Photo Gallery by Envira – Responsive Image Gallery for WordPress - Version 1.5.1

Version Description

  • Added: A justified layout replaces the old "automatic" layout setting for galleries. See documentation on enviragallery.com for additional information.
  • Updated: Spanish translation.
  • Fix: Removing "Insert From Url" option for galleries.
  • Fix: Gallery display follows settings properly when WPML is used in certain cirucmstances.
Download this release

Release Info

Developer dimensionmedia
Plugin Icon 128x128 Photo Gallery by Envira – Responsive Image Gallery for WordPress
Version 1.5.1
Comparing to
See all releases

Code changes from version 1.5.0.8 to 1.5.1

assets/css/envira.css CHANGED
@@ -1 +1 @@
1
- .envira-gallery-wrap,.envira-gallery-wrap *,.envira-tags-filter-list,.envira-tags-filter-list *{background:none;border:0 none;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;float:none;font-size:100%;height:auto;letter-spacing:normal;list-style:none;outline:none;position:static;text-decoration:none;text-indent:0;text-shadow:none;text-transform:none;width:auto;visibility:visible;overflow:visible;margin:0;padding:0;line-height:1;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-shadow:none;-moz-box-shadow:none;-ms-box-shadow:none;-o-box-shadow:none;box-shadow:none;-webkit-appearance:none;transition:none;-webkit-transition:none;-moz-transition:none;-o-transition:none;-ms-transition:none}.envira-tags-filter-list{clear:both;margin:0 0 10px 0}.envira-tags-filter-list li.envira-tags-filter,.envira-tags-filter-list li.envira-tag-filter{float:left;margin:0 20px 10px 0}.envira-tags-filter-list .envira-tag-filter-link{font-size:13px;font-weight:bold}.envira-breadcrumbs{display:block;margin:0 0 20px 0;padding:10px;background:#eee}.envira-breadcrumbs a{text-decoration:none}.envira-gallery-wrap{width:100%;margin:0 auto 20px auto}.envira-gallery-wrap .envira-pagination{margin:0 0 20px 0}.envira-gallery-wrap .envira-gallery-description{clear:both}.envira-gallery-wrap .envira-gallery-public{width:100%;margin:0 auto 20px auto;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.envira-gallery-wrap .envira-gallery-public.envira-clear{clear:both}.envira-gallery-wrap .envira-gallery-public.envira-clear:after{clear:both;content:'.';display:block;height:0;line-height:0;overflow:auto;visibility:hidden;zoom:1}.envira-gallery-wrap .envira-gallery-public .envira-gallery-item-inner{position:relative}.envira-gallery-wrap .envira-gallery-public .envira-gallery-item{float:left}.envira-gallery-wrap .envira-gallery-public .envira-gallery-item>.envira-gallery-link{display:block;outline:none;border:0 none;position:relative}.envira-gallery-wrap .envira-gallery-public .envira-gallery-item img{float:none;display:block;margin:0 auto;padding:0;max-width:100%}.envira-gallery-wrap .envira-gallery-public .envira-gallery-item iframe,.envira-gallery-wrap .envira-gallery-public .envira-gallery-item video{display:block;margin:0 auto;width:100%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-1-columns .envira-gallery-item{clear:both;width:100%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item{width:50%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(2n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item{width:33.33%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(3n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item{width:25%;margin:0;padding:0;box-sizing:border-box}.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(4n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item{width:20%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(5n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item{width:16.66%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(6n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.enviratope .envira-gallery-item{clear:none !important}.envira-gallery-wrap .envira-gallery-public.envira-gallery-css-animations .envira-gallery-item img{opacity:0;transition:all .2s ease-in-out}.envira-gallery-wrap .envira-gallery-public.envira-gallery-css-animations .envira-gallery-item a:hover img{opacity:1 !important}.envira-gallery-wrap.envira-gallery-rtl .envira-gallery-public .envira-gallery-item{float:right}@media only screen and (max-width: 768px){.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item{width:33%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(4n+1){clear:none}.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(3n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item{width:33%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(5n+1){clear:none}.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(3n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item{width:33%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(6n+1){clear:none}.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(3n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.enviratope .envira-gallery-item{clear:none !important}}@media only screen and (max-width: 459px){.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item{width:50% !important}.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(6n+1){clear:none !important}.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(2n+1){clear:both !important}.envira-gallery-wrap .envira-gallery-public.enviratope .envira-gallery-item{clear:none !important}}@media only screen and (max-width: 320px){.envira-gallery-wrap .envira-gallery-public.envira-gallery-1-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item{width:100% !important}.envira-gallery-wrap .envira-gallery-public.envira-gallery-1-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-1-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-1-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-1-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-1-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(6n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.enviratope .envira-gallery-item{clear:none !important}}/*! envirabox v2.1.5 fancyapps.com | fancyapps.com/envirabox/#license */.envirabox-wrap,.envirabox-skin,.envirabox-outer,.envirabox-inner,.envirabox-image,.envirabox-wrap iframe,.envirabox-wrap object,.envirabox-nav,.envirabox-nav span,.envirabox-tmp,.envirabox-buttons,.envirabox-thumbs,.envirabox-wrap *,.envirabox-thumbs *,.envirabox-buttons *{background:none;border:0 none;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;float:none;font-size:100%;height:auto;letter-spacing:normal;list-style:none;outline:none;position:static;text-decoration:none;text-indent:0;text-shadow:none;text-transform:none;width:auto;visibility:visible;overflow:visible;margin:0;padding:0;line-height:1;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-shadow:none;-moz-box-shadow:none;-ms-box-shadow:none;-o-box-shadow:none;box-shadow:none;-webkit-appearance:none;transition:none;-webkit-transition:none;-moz-transition:none;-o-transition:none;-ms-transition:none}.envirabox-wrap{position:absolute;top:0;left:0;z-index:988020}.envirabox-skin{position:relative;background:#f9f9f9;color:#444;text-shadow:none;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.envirabox-opened{z-index:988030}.envirabox-opened .envirabox-skin{-webkit-box-shadow:0 10px 25px rgba(0,0,0,0.5);-moz-box-shadow:0 10px 25px rgba(0,0,0,0.5);box-shadow:0 10px 25px rgba(0,0,0,0.5)}.envirabox-outer,.envirabox-inner{position:relative}.envirabox-inner{overflow:hidden}.envirabox-type-iframe .envirabox-inner{-webkit-overflow-scrolling:touch}.envirabox-error{color:#444;font:13px/20px "Helvetica Neue",Helvetica,Arial,sans-serif;margin:0;padding:15px;white-space:nowrap}.envirabox-image,.envirabox-iframe{display:block;width:100%;height:100%}.envirabox-image{max-width:100%;max-height:100%}#envirabox-loading,.envirabox-close,.envirabox-prev span,.envirabox-next span{background-image:url("images/envirabox_sprite.png")}#envirabox-loading{position:fixed;top:50%;left:50%;margin-top:-22px;margin-left:-22px;background-position:0 -108px;opacity:0.8;cursor:pointer;z-index:988060}#envirabox-loading div{width:44px;height:44px;background:url("images/envirabox_loading.gif") center center no-repeat}.envirabox-close{position:absolute;top:-18px;right:-18px;width:36px;height:36px;cursor:pointer;z-index:988040}.envirabox-nav{position:absolute;top:0;width:40%;height:100%;cursor:pointer;text-decoration:none;background:transparent url("images/blank.gif");-webkit-tap-highlight-color:transparent;z-index:988040}.envirabox-prev{left:0}.envirabox-next{right:0}.envirabox-prev.envirabox-arrows-outside{left:-100px}.envirabox-next.envirabox-arrows-outside{right:-100px}.envirabox-nav span{position:absolute;top:50%;width:36px;height:34px;margin-top:-18px;cursor:pointer;z-index:988040;visibility:hidden}body.envira-touch .envirabox-nav span{visibility:visible}.envirabox-prev span{left:10px;background-position:0 -36px}.envirabox-next span{right:10px;background-position:0 -72px}.envirabox-nav:hover span{visibility:visible}.envirabox-tmp{position:absolute;top:-99999px;left:-99999px;max-width:99999px;max-height:99999px;overflow:visible !important}a.envirabox-close,a.envirabox-nav,a.fancy-close:hover,a.envirabox-nav:hover{border:0}.envirabox-lock{overflow:visible !important;width:auto}.envirabox-lock body{overflow:hidden !important}.envirabox-lock-test{overflow-y:hidden !important}.envirabox-overlay{position:absolute;top:0;left:0;overflow:hidden;display:none;z-index:988010;background:url("images/envirabox_overlay.png")}.envirabox-overlay-fixed{position:fixed;bottom:0;right:0}.envirabox-lock .envirabox-overlay{overflow:auto;overflow-y:scroll}.envirabox-title{visibility:hidden;font-size:13px;line-height:20px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;position:relative;text-shadow:none;z-index:988090}.envirabox-opened .envirabox-title{visibility:visible}.envirabox-title-float-wrap{position:absolute;bottom:auto;right:50%;margin-top:20px;z-index:988050;text-align:center}.envirabox-title-float-wrap .child{display:inline-block;margin-right:-100%;padding:2px 20px;background:transparent;background:rgba(0,0,0,0.8);-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;text-shadow:0 1px 2px #222;color:#FFF;line-height:24px;white-space:nowrap}.envirabox-title-float-wrap.envirabox-title-text-wrap .child{white-space:normal}.envirabox-title-outside-wrap{position:relative;margin-top:10px;color:#fff}.envirabox-title-inside-wrap{padding-top:10px}.envirabox-title-over-wrap{position:absolute;bottom:0;left:0;color:#fff;padding:10px;background:#000;background:rgba(0,0,0,0.8)}#envirabox-buttons{position:fixed;left:0;width:100%;z-index:988050}#envirabox-buttons.top{top:10px}#envirabox-buttons.bottom{bottom:10px}#envirabox-buttons.bottom.has-padding{bottom:80px}#envirabox-buttons.top.has-padding{top:80px}#envirabox-buttons ul{display:block;width:auto;height:30px;margin:0 auto;padding:0;list-style:none;border:1px solid #111;border-radius:3px;-webkit-box-shadow:inset 0 0 0 1px rgba(255,255,255,0.05);-moz-box-shadow:inset 0 0 0 1px rgba(255,255,255,0.05);box-shadow:inset 0 0 0 1px rgba(255,255,255,0.05);background:#323232;background:-moz-linear-gradient(top, #444 0%, #343434 50%, #292929 50%, #333 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #444), color-stop(50%, #343434), color-stop(50%, #292929), color-stop(100%, #333));background:-webkit-linear-gradient(top, #444 0%, #343434 50%, #292929 50%, #333 100%);background:-o-linear-gradient(top, #444 0%, #343434 50%, #292929 50%, #333 100%);background:-ms-linear-gradient(top, #444 0%, #343434 50%, #292929 50%, #333 100%);background:linear-gradient(top, #444 0%, #343434 50%, #292929 50%, #333 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#444444', endColorstr='#222222',GradientType=0 )}#envirabox-buttons ul li{float:left;margin:0;padding:0}#envirabox-buttons ul li#envirabox-buttons-title span{display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:30px;padding:0 10px;color:#fff}#envirabox-buttons a{display:block;width:30px;height:30px;text-indent:-9999px;background-color:transparent;background-image:url("images/envirabox_buttons.png");background-repeat:no-repeat;outline:none;opacity:0.8}#envirabox-buttons a:hover{opacity:1}#envirabox-buttons a.btnPrev{background-position:5px 0}#envirabox-buttons a.btnNext{background-position:-33px 0;border-right:1px solid #3e3e3e}#envirabox-buttons a.btnPlay{background-position:0 -30px}#envirabox-buttons a.btnPlayOn{background-position:-30px -30px}#envirabox-buttons a.btnToggle,#envirabox-buttons a.btnFullscreen{background-position:3px -60px;border-left:1px solid #111;border-right:1px solid #3e3e3e;width:35px}#envirabox-buttons a.btnToggleOn,#envirabox-buttons a.btnFullscreenOn{background-position:-27px -60px}#envirabox-buttons a.btnClose{border-left:1px solid #111;width:35px;background-position:-56px 0px}#envirabox-buttons a.btnDisabled{opacity:0.4;cursor:default}#envirabox-thumbs{position:fixed;left:0;width:100%;overflow:hidden;z-index:988050;box-sizing:border-box}#envirabox-thumbs.top{top:2px}#envirabox-thumbs.top.has-other-content{top:50px}#envirabox-thumbs.bottom{bottom:2px}#envirabox-thumbs.bottom.has-other-content{bottom:50px}#envirabox-thumbs.inline{position:absolute}#envirabox-thumbs *{box-sizing:border-box}#envirabox-thumbs ul{position:relative;list-style:none;margin:0;padding:0}#envirabox-thumbs ul li{border:3px solid #fff;float:left;margin:5px;opacity:1}#envirabox-thumbs ul li.active{opacity:0.75;border:3px solid #888}#envirabox-thumbs ul li:hover{opacity:0.75}#envirabox-thumbs ul li a{display:block;position:relative;overflow:hidden;border:1px solid #222;background:#111;outline:none}#envirabox-thumbs ul li img{display:block;position:relative;border:0;padding:0;max-width:none}@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2 / 1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx){#envirabox-loading,.envirabox-close,.envirabox-prev span,.envirabox-next span{background-image:url("images/envirabox_sprite@2x.png");background-size:44px 152px}#envirabox-loading div{background-image:url("images/envirabox_loading@2x.gif");background-size:24px 24px}}
1
+ .envira-gallery-wrap,.envira-gallery-wrap *,.envira-tags-filter-list,.envira-tags-filter-list *{background:none;border:0 none;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;float:none;font-size:100%;height:auto;letter-spacing:normal;list-style:none;outline:none;position:static;text-decoration:none;text-indent:0;text-shadow:none;text-transform:none;width:auto;visibility:visible;overflow:visible;margin:0;padding:0;line-height:1;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-shadow:none;-moz-box-shadow:none;-ms-box-shadow:none;-o-box-shadow:none;box-shadow:none;-webkit-appearance:none;transition:none;-webkit-transition:none;-moz-transition:none;-o-transition:none;-ms-transition:none}.envira-tags-filter-list{clear:both;margin:0 0 10px 0}.envira-tags-filter-list li.envira-tags-filter,.envira-tags-filter-list li.envira-tag-filter{float:left;margin:0 20px 10px 0}.envira-tags-filter-list .envira-tag-filter-link{font-size:13px;font-weight:bold}.envira-breadcrumbs{display:block;margin:0 0 20px 0;padding:10px;background:#eee}.envira-breadcrumbs a{text-decoration:none}.envira-gallery-wrap{width:100%;margin:0 auto 20px auto}.envira-gallery-wrap .envira-pagination{margin:0 0 20px 0}.envira-gallery-wrap .envira-gallery-description{clear:both}.envira-gallery-wrap .envira-gallery-public{width:100%;margin:0 auto 20px auto;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.envira-gallery-wrap .envira-gallery-public.envira-clear{clear:both}.envira-gallery-wrap .envira-gallery-public.envira-clear:after{clear:both;content:'.';display:block;height:0;line-height:0;overflow:auto;visibility:hidden;zoom:1}.envira-gallery-wrap .envira-gallery-public .envira-gallery-item-inner{position:relative}.envira-gallery-wrap .envira-gallery-public .envira-gallery-item{float:left}.envira-gallery-wrap .envira-gallery-public .envira-gallery-item>.envira-gallery-link{display:block;outline:none;border:0 none;position:relative}.envira-gallery-wrap .envira-gallery-public .envira-gallery-item img{float:none;display:block;margin:0 auto;padding:0;max-width:100%}.envira-gallery-wrap .envira-gallery-public .envira-gallery-item iframe,.envira-gallery-wrap .envira-gallery-public .envira-gallery-item video{display:block;margin:0 auto;width:100%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-1-columns .envira-gallery-item{clear:both;width:100%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item{width:50%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(2n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item{width:33.33%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(3n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item{width:25%;margin:0;padding:0;box-sizing:border-box}.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(4n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item{width:20%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(5n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item{width:16.66%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(6n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.enviratope .envira-gallery-item{clear:none !important}.envira-gallery-wrap .envira-gallery-public.envira-gallery-css-animations .envira-gallery-item img{opacity:0;transition:all .2s ease-in-out}.envira-gallery-wrap .envira-gallery-public.envira-gallery-css-animations .envira-gallery-item a:hover img{opacity:1 !important}.envira-gallery-public.justified-gallery .envira-gallery-item-inner{position:absolute}.envira-gallery-wrap.envira-gallery-rtl .envira-gallery-public .envira-gallery-item{float:right}@media only screen and (max-width: 768px){.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item{width:33%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(4n+1){clear:none}.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(3n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item{width:33%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(5n+1){clear:none}.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(3n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item{width:33%}.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(6n+1){clear:none}.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(3n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.enviratope .envira-gallery-item{clear:none !important}}@media only screen and (max-width: 459px){.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item{width:50% !important}.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(6n+1){clear:none !important}.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(2n+1){clear:both !important}.envira-gallery-wrap .envira-gallery-public.enviratope .envira-gallery-item{clear:none !important}}@media only screen and (max-width: 320px){.envira-gallery-wrap .envira-gallery-public.envira-gallery-1-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item,.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item{width:100% !important}.envira-gallery-wrap .envira-gallery-public.envira-gallery-1-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-1-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-1-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-1-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-1-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-2-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-3-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-4-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-5-columns .envira-gallery-item:nth-child(6n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(2n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(3n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(4n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(5n+1),.envira-gallery-wrap .envira-gallery-public.envira-gallery-6-columns .envira-gallery-item:nth-child(6n+1){clear:both}.envira-gallery-wrap .envira-gallery-public.enviratope .envira-gallery-item{clear:none !important}}/*! envirabox v2.1.5 fancyapps.com | fancyapps.com/envirabox/#license */.envirabox-wrap,.envirabox-skin,.envirabox-outer,.envirabox-inner,.envirabox-image,.envirabox-wrap iframe,.envirabox-wrap object,.envirabox-nav,.envirabox-nav span,.envirabox-tmp,.envirabox-buttons,.envirabox-thumbs,.envirabox-wrap *,.envirabox-thumbs *,.envirabox-buttons *{background:none;border:0 none;border-radius:0;-webkit-border-radius:0;-moz-border-radius:0;float:none;font-size:100%;height:auto;letter-spacing:normal;list-style:none;outline:none;position:static;text-decoration:none;text-indent:0;text-shadow:none;text-transform:none;width:auto;visibility:visible;overflow:visible;margin:0;padding:0;line-height:1;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-shadow:none;-moz-box-shadow:none;-ms-box-shadow:none;-o-box-shadow:none;box-shadow:none;-webkit-appearance:none;transition:none;-webkit-transition:none;-moz-transition:none;-o-transition:none;-ms-transition:none}.envirabox-wrap{position:absolute;top:0;left:0;z-index:988020}.envirabox-skin{position:relative;background:#f9f9f9;color:#444;text-shadow:none;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.envirabox-opened{z-index:988030}.envirabox-opened .envirabox-skin{-webkit-box-shadow:0 10px 25px rgba(0,0,0,0.5);-moz-box-shadow:0 10px 25px rgba(0,0,0,0.5);box-shadow:0 10px 25px rgba(0,0,0,0.5)}.envirabox-outer,.envirabox-inner{position:relative}.envirabox-inner{overflow:hidden}.envirabox-type-iframe .envirabox-inner{-webkit-overflow-scrolling:touch}.envirabox-error{color:#444;font:13px/20px "Helvetica Neue",Helvetica,Arial,sans-serif;margin:0;padding:15px;white-space:nowrap}.envirabox-image,.envirabox-iframe{display:block;width:100%;height:100%}.envirabox-image{max-width:100%;max-height:100%}#envirabox-loading,.envirabox-close,.envirabox-prev span,.envirabox-next span{background-image:url("images/envirabox_sprite.png")}#envirabox-loading{position:fixed;top:50%;left:50%;margin-top:-22px;margin-left:-22px;background-position:0 -108px;opacity:0.8;cursor:pointer;z-index:988060}#envirabox-loading div{width:44px;height:44px;background:url("images/envirabox_loading.gif") center center no-repeat}.envirabox-close{position:absolute;top:-18px;right:-18px;width:36px;height:36px;cursor:pointer;z-index:988040}.envirabox-nav{position:absolute;top:0;width:40%;height:100%;cursor:pointer;text-decoration:none;background:transparent url("images/blank.gif");-webkit-tap-highlight-color:transparent;z-index:988040}.envirabox-prev{left:0}.envirabox-next{right:0}.envirabox-prev.envirabox-arrows-outside{left:-100px}.envirabox-next.envirabox-arrows-outside{right:-100px}.envirabox-nav span{position:absolute;top:50%;width:36px;height:34px;margin-top:-18px;cursor:pointer;z-index:988040;visibility:hidden}body.envira-touch .envirabox-nav span{visibility:visible}.envirabox-prev span{left:10px;background-position:0 -36px}.envirabox-next span{right:10px;background-position:0 -72px}.envirabox-nav:hover span{visibility:visible}.envirabox-tmp{position:absolute;top:-99999px;left:-99999px;max-width:99999px;max-height:99999px;overflow:visible !important}a.envirabox-close,a.envirabox-nav,a.fancy-close:hover,a.envirabox-nav:hover{border:0}.envirabox-lock{overflow:visible !important;width:auto}.envirabox-lock body{overflow:hidden !important}.envirabox-lock-test{overflow-y:hidden !important}.envirabox-overlay{position:absolute;top:0;left:0;overflow:hidden;display:none;z-index:988010;background:url("images/envirabox_overlay.png")}.envirabox-overlay-fixed{position:fixed;bottom:0;right:0}.envirabox-lock .envirabox-overlay{overflow:auto;overflow-y:scroll}.envirabox-title{visibility:hidden;font-size:13px;line-height:20px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;position:relative;text-shadow:none;z-index:988090}.envirabox-opened .envirabox-title{visibility:visible}.envirabox-title-float-wrap{position:absolute;bottom:auto;right:50%;margin-top:20px;z-index:988050;text-align:center}.envirabox-title-float-wrap .child{display:inline-block;margin-right:-100%;padding:2px 20px;background:transparent;background:rgba(0,0,0,0.8);-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;text-shadow:0 1px 2px #222;color:#FFF;line-height:24px;white-space:nowrap}.envirabox-title-float-wrap.envirabox-title-text-wrap .child{white-space:normal}.envirabox-title-outside-wrap{position:relative;margin-top:10px;color:#fff}.envirabox-title-inside-wrap{padding-top:10px}.envirabox-title-over-wrap{position:absolute;bottom:0;left:0;color:#fff;padding:10px;background:#000;background:rgba(0,0,0,0.8)}#envirabox-buttons{position:fixed;left:0;width:100%;z-index:988050}#envirabox-buttons.top{top:10px}#envirabox-buttons.bottom{bottom:10px}#envirabox-buttons.bottom.has-padding{bottom:80px}#envirabox-buttons.top.has-padding{top:80px}#envirabox-buttons ul{display:block;width:auto;height:30px;margin:0 auto;padding:0;list-style:none;border:1px solid #111;border-radius:3px;-webkit-box-shadow:inset 0 0 0 1px rgba(255,255,255,0.05);-moz-box-shadow:inset 0 0 0 1px rgba(255,255,255,0.05);box-shadow:inset 0 0 0 1px rgba(255,255,255,0.05);background:#323232;background:-moz-linear-gradient(top, #444 0%, #343434 50%, #292929 50%, #333 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #444), color-stop(50%, #343434), color-stop(50%, #292929), color-stop(100%, #333));background:-webkit-linear-gradient(top, #444 0%, #343434 50%, #292929 50%, #333 100%);background:-o-linear-gradient(top, #444 0%, #343434 50%, #292929 50%, #333 100%);background:-ms-linear-gradient(top, #444 0%, #343434 50%, #292929 50%, #333 100%);background:linear-gradient(top, #444 0%, #343434 50%, #292929 50%, #333 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#444444', endColorstr='#222222',GradientType=0 )}#envirabox-buttons ul li{float:left;margin:0;padding:0}#envirabox-buttons ul li#envirabox-buttons-title span{display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:30px;padding:0 10px;color:#fff}#envirabox-buttons a{display:block;width:30px;height:30px;text-indent:-9999px;background-color:transparent;background-image:url("images/envirabox_buttons.png");background-repeat:no-repeat;outline:none;opacity:0.8}#envirabox-buttons a:hover{opacity:1}#envirabox-buttons a.btnPrev{background-position:5px 0}#envirabox-buttons a.btnNext{background-position:-33px 0;border-right:1px solid #3e3e3e}#envirabox-buttons a.btnPlay{background-position:0 -30px}#envirabox-buttons a.btnPlayOn{background-position:-30px -30px}#envirabox-buttons a.btnToggle,#envirabox-buttons a.btnFullscreen{background-position:3px -60px;border-left:1px solid #111;border-right:1px solid #3e3e3e;width:35px}#envirabox-buttons a.btnToggleOn,#envirabox-buttons a.btnFullscreenOn{background-position:-27px -60px}#envirabox-buttons a.btnClose{border-left:1px solid #111;width:35px;background-position:-56px 0px}#envirabox-buttons a.btnDisabled{opacity:0.4;cursor:default}#envirabox-thumbs{position:fixed;left:0;width:100%;overflow:hidden;z-index:988050;box-sizing:border-box}#envirabox-thumbs.top{top:2px}#envirabox-thumbs.top.has-other-content{top:50px}#envirabox-thumbs.bottom{bottom:2px}#envirabox-thumbs.bottom.has-other-content{bottom:50px}#envirabox-thumbs.inline{position:absolute}#envirabox-thumbs *{box-sizing:border-box}#envirabox-thumbs ul{position:relative;list-style:none;margin:0;padding:0}#envirabox-thumbs ul li{border:3px solid #fff;float:left;margin:5px;opacity:1}#envirabox-thumbs ul li.active{opacity:0.75;border:3px solid #888}#envirabox-thumbs ul li:hover{opacity:0.75}#envirabox-thumbs ul li a{display:block;position:relative;overflow:hidden;border:1px solid #222;background:#111;outline:none}#envirabox-thumbs ul li img{display:block;position:relative;border:0;padding:0;max-width:none}@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2 / 1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx){#envirabox-loading,.envirabox-close,.envirabox-prev span,.envirabox-next span{background-image:url("images/envirabox_sprite@2x.png");background-size:44px 152px}#envirabox-loading div{background-image:url("images/envirabox_loading@2x.gif");background-size:24px 24px}}
assets/css/justifiedGallery.css ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .envira-js-desaturate {
2
+ filter: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"><filter id="filter"><feColorMatrix type="matrix" color-interpolation-filters="sRGB" values="0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0" /></filter></svg>#filter');
3
+ -webkit-filter: grayscale(100%);
4
+ filter: grayscale(100%);
5
+ -webkit-backface-visibility: hidden;
6
+ -webkit-transform:translate3d(0,0,0);
7
+ }
8
+ .envira-js-blur {
9
+ filter: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"><filter id="filter"><feGaussianBlur stdDeviation="3" /></filter></svg>#filter');
10
+ -webkit-filter: blur(3px);
11
+ filter: blur(3px);
12
+ filter: progid:DXImageTransform.Microsoft.Blur(pixelradius=3);
13
+ -webkit-backface-visibility: hidden;
14
+ -webkit-transform:translate3d(0,0,0);
15
+ }
16
+ .envira-js-vintage {
17
+ filter: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"><filter id="filter"><feColorMatrix type="matrix" color-interpolation-filters="sRGB" values="0.5751000000000001 0.5383 0.1323 0 0 0.24429999999999996 0.7802000000000001 0.11760000000000001 0 0 0.1904 0.3738 0.39170000000000005 0 0 0 0 0 1 0" /><feComponentTransfer color-interpolation-filters="sRGB"><feFuncR type="linear" slope="0.9" /><feFuncG type="linear" slope="0.9" /><feFuncB type="linear" slope="0.9" /></feComponentTransfer><feComponentTransfer color-interpolation-filters="sRGB"><feFuncR type="linear" slope="1.3" intercept="-0.15000000000000002" /><feFuncG type="linear" slope="1.3" intercept="-0.15000000000000002" /><feFuncB type="linear" slope="1.3" intercept="-0.15000000000000002" /></feComponentTransfer></filter></svg>#filter');
18
+ -webkit-filter: sepia(70%) brightness(90%) contrast(130%);
19
+ filter: sepia(70%) brightness(90%) contrast(130%);
20
+ -webkit-backface-visibility: hidden;
21
+ -webkit-transform:translate3d(0,0,0);
22
+ }
23
+ .envira-js-threshold {
24
+ filter: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"><filter id="filter"><feColorMatrix type="matrix" color-interpolation-filters="sRGB" values="0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0" /><feComponentTransfer color-interpolation-filters="sRGB"><feFuncR type="linear" slope="3" intercept="-1" /><feFuncG type="linear" slope="3" intercept="-1" /><feFuncB type="linear" slope="3" intercept="-1" /></feComponentTransfer><feComponentTransfer color-interpolation-filters="sRGB"><feFuncR type="linear" slope="1.7" /><feFuncG type="linear" slope="1.7" /><feFuncB type="linear" slope="1.7" /></feComponentTransfer></filter></svg>#filter');
25
+ -webkit-filter: grayscale(100%) contrast(300%) brightness(170%);
26
+ filter: grayscale(100%) contrast(300%) brightness(170%);
27
+ -webkit-backface-visibility: hidden;
28
+ -webkit-transform:translate3d(0,0,0);
29
+ }
30
+ /*!
31
+ * Justified Gallery - v3.6.2
32
+ * http://miromannino.github.io/Justified-Gallery/
33
+ * Copyright (c) 2016 Miro Mannino
34
+ * Licensed under the MIT license.
35
+ */
36
+ .justified-gallery {
37
+ width: 100%;
38
+ position: relative;
39
+ overflow: hidden;
40
+ }
41
+ .justified-gallery > div > div {
42
+ position: absolute;
43
+ display: inline-block;
44
+ overflow: hidden;
45
+ /* opacity: 0;
46
+ filter: alpha(opacity=0); */
47
+ /* IE8 or Earlier */
48
+ }
49
+ /*.justified-gallery > a > img,
50
+ .justified-gallery > div > img,
51
+ .justified-gallery > a > a > img,
52
+ .justified-gallery > div > a > img,
53
+ .justified-gallery > div > div > a > img,*/
54
+ .justified-gallery > div > div > a > img,
55
+ .justified-gallery > div > div > img,
56
+ .justified-gallery > div > div > a > div.effect-wrapper > img {
57
+ position: absolute;
58
+ top: 50%;
59
+ left: 50%;
60
+ margin: 0;
61
+ padding: 0;
62
+ border: none;
63
+ }
64
+ .justified-gallery > div > div > a > .caption,
65
+ .justified-gallery > div > div > .caption,
66
+ .justified-gallery > div > div .caption {
67
+ display: none;
68
+ position: absolute;
69
+ bottom: 0;
70
+ padding: 5px;
71
+ background-color: #000000;
72
+ left: 0;
73
+ right: 0;
74
+ margin: 0;
75
+ color: white;
76
+ font-size: 12px;
77
+ font-weight: 300;
78
+ font-family: sans-serif;
79
+ z-index: 2;
80
+ }
81
+ .justified-gallery > div > div > a > .caption.caption-visible,
82
+ .justified-gallery > div > div > .caption.caption-visible,
83
+ .justified-gallery > div > .caption.caption-visible {
84
+ display: initial;
85
+ opacity: 0.7;
86
+ filter: "alpha(opacity=70)";
87
+ /* IE8 or Earlier */
88
+ -webkit-transition: opacity 500ms ease-in;
89
+ -moz-transition: opacity 500ms ease-in;
90
+ -o-transition: opacity 500ms ease-in;
91
+ transition: opacity 500ms ease-in;
92
+ }
93
+
94
+ .justified-gallery > div > div > a > .envira-exif,
95
+ .justified-gallery > div > div > .envira-exif,
96
+ .justified-gallery > div > div .envira-exif {
97
+ display: none;
98
+ opacity: 0.8;
99
+ position: absolute;
100
+ top: 0;
101
+ padding: 5px;
102
+ background: rgba(255,255,255,0.7);
103
+ left: 0;
104
+ right: 0;
105
+ margin: 0;
106
+ color: black;
107
+ font-size: 10px;
108
+ font-weight: 300;
109
+ font-family: sans-serif;
110
+ }
111
+ .justified-gallery > div > div > a > .envira-exif.exif-visible,
112
+ .justified-gallery > div > .envira-exif.exif-visible {
113
+ display: initial;
114
+ opacity: 0.7;
115
+ filter: "alpha(opacity=70)";
116
+ /* IE8 or Earlier */
117
+ -webkit-transition: opacity 500ms ease-in;
118
+ -moz-transition: opacity 500ms ease-in;
119
+ -o-transition: opacity 500ms ease-in;
120
+ transition: opacity 500ms ease-in;
121
+ }
122
+
123
+
124
+
125
+
126
+
127
+
128
+ .justified-gallery > .entry-visible {
129
+ opacity: 1.0;
130
+ filter: alpha(opacity=100);
131
+ /* IE8 or Earlier */
132
+ -webkit-transition: opacity 500ms ease-in;
133
+ -moz-transition: opacity 500ms ease-in;
134
+ -o-transition: opacity 500ms ease-in;
135
+ transition: opacity 500ms ease-in;
136
+ }
137
+ .justified-gallery > .jg-filtered {
138
+ display: none;
139
+ }
140
+ .justified-gallery > .spinner {
141
+ position: absolute;
142
+ bottom: 0;
143
+ margin-left: -24px;
144
+ padding: 10px 0 10px 0;
145
+ left: 50%;
146
+ opacity: initial;
147
+ filter: initial;
148
+ overflow: initial;
149
+ }
150
+ .justified-gallery > .spinner > span {
151
+ display: inline-block;
152
+ opacity: 0;
153
+ filter: alpha(opacity=0);
154
+ /* IE8 or Earlier */
155
+ width: 8px;
156
+ height: 8px;
157
+ margin: 0 4px 0 4px;
158
+ background-color: #000;
159
+ border-top-left-radius: 6px;
160
+ border-top-right-radius: 6px;
161
+ border-bottom-right-radius: 6px;
162
+ border-bottom-left-radius: 6px;
163
+ }
assets/css/metabox.css CHANGED
@@ -1 +1 @@
1
- body.post-type-envira #message,body.post-type-envira_album #message{margin:5px 20px 15px 20px}body.post-type-envira #wp-link-wrap,body.post-type-envira_album #wp-link-wrap{z-index:180105 !important}body.post-type-envira #wp-link-backdrop,body.post-type-envira_album #wp-link-backdrop{z-index:160105 !important}form#post.envira-gallery{margin:0 20px}form#post.envira-gallery #poststuff p.envira-intro{margin:0;padding:0 0 30px 0;border-bottom:1px solid #ddd;font-size:16px;font-weight:700}form#post.envira-gallery #poststuff p.envira-intro small{margin:5px 0 0 0;display:block;font-weight:400}form#post.envira-gallery #poststuff p.envira-intro small a{text-decoration:none;font-weight:600}form#post.envira-gallery #poststuff div.envira-video-help{position:relative;z-index:1;width:100%;margin:20px 0 0 0}form#post.envira-gallery #poststuff div.envira-video-help iframe{position:relative;z-index:1;width:100%;height:auto;min-height:300px}form#post.envira-gallery #poststuff div.envira-video-help a.envira-video-close{position:absolute;z-index:2;top:-12px;right:-12px;width:24px;height:24px;line-height:24px;-webkit-border-radius:50%;-moz-border-radius:50%;-o-border-radius:50%;border-radius:50%;background:#f5f5f5;color:#000;text-align:center;text-decoration:none}form#post.envira-gallery #poststuff ul.envira-gallery-images-output{width:100%}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li{position:relative;display:inline-block;width:150px;margin:0 20px 20px 0;padding:0;list-style:none;vertical-align:top;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background:#f7f7f7}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li img{display:block;width:150px;height:150px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.placeholder-image{display:block;width:148px;height:149px;background:url(images/icons/leaf.svg) center no-repeat;background-size:64px 64px;border-left:1px solid #dfdfdf;border-top:1px solid #dfdfdf;border-right:1px solid #dfdfdf}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta{width:148px;overflow:hidden;text-align:center;border-left:1px solid #dfdfdf;border-bottom:1px solid #dfdfdf;border-right:1px solid #dfdfdf}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.title{font-size:12px;font-weight:700;width:138px;height:18px;line-height:18px;margin:8px 5px;overflow:hidden}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.title a.hint{position:absolute;display:inline-block;bottom:10px;right:10px;width:16px;height:16px;background:#f7f7f7}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.title a.hint.hidden{display:none}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.additional{display:none;margin:5px 0 0 0;font-weight:400}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.check{display:none;position:absolute;right:5px;top:5px;width:24px;height:24px;background-color:#eee;-webkit-box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,0,0,0.15);box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,0,0,0.15)}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.check div.media-modal-icon{display:none;width:15px;height:15px;margin:5px 0 0 5px;background-position:-21px 0}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.dashicons{position:absolute;display:block;top:5px;left:5px;width:25px;height:25px;line-height:25px;font-size:18px;outline:none;z-index:20;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.dashicons.envira-gallery-modify-image{background:#0085ba;color:#fff}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.dashicons.envira-gallery-remove-image{left:35px;background:#e02626;color:#fff}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected{width:148px;border:2px solid #7cc048 !important}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected a.check{display:block;background-color:#7cc048;-webkit-box-shadow:0 0 0 1px #fff,0 0 0 2px #7cc048;box-shadow:0 0 0 1px #fff,0 0 0 2px #7cc048}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected a.check div.media-modal-icon{display:block}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected div.meta{width:146px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.ui-sortable-helper li{position:absolute;top:0;left:0}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li{position:relative;z-index:2;display:block;width:100%;margin:0 0 10px 0;padding:10px 15px;background:#fff;border:1px solid #ddd;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li img{display:inline-block;width:75px;margin-left:45px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta{position:absolute;z-index:1;left:0;display:inline-block;width:100%;padding:0 80px 0 150px;border:none;font-weight:700;text-align:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta div.title{display:block;width:100%;height:auto;font-size:16px;margin:0;padding:0}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta div.title a.hint{display:none}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta div.additional{display:block}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li a.check{display:block;position:absolute;left:15px;top:35px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li a.envira-gallery-remove-image{left:auto;top:10px;right:10px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li a.envira-gallery-modify-image{left:auto;top:10px;right:40px}form#post.envira-gallery #poststuff #envira-gallery{margin:60px 0 20px 0}form#post.envira-gallery #poststuff #envira-gallery .handlediv,form#post.envira-gallery #poststuff #envira-albums .handlediv{display:none}form#post.envira-gallery #poststuff #envira-gallery .hndle,form#post.envira-gallery #poststuff #envira-albums .hndle{display:none}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper{margin:-56px 0 0 -1px;padding:0;border-bottom:none}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab{display:inline-block;width:49%;margin:0;padding:15px 0;text-align:center;font-size:16px;border-color:#e5e5e5;background:#f5f5f5}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab.nav-tab-native-envira-gallery span,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab.nav-tab-native-envira-gallery span{display:inline-block;background:url(images/icons/leaf.svg) 0 5px no-repeat;background-size:14px 14px;text-indent:20px}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab.nav-tab-external-gallery,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab.nav-tab-external-gallery{margin-right:-1px}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab:hover,form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab.envira-active,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab:hover,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab.envira-active{background:#fff;border-bottom:1px solid #fff}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab:focus,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab:last-child,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab:last-child{float:right}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab input[type=radio],form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab input[type=radio]{display:none}form#post.envira-gallery #poststuff #envira-gallery .inside,form#post.envira-gallery #poststuff #envira-albums .inside{margin:0;padding:0}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui{height:210px}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area{display:none;border:4px dashed #b4b9be;height:200px}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside{margin:0 auto 0 auto}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p{display:block;text-align:center;color:#a0a5aa;position:absolute;top:50%;left:50%;margin:-10px 0 0 -10px}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p.drag-drop-info,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p.drag-drop-info{display:none;font-size:20px}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p.drag-drop-buttons,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p.drag-drop-buttons{text-align:center;position:relative;top:20px;left:0;margin:0}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button{display:none;position:absolute;margin:0 auto;left:280px;right:0;width:230px;top:115px;text-align:center}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside{width:520px;margin:50px auto 0 auto}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p{position:relative;top:0;left:0;margin:0}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-info,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-info{display:block}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-buttons,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-buttons{margin:10px 0 0 0;text-align:left}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar{display:none;width:100%;position:relative;height:10px;width:100%;margin:10px auto;border-radius:10px;background:#dfdfdf;background:rgba(0,0,0,0.1)}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-inner,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-inner{height:10px;min-width:20px;width:0;background:#aaa;background:rgba(0,0,0,0.2);border-radius:10px;-webkit-transition:width 300ms;-moz-transition:width 300ms;-ms-transition:width 300ms;-o-transition:width 300ms;transition:width 300ms}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-status,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-status{clear:both;position:absolute;right:0;width:50%;height:30px;margin:12px 0 0 0;text-align:right}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-status .done,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-status .done{display:none}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui p.upload-flash-bypass,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui p.upload-flash-bypass{display:none}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab{padding:20px}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external{text-align:center}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external p.envira-intro,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external p.envira-intro{margin:0 0 20px 0;padding:0;border:none}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav{margin:0 0 40px 0;text-align:center}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li{display:inline-block;margin:0 20px 0 0;vertical-align:top}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li:last-child,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li:last-child{margin:0}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a{float:left;width:110px}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label input,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a input,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label input,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a input{display:none}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label div.icon,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a div.icon{width:110px;height:110px;margin:0 0 10px 0;border:1px solid #ddd;background-size:64px 64px;background-position:center;background-repeat:no-repeat}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label div.title,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a div.title,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label div.title,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a div.title{font-weight:700}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li:hover label div.icon,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li:hover a div.icon,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li.envira-active label div.icon,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li.envira-active a div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li:hover label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li:hover a div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li.envira-active label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li.envira-active a div.icon{background-color:#f7fcf3;border-color:#7cc048}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-fc label div.icon,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-fc a div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-fc label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-fc a div.icon{background-image:url(../images/types/fc.png)}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-instagram label div.icon,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-instagram a div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-instagram label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-instagram a div.icon{background-image:url(../images/types/instagram.png)}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external a.button.button-x-large,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external a.button.button-x-large{margin-top:30px}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native{position:relative}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native ul#envira-album-drag-drop-area{z-index:2;min-height:200px;margin:0;padding:20px;border:4px dashed #b4b9be;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native ul#envira-album-drag-drop-area li{cursor:move}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info{position:absolute;top:80px;z-index:1;margin:0 auto;left:0;right:0;text-align:center;color:#a0a5aa;font-size:20px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info span{display:block}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info span.click{font-size:18px}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info small{display:block;margin:5px 0;font-size:14px}form#post.envira-gallery #poststuff #envira-gallery-settings,form#post.envira-gallery #poststuff #envira-albums-settings{background:#f7f7f7}form#post.envira-gallery #poststuff #envira-gallery-settings:after,form#post.envira-gallery #poststuff #envira-albums-settings:after{content:"";display:table;clear:both}form#post.envira-gallery #poststuff #envira-gallery-settings .handlediv,form#post.envira-gallery #poststuff #envira-albums-settings .handlediv{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings .hndle,form#post.envira-gallery #poststuff #envira-albums-settings .hndle{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings .inside,form#post.envira-gallery #poststuff #envira-albums-settings .inside{margin:0;padding:0}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav{width:160px;margin:0;padding:0;border-right:1px solid #ddd}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li{float:left;width:100%;margin:0;padding:0}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a{float:left;width:120px;margin:0 20px;padding:20px 0 20px 25px;text-decoration:none;color:#999;border-bottom:1px solid #ddd;background-position:left center;background-repeat:no-repeat;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;transition:none;-webkit-transition:none}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a:hover,form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a.envira-active,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a:hover,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a.envira-active{width:161px;margin:-1px 0 0 0;padding:20px 20px 20px 45px;text-decoration:none;color:#444;border-top:1px solid #ddd;border-bottom:1px solid #ddd;border-right:1px solid #fff;background-color:#fff;background-position:20px center}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a:focus,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li:last-child a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li:last-child a{border-bottom:none}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li:last-child a:hover,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li:last-child a:hover{border-bottom:none}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-images a,form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-galleries a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-images a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-galleries a{background-image:url(images/icons/leaf.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-config a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-config a{background-image:url(images/icons/configuration.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-lightbox a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-lightbox a{background-image:url(images/icons/lightbox.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-mobile a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-mobile a{background-image:url(images/icons/mobile.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-breadcrumbs a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-breadcrumbs a{background-image:url(images/icons/breadcrumbs.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-comments a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-comments a{background-image:url(images/icons/comments.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-downloads a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-downloads a{background-image:url(images/icons/downloads.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-exif a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-exif a{background-image:url(images/icons/exif.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-pagination a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-pagination a{background-image:url(images/icons/pagination.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-pinterest a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-pinterest a{background-image:url(images/icons/pinterest.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-proofing a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-proofing a{background-image:url(images/icons/proofing.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-printing a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-printing a{background-image:url(images/icons/printing.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-slideshow a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-slideshow a{background-image:url(images/icons/slideshow.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-social a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-social a{background-image:url(images/icons/social.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-tags a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-tags a{background-image:url(images/icons/tags.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-videos a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-videos a{background-image:url(images/icons/video.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-watermarking a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-watermarking a{background-image:url(images/icons/watermark.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-woocommerce a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-woocommerce a{background-image:url(images/icons/woocommerce.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-zoom a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-zoom a{background-image:url(images/icons/zoom.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-misc a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-misc a{background-image:url(images/icons/misc.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs{margin:0 0 0 160px;padding:20px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;background:#fff;border-left:1px solid #ddd}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs h2,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs h2{clear:none}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table{clear:none;margin:0 0 40px 0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table.no-margin,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table.no-margin{margin:0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table th,form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table td,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table th,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table td{padding-top:20px;padding-bottom:20px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table tr.sub-heading th,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table tr.sub-heading th{margin:0;padding:20px 0 0 0;font-style:italic;font-weight:400;font-size:16px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table label.full-width,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table label.full-width{display:block;margin:0 0 5px 0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table label.full-width:first-child,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table label.full-width:first-child{margin-top:5px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table textarea,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table textarea{width:100%}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table input[type=checkbox],form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table input[type=checkbox]{margin-bottom:2px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table p.description,form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table span.description,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table p.description,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table span.description{font-size:13px;font-style:italic;color:#666}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav{width:100%}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav.envira-tab-options,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav.envira-tab-options{margin:20px 0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons{position:absolute;color:#999}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-grid-view,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-grid-view{right:20px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-list-view,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-list-view{right:50px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons.selected,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons.selected{color:#23282d}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons span,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons span{display:inline-block;text-indent:-9999px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav.envira-select-options,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav.envira-select-options{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images ul#envira-gallery-output li,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images ul#envira-gallery-output li{cursor:move}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav{width:100%}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options{height:40px;margin:20px 0;position:relative}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options a.envira-galleries-add,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options a.envira-galleries-add{display:none;position:absolute;top:0;left:0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options input#envira-albums-gallery-search,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options input#envira-albums-gallery-search{position:absolute;top:0;right:0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-select-options,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-select-options{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li{cursor:move}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-remove-image,form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-modify-image,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-remove-image,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-modify-image{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs:after,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs:after{content:"";display:table;clear:both}form#post.envira-gallery #poststuff #envira-gallery-preview:after{content:"";display:table;clear:both}form#post.envira-gallery #poststuff #envira-gallery-preview button.handlediv{display:none}form#post.envira-gallery #poststuff #envira-gallery-preview h2.hndle{display:none}form#post.envira-gallery #poststuff #envira-gallery-preview .inside{margin:0;padding:20px}.media-modal .edit-attachment-frame .edit-media-header button.right{border-right:1px solid #ddd}.media-modal .uploader-inline a.envira-media-library.button{display:none}.media-modal .attachment.details{-webkit-box-shadow:inset 0 0 0 3px #fff,inset 0 0 0 7px #7cc048;box-shadow:inset 0 0 0 3px #fff,inset 0 0 0 7px #7cc048}.media-modal .attachment.details .check{background-color:#7cc048;-webkit-box-shadow:0 0 0 1px #fff,0 0 0 2px #7cc048;box-shadow:0 0 0 1px #fff,0 0 0 2px #7cc048}.media-modal ul.attachments.envira-albums-gallery-cover-image{padding:10px}.media-modal ul.attachments.envira-bulk-edit li.attachment{cursor:default}.media-modal ul.attachments.envira-bulk-edit li.attachment .attachment-preview{cursor:default}.media-modal .attachment-details .attachment-info{padding:16px}.media-modal .attachment-details .attachment-info .settings{margin:0;padding:0;border:none}.media-modal .attachment-details .attachment-info .settings .setting{margin:0 0 20px 0;padding:0 0 20px 0;border-bottom:1px solid #ddd}.media-modal .attachment-details .attachment-info .settings .setting input[type="text"],.media-modal .attachment-details .attachment-info .settings .setting textarea{display:block;width:100%;min-width:100%;margin:0}.media-modal .attachment-details .attachment-info .settings .setting input[type="checkbox"]{float:left;margin:7px 3px 0 0}.media-modal .attachment-details .attachment-info .settings .setting select{margin:0}.media-modal .attachment-details .attachment-info .settings .setting span.name{display:block;width:100%;min-width:100%;margin:0;padding:0;text-align:left;font-weight:700;font-size:14px}.media-modal .attachment-details .attachment-info .settings .setting span.description{text-align:left;font-style:normal;font-size:13px;font-style:italic;color:#666}.media-modal .attachment-details .attachment-info .settings .setting div.description{clear:both;float:left;margin:5px 0 0 0;text-align:left;font-size:13px;font-style:italic;color:#666}.media-modal .attachment-details .attachment-info div.actions a.button{display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi){.wp-core-ui a.check .media-modal-icon{background-image:url(../../../../../wp-includes/images/uploader-icons-2x.png) !important;-webkit-background-size:134px 15px;background-size:134px 15px}}@media screen and (max-width: 1100px){form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area{border-color:#d5d5d5}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside{width:100%;margin-top:20px}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-buttons,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-buttons{text-align:center}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button{left:0;right:0;width:235px;top:145px}}@media screen and (max-width: 768px){form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav{width:60px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a{width:60px;height:60px;margin:0;padding:0;text-indent:-9999px;background-position:center}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a:hover,form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a.envira-active,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a:hover,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a.envira-active{width:60px;height:60px;margin:0;padding:0;text-indent:-9999px;background-position:center}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs{margin:0 0 0 60px}}
1
+ body.post-type-envira #message,body.post-type-envira_album #message{margin:5px 20px 15px 20px}body.post-type-envira #wp-link-wrap,body.post-type-envira_album #wp-link-wrap{z-index:180105 !important}body.post-type-envira #wp-link-backdrop,body.post-type-envira_album #wp-link-backdrop{z-index:160105 !important}form#post.envira-gallery{margin:0 20px}form#post.envira-gallery #poststuff p.envira-intro{margin:0;padding:0 0 30px 0;border-bottom:1px solid #ddd;font-size:16px;font-weight:700}form#post.envira-gallery #poststuff p.envira-intro small{margin:5px 0 0 0;display:block;font-weight:400}form#post.envira-gallery #poststuff p.envira-intro small a{text-decoration:none;font-weight:600}form#post.envira-gallery #poststuff div.envira-video-help{position:relative;z-index:1;width:100%;margin:20px 0 0 0}form#post.envira-gallery #poststuff div.envira-video-help iframe{position:relative;z-index:1;width:100%;height:auto;min-height:300px}form#post.envira-gallery #poststuff div.envira-video-help a.envira-video-close{position:absolute;z-index:2;top:-12px;right:-12px;width:24px;height:24px;line-height:24px;-webkit-border-radius:50%;-moz-border-radius:50%;-o-border-radius:50%;border-radius:50%;background:#f5f5f5;color:#000;text-align:center;text-decoration:none}form#post.envira-gallery #poststuff ul.envira-gallery-images-output{width:100%}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li{position:relative;display:inline-block;width:150px;margin:0 20px 20px 0;padding:0;list-style:none;vertical-align:top;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box;background:#f7f7f7}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li img{display:block;width:150px;height:150px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.placeholder-image{display:block;width:148px;height:149px;background:url(images/icons/leaf.svg) center no-repeat;background-size:64px 64px;border-left:1px solid #dfdfdf;border-top:1px solid #dfdfdf;border-right:1px solid #dfdfdf}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta{width:148px;overflow:hidden;text-align:center;border-left:1px solid #dfdfdf;border-bottom:1px solid #dfdfdf;border-right:1px solid #dfdfdf}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.title{font-size:12px;font-weight:700;width:138px;height:18px;line-height:18px;margin:8px 5px;overflow:hidden}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.title a.hint{position:absolute;display:inline-block;bottom:10px;right:10px;width:16px;height:16px;background:#f7f7f7}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.title a.hint.hidden{display:none}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li div.meta div.additional{display:none;margin:5px 0 0 0;font-weight:400}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.check{display:none;position:absolute;right:5px;top:5px;width:24px;height:24px;background-color:#eee;-webkit-box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,0,0,0.15);box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,0,0,0.15)}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.check div.media-modal-icon{display:none;width:15px;height:15px;margin:5px 0 0 5px;background-position:-21px 0}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.dashicons{position:absolute;display:block;top:5px;left:5px;width:25px;height:25px;line-height:25px;font-size:18px;outline:none;z-index:20;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.dashicons.envira-gallery-modify-image{background:#0085ba;color:#fff}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li a.dashicons.envira-gallery-remove-image{left:35px;background:#e02626;color:#fff}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected{width:148px;border:2px solid #7cc048 !important}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected a.check{display:block;background-color:#7cc048;-webkit-box-shadow:0 0 0 1px #fff,0 0 0 2px #7cc048;box-shadow:0 0 0 1px #fff,0 0 0 2px #7cc048}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected a.check div.media-modal-icon{display:block}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.selected div.meta{width:146px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output li.ui-sortable-helper li{position:absolute;top:0;left:0}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li{position:relative;z-index:2;display:block;width:100%;margin:0 0 10px 0;padding:10px 15px;background:#fff;border:1px solid #ddd;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li img{display:inline-block;width:75px;margin-left:45px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta{position:absolute;z-index:1;left:0;display:inline-block;width:100%;padding:0 80px 0 150px;border:none;font-weight:700;text-align:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta div.title{display:block;width:100%;height:auto;font-size:16px;margin:0;padding:0}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta div.title a.hint{display:none}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li div.meta div.additional{display:block}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li a.check{display:block;position:absolute;left:15px;top:35px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li a.envira-gallery-remove-image{left:auto;top:10px;right:10px}form#post.envira-gallery #poststuff ul.envira-gallery-images-output.list li a.envira-gallery-modify-image{left:auto;top:10px;right:40px}form#post.envira-gallery #poststuff #envira-gallery{margin:60px 0 20px 0}form#post.envira-gallery #poststuff #envira-gallery .handlediv,form#post.envira-gallery #poststuff #envira-albums .handlediv{display:none}form#post.envira-gallery #poststuff #envira-gallery .hndle,form#post.envira-gallery #poststuff #envira-albums .hndle{display:none}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper{margin:-56px 0 0 -1px;padding:0;border-bottom:none}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab{display:inline-block;width:49%;margin:0;padding:15px 0;text-align:center;font-size:16px;border-color:#e5e5e5;background:#f5f5f5}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab.nav-tab-native-envira-gallery span,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab.nav-tab-native-envira-gallery span{display:inline-block;background:url(images/icons/leaf.svg) 0 5px no-repeat;background-size:14px 14px;text-indent:20px}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab.nav-tab-external-gallery,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab.nav-tab-external-gallery{margin-right:-1px}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab:hover,form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab.envira-active,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab:hover,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab.envira-active{background:#fff;border-bottom:1px solid #fff}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab:focus,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab:last-child,form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab:last-child{float:right}form#post.envira-gallery #poststuff #envira-gallery h2.nav-tab-wrapper .nav-tab input[type=radio],form#post.envira-gallery #poststuff #envira-albums h2.nav-tab-wrapper .nav-tab input[type=radio]{display:none}form#post.envira-gallery #poststuff #envira-gallery .inside,form#post.envira-gallery #poststuff #envira-albums .inside{margin:0;padding:0}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui{height:210px}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area{display:none;border:4px dashed #b4b9be;height:200px}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside{margin:0 auto 0 auto}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p{display:block;text-align:center;color:#a0a5aa;position:absolute;top:50%;left:50%;margin:-10px 0 0 -10px}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p.drag-drop-info,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p.drag-drop-info{display:none;font-size:20px}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p.drag-drop-buttons,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui #drag-drop-area .drag-drop-inside p.drag-drop-buttons{text-align:center;position:relative;top:20px;left:0;margin:0}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button{display:none;position:absolute;margin:0 auto;left:280px;right:0;width:230px;top:115px;text-align:center}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside{width:520px;margin:50px auto 0 auto}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p{position:relative;top:0;left:0;margin:0}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-info,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-info{display:block}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-buttons,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-buttons{margin:10px 0 0 0;text-align:left}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar{display:none;width:100%;position:relative;height:10px;width:100%;margin:10px auto;border-radius:10px;background:#dfdfdf;background:rgba(0,0,0,0.1)}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-inner,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-inner{height:10px;min-width:20px;width:0;background:#aaa;background:rgba(0,0,0,0.2);border-radius:10px;-webkit-transition:width 300ms;-moz-transition:width 300ms;-ms-transition:width 300ms;-o-transition:width 300ms;transition:width 300ms}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-status,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-status{clear:both;position:absolute;right:0;width:50%;height:30px;margin:12px 0 0 0;text-align:right}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-status .done,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui .envira-progress-bar .envira-progress-bar-status .done{display:none}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui p.upload-flash-bypass,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui p.upload-flash-bypass{display:none}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab{padding:20px}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external{text-align:center}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external p.envira-intro,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external p.envira-intro{margin:0 0 20px 0;padding:0;border:none}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav{margin:0 0 40px 0;text-align:center}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li{display:inline-block;margin:0 20px 0 0;vertical-align:top}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li:last-child,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li:last-child{margin:0}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a{float:left;width:110px}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label input,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a input,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label input,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a input{display:none}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label div.icon,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a div.icon{width:110px;height:110px;margin:0 0 10px 0;border:1px solid #ddd;background-size:64px 64px;background-position:center;background-repeat:no-repeat}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label div.title,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a div.title,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li label div.title,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li a div.title{font-weight:700}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li:hover label div.icon,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li:hover a div.icon,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li.envira-active label div.icon,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li.envira-active a div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li:hover label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li:hover a div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li.envira-active label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li.envira-active a div.icon{background-color:#f7fcf3;border-color:#7cc048}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-fc label div.icon,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-fc a div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-fc label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-fc a div.icon{background-image:url(../images/types/fc.png)}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-instagram label div.icon,form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-instagram a div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-instagram label div.icon,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external ul#envira-gallery-types-nav li#envira-gallery-type-instagram a div.icon{background-image:url(../images/types/instagram.png)}form#post.envira-gallery #poststuff #envira-gallery .inside div.envira-tab#envira-gallery-external a.button.button-x-large,form#post.envira-gallery #poststuff #envira-albums .inside div.envira-tab#envira-gallery-external a.button.button-x-large{margin-top:30px}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native{position:relative}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native ul#envira-album-drag-drop-area{z-index:2;min-height:200px;margin:0;padding:20px;border:4px dashed #b4b9be;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native ul#envira-album-drag-drop-area li{cursor:move}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info{position:absolute;top:80px;z-index:1;margin:0 auto;left:0;right:0;text-align:center;color:#a0a5aa;font-size:20px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info span{display:block}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info span.click{font-size:18px}form#post.envira-gallery #poststuff #envira-albums .inside #envira-types #envira-album-native p.drag-drop-info small{display:block;margin:5px 0;font-size:14px}form#post.envira-gallery #poststuff #envira-gallery-settings,form#post.envira-gallery #poststuff #envira-albums-settings{background:#f7f7f7}form#post.envira-gallery #poststuff #envira-gallery-settings:after,form#post.envira-gallery #poststuff #envira-albums-settings:after{content:"";display:table;clear:both}form#post.envira-gallery #poststuff #envira-gallery-settings .handlediv,form#post.envira-gallery #poststuff #envira-albums-settings .handlediv{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings .hndle,form#post.envira-gallery #poststuff #envira-albums-settings .hndle{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings .inside,form#post.envira-gallery #poststuff #envira-albums-settings .inside{margin:0;padding:0}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav{width:160px;margin:0;padding:0;border-right:1px solid #ddd}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li{float:left;width:100%;margin:0;padding:0}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a{float:left;width:120px;margin:0 20px;padding:20px 0 20px 25px;text-decoration:none;color:#999;border-bottom:1px solid #ddd;background-position:left center;background-repeat:no-repeat;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;transition:none;-webkit-transition:none}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a:hover,form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a.envira-active,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a:hover,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a.envira-active{width:161px;margin:-1px 0 0 0;padding:20px 20px 20px 45px;text-decoration:none;color:#444;border-top:1px solid #ddd;border-bottom:1px solid #ddd;border-right:1px solid #fff;background-color:#fff;background-position:20px center}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a:focus,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li:last-child a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li:last-child a{border-bottom:none}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li:last-child a:hover,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li:last-child a:hover{border-bottom:none}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-images a,form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-galleries a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-images a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-galleries a{background-image:url(images/icons/leaf.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-config a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-config a{background-image:url(images/icons/configuration.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-lightbox a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-lightbox a{background-image:url(images/icons/lightbox.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-mobile a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-mobile a{background-image:url(images/icons/mobile.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-breadcrumbs a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-breadcrumbs a{background-image:url(images/icons/breadcrumbs.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-comments a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-comments a{background-image:url(images/icons/comments.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-downloads a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-downloads a{background-image:url(images/icons/downloads.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-exif a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-exif a{background-image:url(images/icons/exif.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-pagination a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-pagination a{background-image:url(images/icons/pagination.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-pinterest a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-pinterest a{background-image:url(images/icons/pinterest.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-proofing a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-proofing a{background-image:url(images/icons/proofing.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-printing a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-printing a{background-image:url(images/icons/printing.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-slideshow a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-slideshow a{background-image:url(images/icons/slideshow.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-social a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-social a{background-image:url(images/icons/social.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-tags a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-tags a{background-image:url(images/icons/tags.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-videos a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-videos a{background-image:url(images/icons/video.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-watermarking a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-watermarking a{background-image:url(images/icons/watermark.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-woocommerce a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-woocommerce a{background-image:url(images/icons/woocommerce.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-zoom a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-zoom a{background-image:url(images/icons/zoom.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li.envira-misc a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li.envira-misc a{background-image:url(images/icons/misc.svg);background-size:16px 16px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs{margin:0 0 0 160px;padding:20px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;background:#fff;border-left:1px solid #ddd}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs h2,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs h2{clear:none}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table{clear:none;margin:0 0 40px 0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table.no-margin,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table.no-margin{margin:0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table th,form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table td,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table th,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table td{padding-top:20px;padding-bottom:20px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table tr.sub-heading th,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table tr.sub-heading th{margin:0;padding:20px 0 0 0;font-style:italic;font-weight:400;font-size:16px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table label.full-width,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table label.full-width{display:block;margin:0 0 5px 0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table label.full-width:first-child,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table label.full-width:first-child{margin-top:5px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table textarea,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table textarea{width:100%}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table input[type=checkbox],form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table input[type=checkbox]{margin-bottom:2px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table p.description,form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs table.form-table span.description,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table p.description,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs table.form-table span.description{font-size:13px;font-style:italic;color:#666}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav{width:100%}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav.envira-tab-options,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav.envira-tab-options{margin:20px 0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons{position:absolute;color:#999}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-grid-view,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-grid-view{right:20px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-list-view,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons.dashicons-list-view{right:50px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons.selected,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons.selected{color:#23282d}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav a.dashicons span,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav a.dashicons span{display:inline-block;text-indent:-9999px}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images nav.envira-select-options,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images nav.envira-select-options{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-images ul#envira-gallery-output li,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-images ul#envira-gallery-output li{cursor:move}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav{width:100%}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options{height:40px;margin:20px 0;position:relative}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options a.envira-galleries-add,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options a.envira-galleries-add{display:none;position:absolute;top:0;left:0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options input#envira-albums-gallery-search,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-tab-options input#envira-albums-gallery-search{position:absolute;top:0;right:0}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries nav.envira-select-options,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries nav.envira-select-options{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li{cursor:move}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-remove-image,form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-modify-image,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-remove-image,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs #envira-tab-galleries ul.envira-gallery-images-output li a.envira-gallery-modify-image{display:none}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs:after,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs:after{content:"";display:table;clear:both}form#post.envira-gallery #poststuff #envira-gallery-preview:after{content:"";display:table;clear:both}form#post.envira-gallery #poststuff #envira-gallery-preview button.handlediv{display:none}form#post.envira-gallery #poststuff #envira-gallery-preview h2.hndle{display:none}form#post.envira-gallery #poststuff #envira-gallery-preview .inside{margin:0;padding:20px}.media-modal .edit-attachment-frame .edit-media-header button.right{border-right:1px solid #ddd}.media-modal .uploader-inline a.envira-media-library.button{display:none}.media-modal .attachment.details{-webkit-box-shadow:inset 0 0 0 3px #fff,inset 0 0 0 7px #7cc048;box-shadow:inset 0 0 0 3px #fff,inset 0 0 0 7px #7cc048}.media-modal .attachment.details .check{background-color:#7cc048;-webkit-box-shadow:0 0 0 1px #fff,0 0 0 2px #7cc048;box-shadow:0 0 0 1px #fff,0 0 0 2px #7cc048}.media-modal ul.attachments.envira-albums-gallery-cover-image{padding:10px}.media-modal ul.attachments.envira-bulk-edit li.attachment{cursor:default}.media-modal ul.attachments.envira-bulk-edit li.attachment .attachment-preview{cursor:default}.media-modal .attachment-details .attachment-info{padding:16px}.media-modal .attachment-details .attachment-info .settings{margin:0;padding:0;border:none}.media-modal .attachment-details .attachment-info .settings .setting{margin:0 0 20px 0;padding:0 0 20px 0;border-bottom:1px solid #ddd}.media-modal .attachment-details .attachment-info .settings .setting input[type="text"],.media-modal .attachment-details .attachment-info .settings .setting textarea{display:block;width:100%;min-width:100%;margin:0}.media-modal .attachment-details .attachment-info .settings .setting input[type="checkbox"]{float:left;margin:0 5px 0 0}.media-modal .attachment-details .attachment-info .settings .setting select{margin:0}.media-modal .attachment-details .attachment-info .settings .setting span.name{display:block;width:100%;min-width:100%;margin:0;padding:0;text-align:left;font-weight:700;font-size:14px}.media-modal .attachment-details .attachment-info .settings .setting span.description{text-align:left;font-style:normal;font-size:13px;font-style:italic;color:#666}.media-modal .attachment-details .attachment-info .settings .setting div.description{clear:both;float:left;margin:5px 0 0 0;text-align:left;font-size:13px;font-style:italic;color:#666}.media-modal .attachment-details .attachment-info div.actions a.button{display:inline-block}@media (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi){.wp-core-ui a.check .media-modal-icon{background-image:url(../../../../../wp-includes/images/uploader-icons-2x.png) !important;-webkit-background-size:134px 15px;background-size:134px 15px}}@media screen and (max-width: 1100px){form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area{border-color:#d5d5d5}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside{width:100%;margin-top:20px}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-buttons,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui.drag-drop #drag-drop-area .drag-drop-inside p.drag-drop-buttons{text-align:center}form#post.envira-gallery #poststuff #envira-gallery .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button,form#post.envira-gallery #poststuff #envira-albums .inside #envira-gallery-native #plupload-upload-ui a.envira-media-library.button{left:0;right:0;width:235px;top:145px}}@media screen and (max-width: 768px){form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav{width:60px}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a{width:60px;height:60px;margin:0;padding:0;text-indent:-9999px;background-position:center}form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a:hover,form#post.envira-gallery #poststuff #envira-gallery-settings ul#envira-tabs-nav li a.envira-active,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a:hover,form#post.envira-gallery #poststuff #envira-albums-settings ul#envira-tabs-nav li a.envira-active{width:60px;height:60px;margin:0;padding:0;text-indent:-9999px;background-position:center}form#post.envira-gallery #poststuff #envira-gallery-settings #envira-tabs,form#post.envira-gallery #poststuff #envira-albums-settings #envira-tabs{margin:0 0 0 60px}}
assets/js/conditional-fields.js CHANGED
@@ -7,6 +7,7 @@ jQuery( document ).ready( function( $ ) {
7
  // Show/hide elements as necessary when a conditional field is changed
8
  $( 'input, select' ).conditional( {
9
  data: 'envira-conditional',
 
10
  value: 'envira-conditional-value',
11
  displayOnEnabled: 'envira-conditional-display'
12
  } );
@@ -33,6 +34,7 @@ jQuery( document ).ready( function( $ ) {
33
  var settings = $.extend({
34
  data: 'conditional',
35
  value: 'conditional-value',
 
36
  displayOnEnabled: 'conditional-display'
37
  }, options);
38
 
@@ -48,6 +50,7 @@ jQuery( document ).ready( function( $ ) {
48
  var conditionalElements,
49
  displayOnEnabled,
50
  value,
 
51
  displayElements;
52
 
53
  // Toggle + toggle on change
@@ -67,6 +70,12 @@ jQuery( document ).ready( function( $ ) {
67
  value = '';
68
  }
69
 
 
 
 
 
 
 
70
  // By default, don't display elements
71
  displayElements = false;
72
 
@@ -81,6 +90,9 @@ jQuery( document ).ready( function( $ ) {
81
  break;
82
 
83
  default:
 
 
 
84
  if ( displayOnEnabled ) {
85
  if ( value !== '' ) {
86
  displayElements = ( ( String( $( this ).val() ) !== String( value ) ) ? false : true );
@@ -101,8 +113,14 @@ jQuery( document ).ready( function( $ ) {
101
  for (var i = 0; i < conditionalElements.length; i++) {
102
  if ( displayElements ) {
103
  $( '#' + conditionalElements[i] ).fadeIn( 300 );
 
 
 
104
  } else {
105
  $( '#' + conditionalElements[i] ).fadeOut( 300 );
 
 
 
106
  }
107
  }
108
  });
7
  // Show/hide elements as necessary when a conditional field is changed
8
  $( 'input, select' ).conditional( {
9
  data: 'envira-conditional',
10
+ toggle: 'envira-conditional-toggle',
11
  value: 'envira-conditional-value',
12
  displayOnEnabled: 'envira-conditional-display'
13
  } );
34
  var settings = $.extend({
35
  data: 'conditional',
36
  value: 'conditional-value',
37
+ toggle: 'conditional-toggle',
38
  displayOnEnabled: 'conditional-display'
39
  }, options);
40
 
50
  var conditionalElements,
51
  displayOnEnabled,
52
  value,
53
+ toggle,
54
  displayElements;
55
 
56
  // Toggle + toggle on change
70
  value = '';
71
  }
72
 
73
+ //
74
+ toggle = $( this ).data( settings.toggle );
75
+ if ( typeof value === 'undefined' ) {
76
+ toggle = '';
77
+ }
78
+
79
  // By default, don't display elements
80
  displayElements = false;
81
 
90
  break;
91
 
92
  default:
93
+ console.log( $( this ).attr( 'type' ) );
94
+ console.log( displayOnEnabled );
95
+ console.log( 'toggle: ' + toggle );
96
  if ( displayOnEnabled ) {
97
  if ( value !== '' ) {
98
  displayElements = ( ( String( $( this ).val() ) !== String( value ) ) ? false : true );
113
  for (var i = 0; i < conditionalElements.length; i++) {
114
  if ( displayElements ) {
115
  $( '#' + conditionalElements[i] ).fadeIn( 300 );
116
+ if ( toggle ) {
117
+ $( '#' + toggle ).fadeOut( 300 );
118
+ }
119
  } else {
120
  $( '#' + conditionalElements[i] ).fadeOut( 300 );
121
+ if ( toggle ) {
122
+ $( '#' + toggle ).fadeIn( 300 );
123
+ }
124
  }
125
  }
126
  });
assets/js/envira.js CHANGED
@@ -1,5 +1,7 @@
1
  /**
2
  * envira.js is a placeholder, which CodeKit attaches the following JS files to, before compiling as min/envira-min.js:
 
 
3
  * - lib/touchswipe.js
4
  * - lib/mousewheel.js
5
  * - lib/imagesloaded.js
@@ -28,4 +30,201 @@ jQuery( document ).ready( function( $ ) {
28
 
29
  } );
30
 
31
- } );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  /**
2
  * envira.js is a placeholder, which CodeKit attaches the following JS files to, before compiling as min/envira-min.js:
3
+ * - lib/jquery.justifiedGallery.js
4
+ * - lib/enviraJustifiedGallery-extension.js
5
  * - lib/touchswipe.js
6
  * - lib/mousewheel.js
7
  * - lib/imagesloaded.js
30
 
31
  } );
32
 
33
+ } );
34
+
35
+ function jg_effect_desaturate(src) {
36
+ var supportsCanvas = !!document.createElement('canvas').getContext;
37
+ if (supportsCanvas) {
38
+ var canvas = document.createElement('canvas'),
39
+ context = canvas.getContext('2d'),
40
+ imageData, px, length, i = 0, gray,
41
+ img = new Image();
42
+
43
+ img.src = src;
44
+ canvas.width = img.width;
45
+ canvas.height = img.height;
46
+ context.drawImage(img, 0, 0);
47
+
48
+ imageData = context.getImageData(0, 0, canvas.width, canvas.height);
49
+ px = imageData.data;
50
+ length = px.length;
51
+
52
+ for (; i < length; i += 4) {
53
+ gray = px[i] * .3 + px[i + 1] * .59 + px[i + 2] * .11;
54
+ px[i] = px[i + 1] = px[i + 2] = gray;
55
+ }
56
+
57
+ context.putImageData(imageData, 0, 0);
58
+ return canvas.toDataURL();
59
+ } else {
60
+ return src;
61
+ }
62
+ }
63
+
64
+ function jg_effect_threshold(src) {
65
+ var supportsCanvas = !!document.createElement('canvas').getContext;
66
+ if (supportsCanvas) {
67
+ var canvas = document.createElement('canvas'),
68
+ context = canvas.getContext('2d'),
69
+ imageData, px, length, i = 0, gray,
70
+ img = new Image();
71
+
72
+ img.src = src;
73
+ canvas.width = img.width;
74
+ canvas.height = img.height;
75
+ context.drawImage(img, 0, 0);
76
+
77
+ imageData = context.getImageData(0, 0, canvas.width, canvas.height);
78
+ px = imageData.data;
79
+ length = px.length;
80
+
81
+ threshold = 120;
82
+
83
+ for (var i=0; i<length; i+=4) {
84
+ var r = px[i];
85
+ var g = px[i+1];
86
+ var b = px[i+2];
87
+ var v = (0.2126*r + 0.7152*g + 0.0722*b >= threshold) ? 255 : 0;
88
+ px[i] = px[i+1] = px[i+2] = v
89
+ }
90
+
91
+ context.putImageData(imageData, 0, 0);
92
+ return canvas.toDataURL();
93
+ } else {
94
+ return src;
95
+ }
96
+ }
97
+
98
+ function jg_effect_blur(src) {
99
+ var supportsCanvas = !!document.createElement('canvas').getContext;
100
+ if (supportsCanvas) {
101
+ var canvas = document.createElement('canvas'),
102
+ context = canvas.getContext('2d'),
103
+ imageData, px, length, i = 0, gray, top_x = 0, top_y = 0, radius = 30, iterations = 1
104
+ img = new Image();
105
+
106
+ img.src = src;
107
+ canvas.width = img.width;
108
+ canvas.height = img.height;
109
+ context.drawImage(img, 0, 0);
110
+
111
+ var imageData;
112
+ var width = img.width;
113
+ var height = img.height;
114
+
115
+ imageData = context.getImageData( top_x, top_y, width, height );
116
+ var pixels = imageData.data;
117
+
118
+ var rsum,gsum,bsum,asum,x,y,i,p,p1,p2,yp,yi,yw,idx;
119
+ var wm = width - 1;
120
+ var hm = height - 1;
121
+ var wh = width * height;
122
+ var rad1 = radius + 1;
123
+
124
+ var r = [];
125
+ var g = [];
126
+ var b = [];
127
+
128
+ var mul_sum = mul_table[radius];
129
+ var shg_sum = shg_table[radius];
130
+
131
+ var vmin = [];
132
+ var vmax = [];
133
+
134
+ while ( iterations-- > 0 ){
135
+ yw = yi = 0;
136
+
137
+ for ( y=0; y < height; y++ ){
138
+ rsum = pixels[yw] * rad1;
139
+ gsum = pixels[yw+1] * rad1;
140
+ bsum = pixels[yw+2] * rad1;
141
+
142
+ for( i = 1; i <= radius; i++ ){
143
+ p = yw + (((i > wm ? wm : i )) << 2 );
144
+ rsum += pixels[p++];
145
+ gsum += pixels[p++];
146
+ bsum += pixels[p++];
147
+ }
148
+
149
+ for ( x = 0; x < width; x++ ){
150
+ r[yi] = rsum;
151
+ g[yi] = gsum;
152
+ b[yi] = bsum;
153
+
154
+ if( y==0) {
155
+ vmin[x] = ( ( p = x + rad1) < wm ? p : wm ) << 2;
156
+ vmax[x] = ( ( p = x - radius) > 0 ? p << 2 : 0 );
157
+ }
158
+
159
+ p1 = yw + vmin[x];
160
+ p2 = yw + vmax[x];
161
+
162
+ rsum += pixels[p1++] - pixels[p2++];
163
+ gsum += pixels[p1++] - pixels[p2++];
164
+ bsum += pixels[p1++] - pixels[p2++];
165
+
166
+ yi++;
167
+ }
168
+ yw += ( width << 2 );
169
+ }
170
+
171
+ for ( x = 0; x < width; x++ ){
172
+ yp = x;
173
+ rsum = r[yp] * rad1;
174
+ gsum = g[yp] * rad1;
175
+ bsum = b[yp] * rad1;
176
+
177
+ for( i = 1; i <= radius; i++ ){
178
+ yp += ( i > hm ? 0 : width );
179
+ rsum += r[yp];
180
+ gsum += g[yp];
181
+ bsum += b[yp];
182
+ }
183
+
184
+ yi = x << 2;
185
+ for ( y = 0; y < height; y++){
186
+ pixels[yi] = (rsum * mul_sum) >>> shg_sum;
187
+ pixels[yi+1] = (gsum * mul_sum) >>> shg_sum;
188
+ pixels[yi+2] = (bsum * mul_sum) >>> shg_sum;
189
+
190
+ if( x == 0 ) {
191
+ vmin[y] = ( ( p = y + rad1) < hm ? p : hm ) * width;
192
+ vmax[y] = ( ( p = y - radius) > 0 ? p * width : 0 );
193
+ }
194
+
195
+ p1 = x + vmin[y];
196
+ p2 = x + vmax[y];
197
+
198
+ rsum += r[p1] - r[p2];
199
+ gsum += g[p1] - g[p2];
200
+ bsum += b[p1] - b[p2];
201
+
202
+ yi += width << 2;
203
+ }
204
+ }
205
+ }
206
+ context.putImageData( imageData, top_x, top_y );
207
+
208
+ return canvas.toDataURL();
209
+
210
+ } else {
211
+ return src;
212
+ }
213
+ }
214
+
215
+ function jg_effect_vintage( img ) {
216
+ var options = {
217
+ onError: function() {
218
+ alert('ERROR');
219
+ }
220
+ };
221
+ var effect = {
222
+ vignette: 1,
223
+ sepia: true,
224
+ noise: 50,
225
+ desaturate: .2,
226
+ lighten: .1
227
+
228
+ };
229
+ new VintageJS(img, options, effect);
230
+ }
assets/js/lib/enviraJustifiedGallery-extensions.js ADDED
@@ -0,0 +1,412 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Justified Gallery / Envira Extensions and Overrides - v3.6.2
3
+ * Copyright (c) 2016 David Bisset, Benjamin Rojas
4
+ * Licensed under the MIT license.
5
+ */
6
+
7
+ (function ($) {
8
+ var justifiedGallery = $.fn.justifiedGallery;
9
+ var EnviraJustifiedGallery = {};
10
+
11
+ $.fn.enviraJustifiedGallery = function () {
12
+ var obj = justifiedGallery.apply(this, arguments);
13
+ EnviraJustifiedGallery = obj.data('jg.controller');
14
+
15
+ EnviraJustifiedGallery.displayEntryCaption = function ($entry) {
16
+
17
+ var $image = this.imgFromEntry($entry);
18
+ if ($image !== null && this.settings.captions) {
19
+ var $imgCaption = this.captionFromEntry($entry);
20
+
21
+ // Create it if it doesn't exists
22
+ if ($imgCaption === null) {
23
+
24
+ var caption = $image.data('envira-caption');
25
+
26
+ if (this.isValidCaption(caption)) { // Create only we found something
27
+ $imgCaption = $('<div class="caption">' + caption + '</div>');
28
+ $entry.append($imgCaption);
29
+ $entry.data('jg.createdCaption', true);
30
+ }
31
+ }
32
+
33
+ // Create events (we check again the $imgCaption because it can be still inexistent)
34
+ if ($imgCaption !== null) {
35
+ if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity);
36
+ this.addCaptionEventsHandlers($entry);
37
+ }
38
+ } else {
39
+ this.removeCaptionEventsHandlers($entry);
40
+ }
41
+ };
42
+
43
+ return EnviraJustifiedGallery;
44
+
45
+ };
46
+ })(jQuery);
47
+
48
+ /*!
49
+ * vintageJS
50
+ * Add a retro/vintage effect to images using the HTML5 canvas element
51
+ *
52
+ * @license Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
53
+ * @author Robert Fleischmann <rendro87@gmail.com>
54
+ * @version 1.1.5
55
+ */
56
+
57
+ !function(a,b){"function"==typeof define&&define.amd?define("vintagejs",["jquery"],function(c){return a.VintageJS=b(c)}):"object"==typeof exports?module.exports=b(require("jquery")):a.VintageJS=b(jQuery)}(this,function(a){var b=function(a,b,c){if(!1==a instanceof HTMLImageElement)throw"The element (1st parameter) must be an instance of HTMLImageElement";var d,e,f,g,h,i,j,k,l,m=new Image,n=new Image,o=document.createElement("canvas"),p=o.getContext("2d"),q={onStart:function(){},onStop:function(){},onError:function(){},mime:"image/jpeg"},r={curves:!1,screen:!1,desaturate:!1,vignette:!1,lighten:!1,noise:!1,viewFinder:!1,sepia:!1,brightness:!1,contrast:!1};m.onerror=q.onError,m.onload=function(){i=o.width=m.width,j=o.height=m.height,d()},n.onerror=q.onError,n.onload=function(){p.clearRect(0,0,i,j),p.drawImage(n,0,0,i,j),(window.vjsImageCache||(window.vjsImageCache={}))[l]=p.getImageData(0,0,i,j).data,d()},e=function(a){q.onStart(),k={};for(var b in r)k[b]=a[b]||r[b];g=[],k.viewFinder&&g.push(k.viewFinder),m.src==h?d():m.src=h},d=function(){if(0===g.length)return f();var a=g.pop();return l=[i,j,a].join("-"),window.vjsImageCache&&window.vjsImageCache[l]?d():void(n.src=a)},f=function(){var b,c,d;p.clearRect(0,0,i,j),p.drawImage(m,0,0,i,j),(k.vignette||k.lighten)&&(b=Math.sqrt(Math.pow(i/2,2)+Math.pow(j/2,2))),k.vignette&&(p.globalCompositeOperation="source-over",c=p.createRadialGradient(i/2,j/2,0,i/2,j/2,b),c.addColorStop(0,"rgba(0,0,0,0)"),c.addColorStop(.5,"rgba(0,0,0,0)"),c.addColorStop(1,["rgba(0,0,0,",k.vignette,")"].join("")),p.fillStyle=c,p.fillRect(0,0,i,j)),k.lighten&&(p.globalCompositeOperation="lighter",c=p.createRadialGradient(i/2,j/2,0,i/2,j/2,b),c.addColorStop(0,["rgba(255,255,255,",k.lighten,")"].join("")),c.addColorStop(.5,"rgba(255,255,255,0)"),c.addColorStop(1,"rgba(0,0,0,0)"),p.fillStyle=c,p.fillRect(0,0,i,j)),d=p.getImageData(0,0,i,j);var e,f,g,h,l,n,o,r,s,t=d.data;k.contrast&&(s=259*(k.contrast+255)/(255*(259-k.contrast))),k.viewFinder&&(r=window.vjsImageCache[[i,j,k.viewFinder].join("-")]);for(var u=i*j;u>=0;--u)for(e=u<<2,k.curves&&(t[e]=k.curves.r[t[e]],t[e+1]=k.curves.g[t[e+1]],t[e+2]=k.curves.b[t[e+2]]),k.contrast&&(t[e]=s*(t[e]-128)+128,t[e+1]=s*(t[e+1]-128)+128,t[e+2]=s*(t[e+2]-128)+128),k.brightness&&(t[e]+=k.brightness,t[e+1]+=k.brightness,t[e+2]+=k.brightness),k.screen&&(t[e]=255-(255-t[e])*(255-k.screen.r*k.screen.a)/255,t[e+1]=255-(255-t[e+1])*(255-k.screen.g*k.screen.a)/255,t[e+2]=255-(255-t[e+2])*(255-k.screen.b*k.screen.a)/255),k.noise&&(o=k.noise-Math.random()*k.noise/2,t[e]+=o,t[e+1]+=o,t[e+2]+=o),k.viewFinder&&(t[e]=t[e]*r[e]/255,t[e+1]=t[e+1]*r[e+1]/255,t[e+2]=t[e+2]*r[e+2]/255),k.sepia&&(g=t[e],h=t[e+1],l=t[e+2],t[e]=.393*g+.769*h+.189*l,t[e+1]=.349*g+.686*h+.168*l,t[e+2]=.272*g+.534*h+.131*l),k.desaturate&&(n=(t[e]+t[e+1]+t[e+2])/3,t[e]+=(n-t[e])*k.desaturate,t[e+1]+=(n-t[e+1])*k.desaturate,t[e+2]+=(n-t[e+2])*k.desaturate),f=2;f>=0;--f)t[e+f]=~~(t[e+f]>255?255:t[e+f]<0?0:t[e+f]);p.putImageData(d,0,0),a.src=p.canvas.toDataURL(q.mime),q.onStop()},h=a.src,b=b||{};for(var s in q)q[s]=b[s]||q[s];return c&&e(c),{apply:function(){h=a.src},reset:function(){a.src=h},vintage:e}};return a.fn.vintage=function(c,d){return this.each(function(){a.data(this,"vintageJS")||a.data(this,"vintageJS",new b(this,c,d))})},b});
58
+
59
+
60
+ /*
61
+
62
+ Superfast Blur - a fast Box Blur For Canvas
63
+
64
+ Version: 0.5
65
+ Author: Mario Klingemann
66
+ Contact: mario@quasimondo.com
67
+ Website: http://www.quasimondo.com/BoxBlurForCanvas
68
+ Twitter: @quasimondo
69
+
70
+ In case you find this class useful - especially in commercial projects -
71
+ I am not totally unhappy for a small donation to my PayPal account
72
+ mario@quasimondo.de
73
+
74
+ Or support me on flattr:
75
+ https://flattr.com/thing/140066/Superfast-Blur-a-pretty-fast-Box-Blur-Effect-for-CanvasJavascript
76
+
77
+ Copyright (c) 2011 Mario Klingemann
78
+
79
+ Permission is hereby granted, free of charge, to any person
80
+ obtaining a copy of this software and associated documentation
81
+ files (the "Software"), to deal in the Software without
82
+ restriction, including without limitation the rights to use,
83
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
84
+ copies of the Software, and to permit persons to whom the
85
+ Software is furnished to do so, subject to the following
86
+ conditions:
87
+
88
+ The above copyright notice and this permission notice shall be
89
+ included in all copies or substantial portions of the Software.
90
+
91
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
92
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
93
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
94
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
95
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
96
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
97
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
98
+ OTHER DEALINGS IN THE SOFTWARE.
99
+ */
100
+ var mul_table = [ 1,57,41,21,203,34,97,73,227,91,149,62,105,45,39,137,241,107,3,173,39,71,65,238,219,101,187,87,81,151,141,133,249,117,221,209,197,187,177,169,5,153,73,139,133,127,243,233,223,107,103,99,191,23,177,171,165,159,77,149,9,139,135,131,253,245,119,231,224,109,211,103,25,195,189,23,45,175,171,83,81,79,155,151,147,9,141,137,67,131,129,251,123,30,235,115,113,221,217,53,13,51,50,49,193,189,185,91,179,175,43,169,83,163,5,79,155,19,75,147,145,143,35,69,17,67,33,65,255,251,247,243,239,59,29,229,113,111,219,27,213,105,207,51,201,199,49,193,191,47,93,183,181,179,11,87,43,85,167,165,163,161,159,157,155,77,19,75,37,73,145,143,141,35,138,137,135,67,33,131,129,255,63,250,247,61,121,239,237,117,29,229,227,225,111,55,109,216,213,211,209,207,205,203,201,199,197,195,193,48,190,47,93,185,183,181,179,178,176,175,173,171,85,21,167,165,41,163,161,5,79,157,78,154,153,19,75,149,74,147,73,144,143,71,141,140,139,137,17,135,134,133,66,131,65,129,1];
101
+
102
+
103
+ var shg_table = [0,9,10,10,14,12,14,14,16,15,16,15,16,15,15,17,18,17,12,18,16,17,17,19,19,18,19,18,18,19,19,19,20,19,20,20,20,20,20,20,15,20,19,20,20,20,21,21,21,20,20,20,21,18,21,21,21,21,20,21,17,21,21,21,22,22,21,22,22,21,22,21,19,22,22,19,20,22,22,21,21,21,22,22,22,18,22,22,21,22,22,23,22,20,23,22,22,23,23,21,19,21,21,21,23,23,23,22,23,23,21,23,22,23,18,22,23,20,22,23,23,23,21,22,20,22,21,22,24,24,24,24,24,22,21,24,23,23,24,21,24,23,24,22,24,24,22,24,24,22,23,24,24,24,20,23,22,23,24,24,24,24,24,24,24,23,21,23,22,23,24,24,24,22,24,24,24,23,22,24,24,25,23,25,25,23,24,25,25,24,22,25,25,25,24,23,24,25,25,25,25,25,25,25,25,25,25,25,25,23,25,23,24,25,25,25,25,25,25,25,25,25,24,22,25,25,23,25,25,20,24,25,24,25,25,22,24,25,24,25,24,25,25,24,25,25,25,25,22,25,25,25,24,25,24,25,18];
104
+
105
+
106
+ function boxBlurImage( imageID, canvasID, radius, blurAlphaChannel, iterations ){
107
+
108
+ var img = document.getElementById( imageID );
109
+ var w = img.naturalWidth;
110
+ var h = img.naturalHeight;
111
+
112
+ var canvas = document.getElementById( canvasID );
113
+
114
+ canvas.style.width = w + "px";
115
+ canvas.style.height = h + "px";
116
+ canvas.width = w;
117
+ canvas.height = h;
118
+
119
+ var context = canvas.getContext("2d");
120
+ context.clearRect( 0, 0, w, h );
121
+ context.drawImage( img, 0, 0 );
122
+
123
+ if ( isNaN(radius) || radius < 1 ) return;
124
+
125
+ if ( blurAlphaChannel )
126
+ {
127
+ boxBlurCanvasRGBA( canvasID, 0, 0, w, h, radius, iterations );
128
+ } else {
129
+ boxBlurCanvasRGB( canvasID, 0, 0, w, h, radius, iterations );
130
+ }
131
+
132
+ }
133
+
134
+
135
+ function boxBlurCanvasRGBA( id, top_x, top_y, width, height, radius, iterations ){
136
+ if ( isNaN(radius) || radius < 1 ) return;
137
+
138
+ radius |= 0;
139
+
140
+ if ( isNaN(iterations) ) iterations = 1;
141
+ iterations |= 0;
142
+ if ( iterations > 3 ) iterations = 3;
143
+ if ( iterations < 1 ) iterations = 1;
144
+
145
+ var canvas = document.getElementById( id );
146
+ var context = canvas.getContext("2d");
147
+ var imageData;
148
+
149
+ try {
150
+ try {
151
+ imageData = context.getImageData( top_x, top_y, width, height );
152
+ } catch(e) {
153
+
154
+ // NOTE: this part is supposedly only needed if you want to work with local files
155
+ // so it might be okay to remove the whole try/catch block and just use
156
+ // imageData = context.getImageData( top_x, top_y, width, height );
157
+ try {
158
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
159
+ imageData = context.getImageData( top_x, top_y, width, height );
160
+ } catch(e) {
161
+ alert("Cannot access local image");
162
+ throw new Error("unable to access local image data: " + e);
163
+ return;
164
+ }
165
+ }
166
+ } catch(e) {
167
+ alert("Cannot access image");
168
+ throw new Error("unable to access image data: " + e);
169
+ return;
170
+ }
171
+
172
+ var pixels = imageData.data;
173
+
174
+ var rsum,gsum,bsum,asum,x,y,i,p,p1,p2,yp,yi,yw,idx,pa;
175
+ var wm = width - 1;
176
+ var hm = height - 1;
177
+ var wh = width * height;
178
+ var rad1 = radius + 1;
179
+
180
+ var mul_sum = mul_table[radius];
181
+ var shg_sum = shg_table[radius];
182
+
183
+ var r = [];
184
+ var g = [];
185
+ var b = [];
186
+ var a = [];
187
+
188
+ var vmin = [];
189
+ var vmax = [];
190
+
191
+ while ( iterations-- > 0 ){
192
+ yw = yi = 0;
193
+
194
+ for ( y=0; y < height; y++ ){
195
+ rsum = pixels[yw] * rad1;
196
+ gsum = pixels[yw+1] * rad1;
197
+ bsum = pixels[yw+2] * rad1;
198
+ asum = pixels[yw+3] * rad1;
199
+
200
+
201
+ for( i = 1; i <= radius; i++ ){
202
+ p = yw + (((i > wm ? wm : i )) << 2 );
203
+ rsum += pixels[p++];
204
+ gsum += pixels[p++];
205
+ bsum += pixels[p++];
206
+ asum += pixels[p]
207
+ }
208
+
209
+ for ( x = 0; x < width; x++ ) {
210
+ r[yi] = rsum;
211
+ g[yi] = gsum;
212
+ b[yi] = bsum;
213
+ a[yi] = asum;
214
+
215
+ if( y==0) {
216
+ vmin[x] = ( ( p = x + rad1) < wm ? p : wm ) << 2;
217
+ vmax[x] = ( ( p = x - radius) > 0 ? p << 2 : 0 );
218
+ }
219
+
220
+ p1 = yw + vmin[x];
221
+ p2 = yw + vmax[x];
222
+
223
+ rsum += pixels[p1++] - pixels[p2++];
224
+ gsum += pixels[p1++] - pixels[p2++];
225
+ bsum += pixels[p1++] - pixels[p2++];
226
+ asum += pixels[p1] - pixels[p2];
227
+
228
+ yi++;
229
+ }
230
+ yw += ( width << 2 );
231
+ }
232
+
233
+ for ( x = 0; x < width; x++ ) {
234
+ yp = x;
235
+ rsum = r[yp] * rad1;
236
+ gsum = g[yp] * rad1;
237
+ bsum = b[yp] * rad1;
238
+ asum = a[yp] * rad1;
239
+
240
+ for( i = 1; i <= radius; i++ ) {
241
+ yp += ( i > hm ? 0 : width );
242
+ rsum += r[yp];
243
+ gsum += g[yp];
244
+ bsum += b[yp];
245
+ asum += a[yp];
246
+ }
247
+
248
+ yi = x << 2;
249
+ for ( y = 0; y < height; y++) {
250
+
251
+ pixels[yi+3] = pa = (asum * mul_sum) >>> shg_sum;
252
+ if ( pa > 0 )
253
+ {
254
+ pa = 255 / pa;
255
+ pixels[yi] = ((rsum * mul_sum) >>> shg_sum) * pa;
256
+ pixels[yi+1] = ((gsum * mul_sum) >>> shg_sum) * pa;
257
+ pixels[yi+2] = ((bsum * mul_sum) >>> shg_sum) * pa;
258
+ } else {
259
+ pixels[yi] = pixels[yi+1] = pixels[yi+2] = 0;
260
+ }
261
+ if( x == 0 ) {
262
+ vmin[y] = ( ( p = y + rad1) < hm ? p : hm ) * width;
263
+ vmax[y] = ( ( p = y - radius) > 0 ? p * width : 0 );
264
+ }
265
+
266
+ p1 = x + vmin[y];
267
+ p2 = x + vmax[y];
268
+
269
+ rsum += r[p1] - r[p2];
270
+ gsum += g[p1] - g[p2];
271
+ bsum += b[p1] - b[p2];
272
+ asum += a[p1] - a[p2];
273
+
274
+ yi += width << 2;
275
+ }
276
+ }
277
+ }
278
+
279
+ context.putImageData( imageData, top_x, top_y );
280
+
281
+ }
282
+
283
+ function boxBlurCanvasRGB( id, top_x, top_y, width, height, radius, iterations ){
284
+ if ( isNaN(radius) || radius < 1 ) return;
285
+
286
+ radius |= 0;
287
+
288
+ if ( isNaN(iterations) ) iterations = 1;
289
+ iterations |= 0;
290
+ if ( iterations > 3 ) iterations = 3;
291
+ if ( iterations < 1 ) iterations = 1;
292
+
293
+ var canvas = id;
294
+ var context = canvas.getContext("2d");
295
+ var imageData;
296
+
297
+ try {
298
+ try {
299
+ imageData = context.getImageData( top_x, top_y, width, height );
300
+ } catch(e) {
301
+
302
+ // NOTE: this part is supposedly only needed if you want to work with local files
303
+ // so it might be okay to remove the whole try/catch block and just use
304
+ // imageData = context.getImageData( top_x, top_y, width, height );
305
+ try {
306
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
307
+ imageData = context.getImageData( top_x, top_y, width, height );
308
+ } catch(e) {
309
+ alert("Cannot access local image");
310
+ throw new Error("unable to access local image data: " + e);
311
+ return;
312
+ }
313
+ }
314
+ } catch(e) {
315
+ alert("Cannot access image");
316
+ throw new Error("unable to access image data: " + e);
317
+ return;
318
+ }
319
+
320
+ var pixels = imageData.data;
321
+
322
+ var rsum,gsum,bsum,asum,x,y,i,p,p1,p2,yp,yi,yw,idx;
323
+ var wm = width - 1;
324
+ var hm = height - 1;
325
+ var wh = width * height;
326
+ var rad1 = radius + 1;
327
+
328
+ var r = [];
329
+ var g = [];
330
+ var b = [];
331
+
332
+ var mul_sum = mul_table[radius];
333
+ var shg_sum = shg_table[radius];
334
+
335
+ var vmin = [];
336
+ var vmax = [];
337
+
338
+ while ( iterations-- > 0 ){
339
+ yw = yi = 0;
340
+
341
+ for ( y=0; y < height; y++ ){
342
+ rsum = pixels[yw] * rad1;
343
+ gsum = pixels[yw+1] * rad1;
344
+ bsum = pixels[yw+2] * rad1;
345
+
346
+ for( i = 1; i <= radius; i++ ){
347
+ p = yw + (((i > wm ? wm : i )) << 2 );
348
+ rsum += pixels[p++];
349
+ gsum += pixels[p++];
350
+ bsum += pixels[p++];
351
+ }
352
+
353
+ for ( x = 0; x < width; x++ ){
354
+ r[yi] = rsum;
355
+ g[yi] = gsum;
356
+ b[yi] = bsum;
357
+
358
+ if( y==0) {
359
+ vmin[x] = ( ( p = x + rad1) < wm ? p : wm ) << 2;
360
+ vmax[x] = ( ( p = x - radius) > 0 ? p << 2 : 0 );
361
+ }
362
+
363
+ p1 = yw + vmin[x];
364
+ p2 = yw + vmax[x];
365
+
366
+ rsum += pixels[p1++] - pixels[p2++];
367
+ gsum += pixels[p1++] - pixels[p2++];
368
+ bsum += pixels[p1++] - pixels[p2++];
369
+
370
+ yi++;
371
+ }
372
+ yw += ( width << 2 );
373
+ }
374
+
375
+ for ( x = 0; x < width; x++ ){
376
+ yp = x;
377
+ rsum = r[yp] * rad1;
378
+ gsum = g[yp] * rad1;
379
+ bsum = b[yp] * rad1;
380
+
381
+ for( i = 1; i <= radius; i++ ){
382
+ yp += ( i > hm ? 0 : width );
383
+ rsum += r[yp];
384
+ gsum += g[yp];
385
+ bsum += b[yp];
386
+ }
387
+
388
+ yi = x << 2;
389
+ for ( y = 0; y < height; y++){
390
+ pixels[yi] = (rsum * mul_sum) >>> shg_sum;
391
+ pixels[yi+1] = (gsum * mul_sum) >>> shg_sum;
392
+ pixels[yi+2] = (bsum * mul_sum) >>> shg_sum;
393
+
394
+ if( x == 0 ) {
395
+ vmin[y] = ( ( p = y + rad1) < hm ? p : hm ) * width;
396
+ vmax[y] = ( ( p = y - radius) > 0 ? p * width : 0 );
397
+ }
398
+
399
+ p1 = x + vmin[y];
400
+ p2 = x + vmax[y];
401
+
402
+ rsum += r[p1] - r[p2];
403
+ gsum += g[p1] - g[p2];
404
+ bsum += b[p1] - b[p2];
405
+
406
+ yi += width << 2;
407
+ }
408
+ }
409
+ }
410
+ context.putImageData( imageData, top_x, top_y );
411
+
412
+ }
assets/js/lib/jquery.justifiedGallery.js ADDED
@@ -0,0 +1,1158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Justified Gallery - v3.6.2
3
+ * http://miromannino.github.io/Justified-Gallery/
4
+ * Copyright (c) 2016 Miro Mannino
5
+ * Licensed under the MIT license.
6
+ */
7
+ (function($) {
8
+
9
+ function hasScrollBar() {
10
+ return $("body").height() > $(window).height();
11
+ }
12
+ /**
13
+ * Justified Gallery controller constructor
14
+ *
15
+ * @param $gallery the gallery to build
16
+ * @param settings the settings (the defaults are in $.fn.justifiedGallery.defaults)
17
+ * @constructor
18
+ */
19
+ var JustifiedGallery = function ($gallery, settings) {
20
+
21
+ this.settings = settings;
22
+ this.checkSettings();
23
+
24
+ this.imgAnalyzerTimeout = null;
25
+ this.entries = null;
26
+ this.buildingRow = {
27
+ entriesBuff : [],
28
+ width : 0,
29
+ height : 0,
30
+ aspectRatio : 0
31
+ };
32
+ this.lastAnalyzedIndex = -1;
33
+ this.yield = {
34
+ every : 2, // do a flush every n flushes (must be greater than 1)
35
+ flushed : 0 // flushed rows without a yield
36
+ };
37
+ this.border = settings.border >= 0 ? settings.border : settings.margins;
38
+ this.maxRowHeight = this.retrieveMaxRowHeight();
39
+ this.suffixRanges = this.retrieveSuffixRanges();
40
+ this.offY = this.border;
41
+ this.rows = 0;
42
+ this.spinner = {
43
+ phase : 0,
44
+ timeSlot : 150,
45
+ $el : $('<div class="spinner"><span></span><span></span><span></span></div>'),
46
+ intervalId : null
47
+ };
48
+ this.checkWidthIntervalId = null;
49
+ this.galleryWidth = $gallery.width();
50
+ this.$gallery = $gallery;
51
+
52
+ };
53
+
54
+ /** @returns {String} the best suffix given the width and the height */
55
+ JustifiedGallery.prototype.getSuffix = function (width, height) {
56
+ var longestSide, i;
57
+ longestSide = (width > height) ? width : height;
58
+ for (i = 0; i < this.suffixRanges.length; i++) {
59
+ if (longestSide <= this.suffixRanges[i]) {
60
+ return this.settings.sizeRangeSuffixes[this.suffixRanges[i]];
61
+ }
62
+ }
63
+ return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]];
64
+ };
65
+
66
+ /**
67
+ * Remove the suffix from the string
68
+ *
69
+ * @returns {string} a new string without the suffix
70
+ */
71
+ JustifiedGallery.prototype.removeSuffix = function (str, suffix) {
72
+ return str.substring(0, str.length - suffix.length);
73
+ };
74
+
75
+ /**
76
+ * @returns {boolean} a boolean to say if the suffix is contained in the str or not
77
+ */
78
+ JustifiedGallery.prototype.endsWith = function (str, suffix) {
79
+ return str.indexOf(suffix, str.length - suffix.length) !== -1;
80
+ };
81
+
82
+ /**
83
+ * Get the used suffix of a particular url
84
+ *
85
+ * @param str
86
+ * @returns {String} return the used suffix
87
+ */
88
+ JustifiedGallery.prototype.getUsedSuffix = function (str) {
89
+ for (var si in this.settings.sizeRangeSuffixes) {
90
+ if (this.settings.sizeRangeSuffixes.hasOwnProperty(si)) {
91
+ if (this.settings.sizeRangeSuffixes[si].length === 0) continue;
92
+ if (this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si];
93
+ }
94
+ }
95
+ return '';
96
+ };
97
+
98
+ /**
99
+ * Given an image src, with the width and the height, returns the new image src with the
100
+ * best suffix to show the best quality thumbnail.
101
+ *
102
+ * @returns {String} the suffix to use
103
+ */
104
+ JustifiedGallery.prototype.newSrc = function (imageSrc, imgWidth, imgHeight) {
105
+ var newImageSrc;
106
+
107
+ if (this.settings.thumbnailPath) {
108
+ newImageSrc = this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight);
109
+ } else {
110
+ var matchRes = imageSrc.match(this.settings.extension);
111
+ var ext = (matchRes !== null) ? matchRes[0] : '';
112
+ newImageSrc = imageSrc.replace(this.settings.extension, '');
113
+ newImageSrc = this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc));
114
+ newImageSrc += this.getSuffix(imgWidth, imgHeight) + ext;
115
+ }
116
+
117
+ return newImageSrc;
118
+ };
119
+
120
+ /**
121
+ * Shows the images that is in the given entry
122
+ *
123
+ * @param $entry the entry
124
+ * @param callback the callback that is called when the show animation is finished
125
+ */
126
+ JustifiedGallery.prototype.showImg = function ($entry, callback) {
127
+ if (this.settings.cssAnimation) {
128
+ $entry.addClass('entry-visible');
129
+ if (callback) callback();
130
+ } else {
131
+ $entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback);
132
+ }
133
+ };
134
+
135
+ /**
136
+ * Extract the image src form the image, looking from the 'safe-src', and if it can't be found, from the
137
+ * 'src' attribute. It saves in the image data the 'jg.originalSrc' field, with the extracted src.
138
+ *
139
+ * @param $image the image to analyze
140
+ * @returns {String} the extracted src
141
+ */
142
+ JustifiedGallery.prototype.extractImgSrcFromImage = function ($image) {
143
+ var imageSrc = (typeof $image.data('safe-src') !== 'undefined') ? $image.data('safe-src') : $image.attr('src');
144
+ $image.data('jg.originalSrc', imageSrc);
145
+ return imageSrc;
146
+ };
147
+
148
+ /** @returns {jQuery} the image in the given entry */
149
+ JustifiedGallery.prototype.imgFromEntry = function ($entry) {
150
+ var $img = $entry.find('> img');
151
+ if ($img.length === 0) $img = $entry.find('> a > img');
152
+ return $img.length === 0 ? null : $img;
153
+ };
154
+
155
+ /** @returns {jQuery} the caption in the given entry */
156
+ JustifiedGallery.prototype.captionFromEntry = function ($entry) {
157
+ var $caption = $entry.find('> .caption');
158
+ return $caption.length === 0 ? null : $caption;
159
+ };
160
+
161
+ /**
162
+ * Display the entry
163
+ *
164
+ * @param {jQuery} $entry the entry to display
165
+ * @param {int} x the x position where the entry must be positioned
166
+ * @param y the y position where the entry must be positioned
167
+ * @param imgWidth the image width
168
+ * @param imgHeight the image height
169
+ * @param rowHeight the row height of the row that owns the entry
170
+ */
171
+ JustifiedGallery.prototype.displayEntry = function ($entry, x, y, imgWidth, imgHeight, rowHeight) {
172
+ $entry.width(imgWidth);
173
+ $entry.height(rowHeight);
174
+ $entry.css('top', y);
175
+ $entry.css('left', x);
176
+
177
+ var $image = this.imgFromEntry($entry);
178
+ if ($image !== null) {
179
+ $image.css('width', imgWidth);
180
+ $image.css('height', imgHeight);
181
+ $image.css('margin-left', - imgWidth / 2);
182
+ $image.css('margin-top', - imgHeight / 2);
183
+
184
+ // Image reloading for an high quality of thumbnails
185
+ var imageSrc = $image.attr('src');
186
+ var newImageSrc = this.newSrc(imageSrc, imgWidth, imgHeight);
187
+
188
+ $image.one('error', function () {
189
+ $image.attr('src', $image.data('jg.originalSrc')); //revert to the original thumbnail, we got it.
190
+ });
191
+
192
+ var loadNewImage = function () {
193
+ if (imageSrc !== newImageSrc) { //load the new image after the fadeIn
194
+ $image.attr('src', newImageSrc);
195
+ }
196
+ };
197
+
198
+ if ($entry.data('jg.loaded') === 'skipped') {
199
+ this.onImageEvent(imageSrc, $.proxy(function() {
200
+ this.showImg($entry, loadNewImage);
201
+ $entry.data('jg.loaded', true);
202
+ }, this));
203
+ } else {
204
+ this.showImg($entry, loadNewImage);
205
+ }
206
+
207
+ } else {
208
+ this.showImg($entry);
209
+ }
210
+
211
+ this.displayEntryCaption($entry);
212
+ };
213
+
214
+ /**
215
+ * Display the entry caption. If the caption element doesn't exists, it creates the caption using the 'alt'
216
+ * or the 'title' attributes.
217
+ *
218
+ * @param {jQuery} $entry the entry to process
219
+ */
220
+ JustifiedGallery.prototype.displayEntryCaption = function ($entry) {
221
+ var $image = this.imgFromEntry($entry);
222
+ if ($image !== null && this.settings.captions) {
223
+ var $imgCaption = this.captionFromEntry($entry);
224
+
225
+ // Create it if it doesn't exists
226
+ if ($imgCaption === null) {
227
+ var caption = $image.attr('alt');
228
+ if (!this.isValidCaption(caption)) caption = $entry.attr('title');
229
+ if (this.isValidCaption(caption)) { // Create only we found something
230
+ $imgCaption = $('<div class="caption">' + caption + '</div>');
231
+ $entry.append($imgCaption);
232
+ $entry.data('jg.createdCaption', true);
233
+ }
234
+ }
235
+
236
+ // Create events (we check again the $imgCaption because it can be still inexistent)
237
+ if ($imgCaption !== null) {
238
+ if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity);
239
+ this.addCaptionEventsHandlers($entry);
240
+ }
241
+ } else {
242
+ this.removeCaptionEventsHandlers($entry);
243
+ }
244
+ };
245
+
246
+ /**
247
+ * Validates the caption
248
+ *
249
+ * @param caption The caption that should be validated
250
+ * @return {boolean} Validation result
251
+ */
252
+ JustifiedGallery.prototype.isValidCaption = function (caption) {
253
+ return (typeof caption !== 'undefined' && caption.length > 0);
254
+ };
255
+
256
+ /**
257
+ * The callback for the event 'mouseenter'. It assumes that the event currentTarget is an entry.
258
+ * It shows the caption using jQuery (or using CSS if it is configured so)
259
+ *
260
+ * @param {Event} eventObject the event object
261
+ */
262
+ JustifiedGallery.prototype.onEntryMouseEnterForCaption = function (eventObject) {
263
+ var $caption = this.captionFromEntry($(eventObject.currentTarget));
264
+ if (this.settings.cssAnimation) {
265
+ $caption.addClass('caption-visible').removeClass('caption-hidden');
266
+ } else {
267
+ $caption.stop().fadeTo(this.settings.captionSettings.animationDuration,
268
+ this.settings.captionSettings.visibleOpacity);
269
+ }
270
+ };
271
+
272
+ /**
273
+ * The callback for the event 'mouseleave'. It assumes that the event currentTarget is an entry.
274
+ * It hides the caption using jQuery (or using CSS if it is configured so)
275
+ *
276
+ * @param {Event} eventObject the event object
277
+ */
278
+ JustifiedGallery.prototype.onEntryMouseLeaveForCaption = function (eventObject) {
279
+ var $caption = this.captionFromEntry($(eventObject.currentTarget));
280
+ if (this.settings.cssAnimation) {
281
+ $caption.removeClass('caption-visible').removeClass('caption-hidden');
282
+ } else {
283
+ $caption.stop().fadeTo(this.settings.captionSettings.animationDuration,
284
+ this.settings.captionSettings.nonVisibleOpacity);
285
+ }
286
+ };
287
+
288
+ /**
289
+ * Add the handlers of the entry for the caption
290
+ *
291
+ * @param $entry the entry to modify
292
+ */
293
+ JustifiedGallery.prototype.addCaptionEventsHandlers = function ($entry) {
294
+ var captionMouseEvents = $entry.data('jg.captionMouseEvents');
295
+ if (typeof captionMouseEvents === 'undefined') {
296
+ captionMouseEvents = {
297
+ mouseenter: $.proxy(this.onEntryMouseEnterForCaption, this),
298
+ mouseleave: $.proxy(this.onEntryMouseLeaveForCaption, this)
299
+ };
300
+ $entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter);
301
+ $entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave);
302
+ $entry.data('jg.captionMouseEvents', captionMouseEvents);
303
+ }
304
+ };
305
+
306
+ /**
307
+ * Remove the handlers of the entry for the caption
308
+ *
309
+ * @param $entry the entry to modify
310
+ */
311
+ JustifiedGallery.prototype.removeCaptionEventsHandlers = function ($entry) {
312
+ var captionMouseEvents = $entry.data('jg.captionMouseEvents');
313
+ if (typeof captionMouseEvents !== 'undefined') {
314
+ $entry.off('mouseenter', undefined, captionMouseEvents.mouseenter);
315
+ $entry.off('mouseleave', undefined, captionMouseEvents.mouseleave);
316
+ $entry.removeData('jg.captionMouseEvents');
317
+ }
318
+ };
319
+
320
+ /**
321
+ * Justify the building row, preparing it to
322
+ *
323
+ * @param isLastRow
324
+ * @returns a boolean to know if the row has been justified or not
325
+ */
326
+ JustifiedGallery.prototype.prepareBuildingRow = function (isLastRow) {
327
+ var i, $entry, imgAspectRatio, newImgW, newImgH, justify = true;
328
+ var minHeight = 0;
329
+ var availableWidth = this.galleryWidth - 2 * this.border - (
330
+ (this.buildingRow.entriesBuff.length - 1) * this.settings.margins);
331
+ var rowHeight = availableWidth / this.buildingRow.aspectRatio;
332
+ var defaultRowHeight = this.settings.rowHeight;
333
+ var justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold;
334
+
335
+ //Skip the last row if we can't justify it and the lastRow == 'hide'
336
+ if (isLastRow && this.settings.lastRow === 'hide' && !justifiable) {
337
+ for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
338
+ $entry = this.buildingRow.entriesBuff[i];
339
+ if (this.settings.cssAnimation)
340
+ $entry.removeClass('entry-visible');
341
+ else
342
+ $entry.stop().fadeTo(0, 0);
343
+ }
344
+ return -1;
345
+ }
346
+
347
+ // With lastRow = nojustify, justify if is justificable (the images will not become too big)
348
+ if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') {
349
+ justify = false;
350
+
351
+ if (this.rows > 0) {
352
+ defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows;
353
+ if (defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold) {
354
+ justify = true;
355
+ } else {
356
+ justify = false;
357
+ }
358
+ }
359
+ }
360
+
361
+ for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
362
+ $entry = this.buildingRow.entriesBuff[i];
363
+ imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height');
364
+
365
+ if (justify) {
366
+ newImgW = (i === this.buildingRow.entriesBuff.length - 1) ? availableWidth : rowHeight * imgAspectRatio;
367
+ newImgH = rowHeight;
368
+
369
+ /* With fixedHeight the newImgH must be greater than rowHeight.
370
+ In some cases here this is not satisfied (due to the justification).
371
+ But we comment it, because is better to have a shorter but justified row instead
372
+ to have a cropped image at the end. */
373
+ /*if (this.settings.fixedHeight && newImgH < this.settings.rowHeight) {
374
+ newImgW = this.settings.rowHeight * imgAspectRatio;
375
+ newImgH = this.settings.rowHeight;
376
+ }*/
377
+
378
+ } else {
379
+ newImgW = defaultRowHeight * imgAspectRatio;
380
+ newImgH = defaultRowHeight;
381
+ }
382
+
383
+ availableWidth -= Math.round(newImgW);
384
+ $entry.data('jg.jwidth', Math.round(newImgW));
385
+ $entry.data('jg.jheight', Math.ceil(newImgH));
386
+ if (i === 0 || minHeight > newImgH) minHeight = newImgH;
387
+ }
388
+
389
+ if (this.settings.fixedHeight && minHeight > this.settings.rowHeight)
390
+ minHeight = this.settings.rowHeight;
391
+
392
+ this.buildingRow.height = minHeight;
393
+ return justify;
394
+ };
395
+
396
+ /**
397
+ * Clear the building row data to be used for a new row
398
+ */
399
+ JustifiedGallery.prototype.clearBuildingRow = function () {
400
+ this.buildingRow.entriesBuff = [];
401
+ this.buildingRow.aspectRatio = 0;
402
+ this.buildingRow.width = 0;
403
+ };
404
+
405
+ /**
406
+ * Flush a row: justify it, modify the gallery height accordingly to the row height
407
+ *
408
+ * @param isLastRow
409
+ */
410
+ JustifiedGallery.prototype.flushRow = function (isLastRow) {
411
+ var settings = this.settings;
412
+ var $entry, buildingRowRes, offX = this.border, i;
413
+
414
+ buildingRowRes = this.prepareBuildingRow(isLastRow);
415
+ if (isLastRow && settings.lastRow === 'hide' && buildingRowRes === -1) {
416
+ this.clearBuildingRow();
417
+ return;
418
+ }
419
+
420
+ if (this.maxRowHeight.isPercentage) {
421
+ if (this.maxRowHeight.value * settings.rowHeight < this.buildingRow.height) {
422
+ this.buildingRow.height = this.maxRowHeight.value * settings.rowHeight;
423
+ }
424
+ } else {
425
+ if (this.maxRowHeight.value > 0 && this.maxRowHeight.value < this.buildingRow.height) {
426
+ this.buildingRow.height = this.maxRowHeight.value;
427
+ }
428
+ }
429
+
430
+ //Align last (unjustified) row
431
+ if (settings.lastRow === 'center' || settings.lastRow === 'right') {
432
+ var availableWidth = this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins;
433
+
434
+ for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
435
+ $entry = this.buildingRow.entriesBuff[i];
436
+ availableWidth -= $entry.data('jg.jwidth');
437
+ }
438
+
439
+ if (settings.lastRow === 'center')
440
+ offX += availableWidth / 2;
441
+ else if (settings.lastRow === 'right')
442
+ offX += availableWidth;
443
+ }
444
+
445
+ for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
446
+ $entry = this.buildingRow.entriesBuff[i];
447
+ this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height);
448
+ offX += $entry.data('jg.jwidth') + settings.margins;
449
+ }
450
+
451
+ //Gallery Height
452
+ this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border;
453
+ this.$gallery.height(this.galleryHeightToSet + this.getSpinnerHeight());
454
+
455
+ if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowRes)) {
456
+ //Ready for a new row
457
+ this.offY += this.buildingRow.height + settings.margins;
458
+ this.rows += 1;
459
+ this.clearBuildingRow();
460
+ this.$gallery.trigger('jg.rowflush');
461
+ }
462
+ };
463
+
464
+ /**
465
+ * Checks the width of the gallery container, to know if a new justification is needed
466
+ */
467
+ var scrollBarOn = false;
468
+ JustifiedGallery.prototype.checkWidth = function () {
469
+ this.checkWidthIntervalId = setInterval($.proxy(function () {
470
+ var galleryWidth = parseFloat(this.$gallery.width());
471
+ if (hasScrollBar() === scrollBarOn){
472
+
473
+ if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) {
474
+ this.galleryWidth = galleryWidth;
475
+ this.rewind();
476
+
477
+ // Restart to analyze
478
+ this.startImgAnalyzer(true);
479
+ }
480
+ } else {
481
+ scrollBarOn = hasScrollBar();
482
+ this.galleryWidth = galleryWidth;
483
+ }
484
+ }, this), this.settings.refreshTime);
485
+ };
486
+
487
+ /**
488
+ * @returns {boolean} a boolean saying if the spinner is active or not
489
+ */
490
+ JustifiedGallery.prototype.isSpinnerActive = function () {
491
+ return this.spinner.intervalId !== null;
492
+ };
493
+
494
+ /**
495
+ * @returns {int} the spinner height
496
+ */
497
+ JustifiedGallery.prototype.getSpinnerHeight = function () {
498
+ return this.spinner.$el.innerHeight();
499
+ };
500
+
501
+ /**
502
+ * Stops the spinner animation and modify the gallery height to exclude the spinner
503
+ */
504
+ JustifiedGallery.prototype.stopLoadingSpinnerAnimation = function () {
505
+ clearInterval(this.spinner.intervalId);
506
+ this.spinner.intervalId = null;
507
+ this.$gallery.height(this.$gallery.height() - this.getSpinnerHeight());
508
+ this.spinner.$el.detach();
509
+ };
510
+
511
+ /**
512
+ * Starts the spinner animation
513
+ */
514
+ JustifiedGallery.prototype.startLoadingSpinnerAnimation = function () {
515
+ var spinnerContext = this.spinner;
516
+ var $spinnerPoints = spinnerContext.$el.find('span');
517
+ clearInterval(spinnerContext.intervalId);
518
+ this.$gallery.append(spinnerContext.$el);
519
+ this.$gallery.height(this.offY + this.buildingRow.height + this.getSpinnerHeight());
520
+ spinnerContext.intervalId = setInterval(function () {
521
+ if (spinnerContext.phase < $spinnerPoints.length) {
522
+ $spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1);
523
+ } else {
524
+ $spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0);
525
+ }
526
+ spinnerContext.phase = (spinnerContext.phase + 1) % ($spinnerPoints.length * 2);
527
+ }, spinnerContext.timeSlot);
528
+ };
529
+
530
+ /**
531
+ * Rewind the image analysis to start from the first entry.
532
+ */
533
+ JustifiedGallery.prototype.rewind = function () {
534
+ this.lastAnalyzedIndex = -1;
535
+ this.offY = this.border;
536
+ this.rows = 0;
537
+ this.clearBuildingRow();
538
+ };
539
+
540
+ /**
541
+ * Update the entries searching it from the justified gallery HTML element
542
+ *
543
+ * @param norewind if norewind only the new entries will be changed (i.e. randomized, sorted or filtered)
544
+ * @returns {boolean} true if some entries has been founded
545
+ */
546
+ JustifiedGallery.prototype.updateEntries = function (norewind) {
547
+ this.entries = this.$gallery.find(this.settings.selector).toArray();
548
+ if (this.entries.length === 0) return false;
549
+
550
+ // Filter
551
+ if (this.settings.filter) {
552
+ this.modifyEntries(this.filterArray, norewind);
553
+ } else {
554
+ this.modifyEntries(this.resetFilters, norewind);
555
+ }
556
+
557
+ // Sort or randomize
558
+ if ($.isFunction(this.settings.sort)) {
559
+ this.modifyEntries(this.sortArray, norewind);
560
+ } else if (this.settings.randomize) {
561
+ this.modifyEntries(this.shuffleArray, norewind);
562
+ }
563
+
564
+ return true;
565
+ };
566
+
567
+ /**
568
+ * Apply the entries order to the DOM, iterating the entries and appending the images
569
+ *
570
+ * @param entries the entries that has been modified and that must be re-ordered in the DOM
571
+ */
572
+ JustifiedGallery.prototype.insertToGallery = function (entries) {
573
+ var that = this;
574
+ $.each(entries, function () {
575
+ $(this).appendTo(that.$gallery);
576
+ });
577
+ };
578
+
579
+ /**
580
+ * Shuffle the array using the Fisher-Yates shuffle algorithm
581
+ *
582
+ * @param a the array to shuffle
583
+ * @return the shuffled array
584
+ */
585
+ JustifiedGallery.prototype.shuffleArray = function (a) {
586
+ var i, j, temp;
587
+ for (i = a.length - 1; i > 0; i--) {
588
+ j = Math.floor(Math.random() * (i + 1));
589
+ temp = a[i];
590
+ a[i] = a[j];
591
+ a[j] = temp;
592
+ }
593
+ this.insertToGallery(a);
594
+ return a;
595
+ };
596
+
597
+ /**
598
+ * Sort the array using settings.comparator as comparator
599
+ *
600
+ * @param a the array to sort (it is sorted)
601
+ * @return the sorted array
602
+ */
603
+ JustifiedGallery.prototype.sortArray = function (a) {
604
+ a.sort(this.settings.sort);
605
+ this.insertToGallery(a);
606
+ return a;
607
+ };
608
+
609
+ /**
610
+ * Reset the filters removing the 'jg-filtered' class from all the entries
611
+ *
612
+ * @param a the array to reset
613
+ */
614
+ JustifiedGallery.prototype.resetFilters = function (a) {
615
+ for (var i = 0; i < a.length; i++) $(a[i]).removeClass('jg-filtered');
616
+ return a;
617
+ };
618
+
619
+ /**
620
+ * Filter the entries considering theirs classes (if a string has been passed) or using a function for filtering.
621
+ *
622
+ * @param a the array to filter
623
+ * @return the filtered array
624
+ */
625
+ JustifiedGallery.prototype.filterArray = function (a) {
626
+ var settings = this.settings;
627
+ if ($.type(settings.filter) === 'string') {
628
+ // Filter only keeping the entries passed in the string
629
+ return a.filter(function (el) {
630
+ var $el = $(el);
631
+ if ($el.is(settings.filter)) {
632
+ $el.removeClass('jg-filtered');
633
+ return true;
634
+ } else {
635
+ $el.addClass('jg-filtered');
636
+ return false;
637
+ }
638
+ });
639
+ } else if ($.isFunction(settings.filter)) {
640
+ // Filter using the passed function
641
+ return a.filter(settings.filter);
642
+ }
643
+ };
644
+
645
+ /**
646
+ * Modify the entries. With norewind only the new inserted images will be modified (the ones after lastAnalyzedIndex)
647
+ *
648
+ * @param functionToApply the function to call to modify the entries (e.g. sorting, randomization, filtering)
649
+ * @param norewind specify if the norewind has been called or not
650
+ */
651
+ JustifiedGallery.prototype.modifyEntries = function (functionToApply, norewind) {
652
+ var lastEntries = norewind ?
653
+ this.entries.splice(this.lastAnalyzedIndex + 1, this.entries.length - this.lastAnalyzedIndex - 1)
654
+ : this.entries;
655
+ lastEntries = functionToApply.call(this, lastEntries);
656
+ this.entries = norewind ? this.entries.concat(lastEntries) : lastEntries;
657
+ };
658
+
659
+ /**
660
+ * Destroy the Justified Gallery instance.
661
+ *
662
+ * It clears all the css properties added in the style attributes. We doesn't backup the original
663
+ * values for those css attributes, because it costs (performance) and because in general one
664
+ * shouldn't use the style attribute for an uniform set of images (where we suppose the use of
665
+ * classes). Creating a backup is also difficult because JG could be called multiple times and
666
+ * with different style attributes.
667
+ */
668
+ JustifiedGallery.prototype.destroy = function () {
669
+ clearInterval(this.checkWidthIntervalId);
670
+
671
+ $.each(this.entries, $.proxy(function(_, entry) {
672
+ var $entry = $(entry);
673
+
674
+ // Reset entry style
675
+ $entry.css('width', '');
676
+ $entry.css('height', '');
677
+ $entry.css('top', '');
678
+ $entry.css('left', '');
679
+ $entry.data('jg.loaded', undefined);
680
+ $entry.removeClass('jg-entry');
681
+
682
+ // Reset image style
683
+ var $img = this.imgFromEntry($entry);
684
+ $img.css('width', '');
685
+ $img.css('height', '');
686
+ $img.css('margin-left', '');
687
+ $img.css('margin-top', '');
688
+ $img.attr('src', $img.data('jg.originalSrc'));
689
+ $img.data('jg.originalSrc', undefined);
690
+
691
+ // Remove caption
692
+ this.removeCaptionEventsHandlers($entry);
693
+ var $caption = this.captionFromEntry($entry);
694
+ if ($entry.data('jg.createdCaption')) {
695
+ // remove also the caption element (if created by jg)
696
+ $entry.data('jg.createdCaption', undefined);
697
+ if ($caption !== null) $caption.remove();
698
+ } else {
699
+ if ($caption !== null) $caption.fadeTo(0, 1);
700
+ }
701
+
702
+ }, this));
703
+
704
+ this.$gallery.css('height', '');
705
+ this.$gallery.removeClass('justified-gallery');
706
+ this.$gallery.data('jg.controller', undefined);
707
+ };
708
+
709
+ /**
710
+ * Analyze the images and builds the rows. It returns if it found an image that is not loaded.
711
+ *
712
+ * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end
713
+ */
714
+ JustifiedGallery.prototype.analyzeImages = function (isForResize) {
715
+ for (var i = this.lastAnalyzedIndex + 1; i < this.entries.length; i++) {
716
+ var $entry = $(this.entries[i]);
717
+ if ($entry.data('jg.loaded') === true || $entry.data('jg.loaded') === 'skipped') {
718
+ var availableWidth = this.galleryWidth - 2 * this.border - (
719
+ (this.buildingRow.entriesBuff.length - 1) * this.settings.margins);
720
+ var imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height');
721
+ if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) {
722
+ this.flushRow(false);
723
+ if(++this.yield.flushed >= this.yield.every) {
724
+ this.startImgAnalyzer(isForResize);
725
+ return;
726
+ }
727
+ }
728
+
729
+ this.buildingRow.entriesBuff.push($entry);
730
+ this.buildingRow.aspectRatio += imgAspectRatio;
731
+ this.buildingRow.width += imgAspectRatio * this.settings.rowHeight;
732
+ this.lastAnalyzedIndex = i;
733
+
734
+ } else if ($entry.data('jg.loaded') !== 'error') {
735
+ return;
736
+ }
737
+ }
738
+
739
+ // Last row flush (the row is not full)
740
+ if (this.buildingRow.entriesBuff.length > 0) this.flushRow(true);
741
+
742
+ if (this.isSpinnerActive()) {
743
+ this.stopLoadingSpinnerAnimation();
744
+ }
745
+
746
+ /* Stop, if there is, the timeout to start the analyzeImages.
747
+ This is because an image can be set loaded, and the timeout can be set,
748
+ but this image can be analyzed yet.
749
+ */
750
+ this.stopImgAnalyzerStarter();
751
+
752
+ //On complete callback
753
+ this.$gallery.trigger(isForResize ? 'jg.resize' : 'jg.complete');
754
+ this.$gallery.height(this.galleryHeightToSet);
755
+ };
756
+
757
+ /**
758
+ * Stops any ImgAnalyzer starter (that has an assigned timeout)
759
+ */
760
+ JustifiedGallery.prototype.stopImgAnalyzerStarter = function () {
761
+ this.yield.flushed = 0;
762
+ if (this.imgAnalyzerTimeout !== null) clearTimeout(this.imgAnalyzerTimeout);
763
+ };
764
+
765
+ /**
766
+ * Starts the image analyzer. It is not immediately called to let the browser to update the view
767
+ *
768
+ * @param isForResize specifies if the image analyzer must be called for resizing or not
769
+ */
770
+ JustifiedGallery.prototype.startImgAnalyzer = function (isForResize) {
771
+ var that = this;
772
+ this.stopImgAnalyzerStarter();
773
+ this.imgAnalyzerTimeout = setTimeout(function () {
774
+ that.analyzeImages(isForResize);
775
+ }, 0.001); // we can't start it immediately due to a IE different behaviour
776
+ };
777
+
778
+ /**
779
+ * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property,
780
+ * because some browsers, with a 404 set complete = true.
781
+ *
782
+ * @param imageSrc the image src to load
783
+ * @param onLoad callback that is called when the image has been loaded
784
+ * @param onError callback that is called in case of an error
785
+ */
786
+ JustifiedGallery.prototype.onImageEvent = function (imageSrc, onLoad, onError) {
787
+ if (!onLoad && !onError) return;
788
+
789
+ var memImage = new Image();
790
+ var $memImage = $(memImage);
791
+ if (onLoad) {
792
+ $memImage.one('load', function () {
793
+ $memImage.off('load error');
794
+ onLoad(memImage);
795
+ });
796
+ }
797
+ if (onError) {
798
+ $memImage.one('error', function() {
799
+ $memImage.off('load error');
800
+ onError(memImage);
801
+ });
802
+ }
803
+ memImage.src = imageSrc;
804
+ };
805
+
806
+ /**
807
+ * Init of Justified Gallery controlled
808
+ * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images)
809
+ */
810
+ JustifiedGallery.prototype.init = function () {
811
+ var imagesToLoad = false, skippedImages = false, that = this;
812
+ $.each(this.entries, function (index, entry) {
813
+ var $entry = $(entry);
814
+ var $image = that.imgFromEntry($entry);
815
+
816
+ $entry.addClass('jg-entry');
817
+
818
+ if ($entry.data('jg.loaded') !== true && $entry.data('jg.loaded') !== 'skipped') {
819
+
820
+ // Link Rel global overwrite
821
+ if (that.settings.rel !== null) $entry.attr('rel', that.settings.rel);
822
+
823
+ // Link Target global overwrite
824
+ if (that.settings.target !== null) $entry.attr('target', that.settings.target);
825
+
826
+ if ($image !== null) {
827
+
828
+ // Image src
829
+ var imageSrc = that.extractImgSrcFromImage($image);
830
+ $image.attr('src', imageSrc);
831
+
832
+ /* If we have the height and the width, we don't wait that the image is loaded, but we start directly
833
+ * with the justification */
834
+ if (that.settings.waitThumbnailsLoad === false) {
835
+ var width = parseFloat($image.attr('width'));
836
+ var height = parseFloat($image.attr('height'));
837
+ if (!isNaN(width) && !isNaN(height)) {
838
+ $entry.data('jg.width', width);
839
+ $entry.data('jg.height', height);
840
+ $entry.data('jg.loaded', 'skipped');
841
+ skippedImages = true;
842
+ that.startImgAnalyzer(false);
843
+ return true; // continue
844
+ }
845
+ }
846
+
847
+ $entry.data('jg.loaded', false);
848
+ imagesToLoad = true;
849
+
850
+ // Spinner start
851
+ if (!that.isSpinnerActive()) that.startLoadingSpinnerAnimation();
852
+
853
+ that.onImageEvent(imageSrc, function (loadImg) { // image loaded
854
+ $entry.data('jg.width', loadImg.width);
855
+ $entry.data('jg.height', loadImg.height);
856
+ $entry.data('jg.loaded', true);
857
+ that.startImgAnalyzer(false);
858
+ }, function () { // image load error
859
+ $entry.data('jg.loaded', 'error');
860
+ that.startImgAnalyzer(false);
861
+ });
862
+
863
+ } else {
864
+ $entry.data('jg.loaded', true);
865
+ $entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1);
866
+ $entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1);
867
+ }
868
+
869
+ }
870
+
871
+ });
872
+
873
+ if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false);
874
+ this.checkWidth();
875
+ };
876
+
877
+ /**
878
+ * Checks that it is a valid number. If a string is passed it is converted to a number
879
+ *
880
+ * @param settingContainer the object that contains the setting (to allow the conversion)
881
+ * @param settingName the setting name
882
+ */
883
+ JustifiedGallery.prototype.checkOrConvertNumber = function (settingContainer, settingName) {
884
+ if ($.type(settingContainer[settingName]) === 'string') {
885
+ settingContainer[settingName] = parseFloat(settingContainer[settingName]);
886
+ }
887
+
888
+ if ($.type(settingContainer[settingName]) === 'number') {
889
+ if (isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName;
890
+ } else {
891
+ throw settingName + ' must be a number';
892
+ }
893
+ };
894
+
895
+ /**
896
+ * Checks the sizeRangeSuffixes and, if necessary, converts
897
+ * its keys from string (e.g. old settings with 'lt100') to int.
898
+ */
899
+ JustifiedGallery.prototype.checkSizeRangesSuffixes = function () {
900
+ if ($.type(this.settings.sizeRangeSuffixes) !== 'object') {
901
+ throw 'sizeRangeSuffixes must be defined and must be an object';
902
+ }
903
+
904
+ var suffixRanges = [];
905
+ for (var rangeIdx in this.settings.sizeRangeSuffixes) {
906
+ if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx);
907
+ }
908
+
909
+ var newSizeRngSuffixes = {0: ''};
910
+ for (var i = 0; i < suffixRanges.length; i++) {
911
+ if ($.type(suffixRanges[i]) === 'string') {
912
+ try {
913
+ var numIdx = parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10);
914
+ newSizeRngSuffixes[numIdx] = this.settings.sizeRangeSuffixes[suffixRanges[i]];
915
+ } catch (e) {
916
+ throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')';
917
+ }
918
+ } else {
919
+ newSizeRngSuffixes[suffixRanges[i]] = this.settings.sizeRangeSuffixes[suffixRanges[i]];
920
+ }
921
+ }
922
+
923
+ this.settings.sizeRangeSuffixes = newSizeRngSuffixes;
924
+ };
925
+
926
+ /**
927
+ * check and convert the maxRowHeight setting
928
+ */
929
+ JustifiedGallery.prototype.retrieveMaxRowHeight = function () {
930
+ var newMaxRowHeight = { };
931
+
932
+ if ($.type(this.settings.maxRowHeight) === 'string') {
933
+ if (this.settings.maxRowHeight.match(/^[0-9]+%$/)) {
934
+ newMaxRowHeight.value = parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100;
935
+ newMaxRowHeight.isPercentage = false;
936
+ } else {
937
+ newMaxRowHeight.value = parseFloat(this.settings.maxRowHeight);
938
+ newMaxRowHeight.isPercentage = true;
939
+ }
940
+ } else if ($.type(this.settings.maxRowHeight) === 'number') {
941
+ newMaxRowHeight.value = this.settings.maxRowHeight;
942
+ newMaxRowHeight.isPercentage = false;
943
+ } else {
944
+ throw 'maxRowHeight must be a number or a percentage';
945
+ }
946
+
947
+ // check if the converted value is not a number
948
+ if (isNaN(newMaxRowHeight.value)) throw 'invalid number for maxRowHeight';
949
+
950
+ // check values
951
+ if (newMaxRowHeight.isPercentage) {
952
+ if (newMaxRowHeight.value < 100) newMaxRowHeight.value = 100;
953
+ } else {
954
+ if (newMaxRowHeight.value > 0 && newMaxRowHeight.value < this.settings.rowHeight) {
955
+ newMaxRowHeight.value = this.settings.rowHeight;
956
+ }
957
+ }
958
+
959
+ return newMaxRowHeight;
960
+
961
+ };
962
+
963
+ /**
964
+ * Checks the settings
965
+ */
966
+ JustifiedGallery.prototype.checkSettings = function () {
967
+ this.checkSizeRangesSuffixes();
968
+
969
+ this.checkOrConvertNumber(this.settings, 'rowHeight');
970
+ this.checkOrConvertNumber(this.settings, 'margins');
971
+ this.checkOrConvertNumber(this.settings, 'border');
972
+
973
+ var lastRowModes = [
974
+ 'justify',
975
+ 'nojustify',
976
+ 'left',
977
+ 'center',
978
+ 'right',
979
+ 'hide'
980
+ ];
981
+ if (lastRowModes.indexOf(this.settings.lastRow) === -1) {
982
+ throw 'lastRow must be one of: ' + lastRowModes.join(', ');
983
+ }
984
+
985
+ this.checkOrConvertNumber(this.settings, 'justifyThreshold');
986
+ if (this.settings.justifyThreshold < 0 || this.settings.justifyThreshold > 1) {
987
+ throw 'justifyThreshold must be in the interval [0,1]';
988
+ }
989
+ if ($.type(this.settings.cssAnimation) !== 'boolean') {
990
+ throw 'cssAnimation must be a boolean';
991
+ }
992
+
993
+ if ($.type(this.settings.captions) !== 'boolean') throw 'captions must be a boolean';
994
+ this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration');
995
+
996
+ this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity');
997
+ if (this.settings.captionSettings.visibleOpacity < 0 ||
998
+ this.settings.captionSettings.visibleOpacity > 1) {
999
+ throw 'captionSettings.visibleOpacity must be in the interval [0, 1]';
1000
+ }
1001
+
1002
+ this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity');
1003
+ if (this.settings.captionSettings.nonVisibleOpacity < 0 ||
1004
+ this.settings.captionSettings.nonVisibleOpacity > 1) {
1005
+ throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]';
1006
+ }
1007
+
1008
+ if ($.type(this.settings.fixedHeight) !== 'boolean') throw 'fixedHeight must be a boolean';
1009
+ this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration');
1010
+ this.checkOrConvertNumber(this.settings, 'refreshTime');
1011
+ this.checkOrConvertNumber(this.settings, 'refreshSensitivity');
1012
+ if ($.type(this.settings.randomize) !== 'boolean') throw 'randomize must be a boolean';
1013
+ if ($.type(this.settings.selector) !== 'string') throw 'selector must be a string';
1014
+
1015
+ if (this.settings.sort !== false && !$.isFunction(this.settings.sort)) {
1016
+ throw 'sort must be false or a comparison function';
1017
+ }
1018
+
1019
+ if (this.settings.filter !== false && !$.isFunction(this.settings.filter) &&
1020
+ $.type(this.settings.filter) !== 'string') {
1021
+ throw 'filter must be false, a string or a filter function';
1022
+ }
1023
+ };
1024
+
1025
+ /**
1026
+ * It brings all the indexes from the sizeRangeSuffixes and it orders them. They are then sorted and returned.
1027
+ * @returns {Array} sorted suffix ranges
1028
+ */
1029
+ JustifiedGallery.prototype.retrieveSuffixRanges = function () {
1030
+ var suffixRanges = [];
1031
+ for (var rangeIdx in this.settings.sizeRangeSuffixes) {
1032
+ if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10));
1033
+ }
1034
+ suffixRanges.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; });
1035
+ return suffixRanges;
1036
+ };
1037
+
1038
+ /**
1039
+ * Update the existing settings only changing some of them
1040
+ *
1041
+ * @param newSettings the new settings (or a subgroup of them)
1042
+ */
1043
+ JustifiedGallery.prototype.updateSettings = function (newSettings) {
1044
+ // In this case Justified Gallery has been called again changing only some options
1045
+ this.settings = $.extend({}, this.settings, newSettings);
1046
+ this.checkSettings();
1047
+
1048
+ // As reported in the settings: negative value = same as margins, 0 = disabled
1049
+ this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins;
1050
+
1051
+ this.maxRowHeight = this.retrieveMaxRowHeight();
1052
+ this.suffixRanges = this.retrieveSuffixRanges();
1053
+ };
1054
+
1055
+ /**
1056
+ * Justified Gallery plugin for jQuery
1057
+ *
1058
+ * Events
1059
+ * - jg.complete : called when all the gallery has been created
1060
+ * - jg.resize : called when the gallery has been resized
1061
+ * - jg.rowflush : when a new row appears
1062
+ *
1063
+ * @param arg the action (or the settings) passed when the plugin is called
1064
+ * @returns {*} the object itself
1065
+ */
1066
+ $.fn.justifiedGallery = function (arg) {
1067
+ return this.each(function (index, gallery) {
1068
+
1069
+ var $gallery = $(gallery);
1070
+ $gallery.addClass('justified-gallery');
1071
+
1072
+ var controller = $gallery.data('jg.controller');
1073
+ if (typeof controller === 'undefined') {
1074
+ // Create controller and assign it to the object data
1075
+ if (typeof arg !== 'undefined' && arg !== null && $.type(arg) !== 'object') {
1076
+ if (arg === 'destroy') return; // Just a call to an unexisting object
1077
+ throw 'The argument must be an object';
1078
+ }
1079
+ controller = new JustifiedGallery($gallery, $.extend({}, $.fn.justifiedGallery.defaults, arg));
1080
+ $gallery.data('jg.controller', controller);
1081
+ } else if (arg === 'norewind') {
1082
+ // In this case we don't rewind: we analyze only the latest images (e.g. to complete the last unfinished row
1083
+ // ... left to be more readable
1084
+ } else if (arg === 'destroy') {
1085
+ controller.destroy();
1086
+ return;
1087
+ } else {
1088
+ // In this case Justified Gallery has been called again changing only some options
1089
+ controller.updateSettings(arg);
1090
+ controller.rewind();
1091
+ }
1092
+
1093
+ // Update the entries list
1094
+ if (!controller.updateEntries(arg === 'norewind')) return;
1095
+
1096
+ // Init justified gallery
1097
+ controller.init();
1098
+
1099
+ });
1100
+ };
1101
+
1102
+ // Default options
1103
+ $.fn.justifiedGallery.defaults = {
1104
+ sizeRangeSuffixes: { }, /* e.g. Flickr configuration
1105
+ {
1106
+ 100: '_t', // used when longest is less than 100px
1107
+ 240: '_m', // used when longest is between 101px and 240px
1108
+ 320: '_n', // ...
1109
+ 500: '',
1110
+ 640: '_z',
1111
+ 1024: '_b' // used as else case because it is the last
1112
+ }
1113
+ */
1114
+ thumbnailPath: undefined, /* If defined, sizeRangeSuffixes is not used, and this function is used to determine the
1115
+ path relative to a specific thumbnail size. The function should accept respectively three arguments:
1116
+ current path, width and height */
1117
+ rowHeight: 120,
1118
+ maxRowHeight: -1, // negative value = no limits, number to express the value in pixels,
1119
+ // '[0-9]+%' to express in percentage (e.g. 300% means that the row height
1120
+ // can't exceed 3 * rowHeight)
1121
+ margins: 1,
1122
+ border: -1, // negative value = same as margins, 0 = disabled, any other value to set the border
1123
+
1124
+ lastRow: 'nojustify', // … which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide'
1125
+
1126
+ justifyThreshold: 0.90, /* if row width / available space > 0.90 it will be always justified
1127
+ * (i.e. lastRow setting is not considered) */
1128
+ fixedHeight: false,
1129
+ waitThumbnailsLoad: true,
1130
+ captions: true,
1131
+ cssAnimation: false,
1132
+ imagesAnimationDuration: 500, // ignored with css animations
1133
+ captionSettings: { // ignored with css animations
1134
+ animationDuration: 500,
1135
+ visibleOpacity: 0.7,
1136
+ nonVisibleOpacity: 0.0
1137
+ },
1138
+ rel: null, // rewrite the rel of each analyzed links
1139
+ target: null, // rewrite the target of all links
1140
+ extension: /\.[^.\\/]+$/, // regexp to capture the extension of an image
1141
+ refreshTime: 200, // time interval (in ms) to check if the page changes its width
1142
+ refreshSensitivity: 0, // change in width allowed (in px) without re-building the gallery
1143
+ randomize: false,
1144
+ sort: false, /*
1145
+ - false: to do not sort
1146
+ - function: to sort them using the function as comparator (see Array.prototype.sort())
1147
+ */
1148
+ filter: false, /*
1149
+ - false: for a disabled filter
1150
+ - a string: an entry is kept if entry.is(filter string) returns true
1151
+ see jQuery's .is() function for further information
1152
+ - a function: invoked with arguments (entry, index, array). Return true to keep the entry, false otherwise.
1153
+ see Array.prototype.filter for further information.
1154
+ */
1155
+ selector: '> a, > div:not(.spinner)' // The selector that is used to know what are the entries of the gallery
1156
+ };
1157
+
1158
+ }(jQuery));
assets/js/min/conditional-fields-min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function($){$("input, select").conditional({data:"envira-conditional",value:"envira-conditional-value",displayOnEnabled:"envira-conditional-display"})}),function($){"use strict";$.fn.conditional=function(t){var a=$.extend({data:"conditional",value:"conditional-value",displayOnEnabled:"conditional-display"},t);return this.each(function(){if("undefined"==typeof $(this).data(a.data))return!0;var t,i,n,e;$(this).on("change",function(){switch(t=$(this).data(a.data).split(","),i=$(this).data(a.displayOnEnabled),"undefined"==typeof i&&(i=!0),n=$(this).data(a.value),"undefined"==typeof n&&(n=""),e=!1,$(this).attr("type")){case"checkbox":e=i?$(this).is(":checked"):$(this).is(":checked")?!1:!0;break;default:e=i?""!==n?String($(this).val())!==String(n)?!1:!0:""===$(this).val()||"0"===$(this).val()?!1:!0:""!==n?$(this).val()!==n?!0:!1:""===$(this).val()||"0"===$(this).val()?!0:!1}for(var d=0;d<t.length;d++)e?$("#"+t[d]).fadeIn(300):$("#"+t[d]).fadeOut(300)}),$(this).trigger("change")}),this}}(jQuery);
1
+ jQuery(document).ready(function($){$("input, select").conditional({data:"envira-conditional",toggle:"envira-conditional-toggle",value:"envira-conditional-value",displayOnEnabled:"envira-conditional-display"})}),function($){"use strict";$.fn.conditional=function(t){var a=$.extend({data:"conditional",value:"conditional-value",toggle:"conditional-toggle",displayOnEnabled:"conditional-display"},t);return this.each(function(){if("undefined"==typeof $(this).data(a.data))return!0;var t,i,n,e,o;$(this).on("change",function(){switch(t=$(this).data(a.data).split(","),i=$(this).data(a.displayOnEnabled),"undefined"==typeof i&&(i=!0),n=$(this).data(a.value),"undefined"==typeof n&&(n=""),e=$(this).data(a.toggle),"undefined"==typeof n&&(e=""),o=!1,$(this).attr("type")){case"checkbox":o=i?$(this).is(":checked"):$(this).is(":checked")?!1:!0;break;default:console.log($(this).attr("type")),console.log(i),console.log("toggle: "+e),o=i?""!==n?String($(this).val())!==String(n)?!1:!0:""===$(this).val()||"0"===$(this).val()?!1:!0:""!==n?$(this).val()!==n?!0:!1:""===$(this).val()||"0"===$(this).val()?!0:!1}for(var d=0;d<t.length;d++)o?($("#"+t[d]).fadeIn(300),e&&$("#"+e).fadeOut(300)):($("#"+t[d]).fadeOut(300),e&&$("#"+e).fadeIn(300))}),$(this).trigger("change")}),this}}(jQuery);
assets/js/min/envira-min.js CHANGED
@@ -1,3 +1,10631 @@
1
- !function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}(this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||[];return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=0,o=i[n];e=e||[];for(var r=this._onceEvents&&this._onceEvents[t];o;){var s=r&&r[o];s&&(this.off(t,o),delete r[o]),o.apply(this,e),n+=s?0:1,o=i[n]}return this}},t}),function(t,e){"use strict";"function"==typeof define&&define.amd?define(["ev-emitter/ev-emitter"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.enviraImagesLoaded=e(t,t.EvEmitter)}(window,function t(e,i){function n(t,e){for(var i in e)t[i]=e[i];return t}function o(t){var e=[];if(Array.isArray(t))e=t;else if("number"==typeof t.length)for(var i=0;i<t.length;i++)e.push(t[i]);else e.push(t);return e}function r(t,e,i){return this instanceof r?("string"==typeof t&&(t=document.querySelectorAll(t)),this.elements=o(t),this.options=n({},this.options),"function"==typeof e?i=e:n(this.options,e),i&&this.on("always",i),this.getImages(),$&&(this.jqDeferred=new $.Deferred),void setTimeout(function(){this.check()}.bind(this))):new r(t,e,i)}function s(t){this.img=t}function a(t,e){this.url=t,this.element=e,this.img=new Image}var $=e.jQuery,u=e.console;r.prototype=Object.create(i.prototype),r.prototype.options={},r.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)},r.prototype.addElementImages=function(t){"IMG"==t.nodeName&&this.addImage(t),this.options.background===!0&&this.addElementBackgroundImages(t);var e=t.nodeType;if(e&&l[e]){for(var i=t.querySelectorAll("img"),n=0;n<i.length;n++){var o=i[n];this.addImage(o)}if("string"==typeof this.options.background){var r=t.querySelectorAll(this.options.background);for(n=0;n<r.length;n++){var s=r[n];this.addElementBackgroundImages(s)}}}};var l={1:!0,9:!0,11:!0};return r.prototype.addElementBackgroundImages=function(t){var e=getComputedStyle(t);if(e)for(var i=/url\((['"])?(.*?)\1\)/gi,n=i.exec(e.backgroundImage);null!==n;){var o=n&&n[2];o&&this.addBackground(o,t),n=i.exec(e.backgroundImage)}},r.prototype.addImage=function(t){var e=new s(t);this.images.push(e)},r.prototype.addBackground=function(t,e){var i=new a(t,e);this.images.push(i)},r.prototype.check=function(){function t(t,i,n){setTimeout(function(){e.progress(t,i,n)})}var e=this;return this.progressedCount=0,this.hasAnyBroken=!1,this.images.length?void this.images.forEach(function(e){e.once("progress",t),e.check()}):void this.complete()},r.prototype.progress=function(t,e,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount==this.images.length&&this.complete(),this.options.debug&&u&&u.log("progress: "+i,t,e)},r.prototype.complete=function(){var t=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){var e=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[e](this)}},s.prototype=Object.create(i.prototype),s.prototype.check=function(){var t=this.getIsImageComplete();return t?void this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),void(this.proxyImage.src=this.img.src))},s.prototype.getIsImageComplete=function(){return this.img.complete&&void 0!==this.img.naturalWidth},s.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.img,e])},s.prototype.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},s.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},s.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},s.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},a.prototype=Object.create(s.prototype),a.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url;var t=this.getIsImageComplete();t&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},a.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},a.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])},r.makeJQueryPlugin=function(t){t=t||e.jQuery,t&&($=t,$.fn.enviraImagesLoaded=function(t,e){var i=new r(this,t,e);return i.jqDeferred.promise($(this))})},r.makeJQueryPlugin(),r}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("jquery-bridget/jquery-bridget",["jquery"],function(i){e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("jquery")):t.jQueryBridget=e(t,t.jQuery)}(window,function e(t,i){"use strict";function n(e,n,$){function s(t,i,n){var o,r="$()."+e+'("'+i+'")';return t.each(function(t,s){var u=$.data(s,e);if(!u)return void a(e+" not initialized. Cannot call methods, i.e. "+r);var l=u[i];if(!l||"_"==i.charAt(0))return void a(r+" is not a valid method");var h=l.apply(u,n);o=void 0===o?h:o}),void 0!==o?o:t}function u(t,i){t.each(function(t,o){var r=$.data(o,e);r?(r.option(i),r._init()):(r=new n(o,i),$.data(o,e,r))})}$=$||i||t.jQuery,$&&(n.prototype.option||(n.prototype.option=function(t){$.isPlainObject(t)&&(this.options=$.extend(!0,this.options,t))}),$.fn[e]=function(t){if("string"==typeof t){var e=r.call(arguments,1);return s(this,t,e)}return u(this,t),this},o($))}function o($){!$||$&&$.bridget||($.bridget=n)}var r=Array.prototype.slice,s=t.console,a="undefined"==typeof s?function(){}:function(t){s.error(t)};return o(i||t.jQuery),n}),function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}(this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=0,o=i[n];e=e||[];for(var r=this._onceEvents&&this._onceEvents[t];o;){var s=r&&r[o];s&&(this.off(t,o),delete r[o]),o.apply(this,e),n+=s?0:1,o=i[n]}return this}},t}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("get-size/get-size",[],function(){return e()}):"object"==typeof module&&module.exports?module.exports=e():t.getSize=e()}(window,function i(){"use strict";function t(t){var e=parseFloat(t),i=-1==t.indexOf("%")&&!isNaN(e);return i&&e}function e(){}function i(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0;u>e;e++){var i=a[e];t[i]=0}return t}function n(t){var e=getComputedStyle(t);return e||s("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? See http://bit.ly/getsizebug1"),e}function o(){if(!l){l=!0;var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style.boxSizing="border-box";var i=document.body||document.documentElement;i.appendChild(e);var o=n(e);r.isBoxSizeOuter=h=200==t(o.width),i.removeChild(e)}}function r(e){if(o(),"string"==typeof e&&(e=document.querySelector(e)),e&&"object"==typeof e&&e.nodeType){var r=n(e);if("none"==r.display)return i();var s={};s.width=e.offsetWidth,s.height=e.offsetHeight;for(var l=s.isBorderBox="border-box"==r.boxSizing,d=0;u>d;d++){var c=a[d],p=r[c],f=parseFloat(p);s[c]=isNaN(f)?0:f}var m=s.paddingLeft+s.paddingRight,g=s.paddingTop+s.paddingBottom,v=s.marginLeft+s.marginRight,y=s.marginTop+s.marginBottom,w=s.borderLeftWidth+s.borderRightWidth,b=s.borderTopWidth+s.borderBottomWidth,x=l&&h,_=t(r.width);_!==!1&&(s.width=_+(x?0:m+w));var I=t(r.height);return I!==!1&&(s.height=I+(x?0:g+b)),s.innerWidth=s.width-(m+w),s.innerHeight=s.height-(g+b),s.outerWidth=s.width+v,s.outerHeight=s.height+y,s}}var s="undefined"==typeof console?e:function(t){console.error(t)},a=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],u=a.length,l=!1,h;return r}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("desandro-matches-selector/matches-selector",e):"object"==typeof module&&module.exports?module.exports=e():t.matchesSelector=e()}(window,function n(){"use strict";var t=function(){var t=Element.prototype;if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0;i<e.length;i++){var n=e[i],o=n+"MatchesSelector";if(t[o])return o}}();return function e(i,n){return i[t](n)}}),function(t,e){"function"==typeof define&&define.amd?define("fizzy-ui-utils/utils",["desandro-matches-selector/matches-selector"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("desandro-matches-selector")):t.fizzyUIUtils=e(t,t.matchesSelector)}(window,function o(t,e){var i={};i.extend=function(t,e){for(var i in e)t[i]=e[i];return t},i.modulo=function(t,e){return(t%e+e)%e},i.makeArray=function(t){var e=[];if(Array.isArray(t))e=t;else if(t&&"number"==typeof t.length)for(var i=0;i<t.length;i++)e.push(t[i]);else e.push(t);return e},i.removeFrom=function(t,e){var i=t.indexOf(e);-1!=i&&t.splice(i,1)},i.getParent=function(t,i){for(;t!=document.body;)if(t=t.parentNode,e(t,i))return t},i.getQueryElement=function(t){return"string"==typeof t?document.querySelector(t):t},i.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},i.filterFindElements=function(t,n){t=i.makeArray(t);var o=[];return t.forEach(function(t){if(t instanceof HTMLElement){if(!n)return void o.push(t);e(t,n)&&o.push(t);for(var i=t.querySelectorAll(n),r=0;r<i.length;r++)o.push(i[r])}}),o},i.debounceMethod=function(t,e,i){var n=t.prototype[e],o=e+"Timeout";t.prototype[e]=function(){var t=this[o];t&&clearTimeout(t);var e=arguments,r=this;this[o]=setTimeout(function(){n.apply(r,e),delete r[o]},i||100)}},i.docReady=function(t){"complete"==document.readyState?t():document.addEventListener("DOMContentLoaded",t)},i.toDashed=function(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()};var n=t.console;return i.htmlInit=function(e,o){i.docReady(function(){var r=i.toDashed(o),s="data-"+r,a=document.querySelectorAll("["+s+"]"),u=document.querySelectorAll(".js-"+r),l=i.makeArray(a).concat(i.makeArray(u)),h=s+"-options",d=t.jQuery;l.forEach(function(t){var i=t.getAttribute(s)||t.getAttribute(h),r;try{r=i&&JSON.parse(i)}catch(a){return void(n&&n.error("Error parsing "+s+" on "+t.className+": "+a))}var u=new e(t,r);d&&d.data(t,o,u)})})},i}),function(t,e){"function"==typeof define&&define.amd?define("outlayer/item",["ev-emitter/ev-emitter","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("ev-emitter"),require("get-size")):(t.Outlayer={},t.Outlayer.Item=e(t.EvEmitter,t.getSize))}(window,function r(t,e){"use strict";function i(t){for(var e in t)return!1;return e=null,!0}function n(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}function o(t){return t.replace(/([A-Z])/g,function(t){return"-"+t.toLowerCase()})}var r=document.documentElement.style,s="string"==typeof r.transition?"transition":"WebkitTransition",a="string"==typeof r.transform?"transform":"WebkitTransform",u={WebkitTransition:"webkitTransitionEnd",transition:"transitionend"}[s],l={transform:a,transition:s,transitionDuration:s+"Duration",transitionProperty:s+"Property",transitionDelay:s+"Delay"},h=n.prototype=Object.create(t.prototype);h.constructor=n,h._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},h.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},h.getSize=function(){this.size=e(this.element)},h.css=function(t){var e=this.element.style;for(var i in t){var n=l[i]||i;e[n]=t[i]}},h.getPosition=function(){var t=getComputedStyle(this.element),e=this.layout._getOption("originLeft"),i=this.layout._getOption("originTop"),n=t[e?"left":"right"],o=t[i?"top":"bottom"],r=this.layout.size,s=-1!=n.indexOf("%")?parseFloat(n)/100*r.width:parseInt(n,10),a=-1!=o.indexOf("%")?parseFloat(o)/100*r.height:parseInt(o,10);s=isNaN(s)?0:s,a=isNaN(a)?0:a,s-=e?r.paddingLeft:r.paddingRight,a-=i?r.paddingTop:r.paddingBottom,this.position.x=s,this.position.y=a},h.layoutPosition=function(){var t=this.layout.size,e={},i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop"),o=i?"paddingLeft":"paddingRight",r=i?"left":"right",s=i?"right":"left",a=this.position.x+t[o];e[r]=this.getXValue(a),e[s]="";var u=n?"paddingTop":"paddingBottom",l=n?"top":"bottom",h=n?"bottom":"top",d=this.position.y+t[u];e[l]=this.getYValue(d),e[h]="",this.css(e),this.emitEvent("layout",[this])},h.getXValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&!e?t/this.layout.size.width*100+"%":t+"px"},h.getYValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&e?t/this.layout.size.height*100+"%":t+"px"},h._transitionTo=function(t,e){this.getPosition();var i=this.position.x,n=this.position.y,o=parseInt(t,10),r=parseInt(e,10),s=o===this.position.x&&r===this.position.y;if(this.setPosition(t,e),s&&!this.isTransitioning)return void this.layoutPosition();var a=t-i,u=e-n,l={};l.transform=this.getTranslate(a,u),this.transition({to:l,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},h.getTranslate=function(t,e){var i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop");return t=i?t:-t,e=n?e:-e,"translate3d("+t+"px, "+e+"px, 0)"},h.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},h.moveTo=h._transitionTo,h.setPosition=function(t,e){this.position.x=parseInt(t,10),this.position.y=parseInt(e,10)},h._nonTransition=function(t){this.css(t.to),t.isCleaning&&this._removeStyles(t.to);for(var e in t.onTransitionEnd)t.onTransitionEnd[e].call(this)},h.transition=function(t){if(!parseFloat(this.layout.options.transitionDuration))return void this._nonTransition(t);var e=this._transn;for(var i in t.onTransitionEnd)e.onEnd[i]=t.onTransitionEnd[i];for(i in t.to)e.ingProperties[i]=!0,t.isCleaning&&(e.clean[i]=!0);if(t.from){this.css(t.from);var n=this.element.offsetHeight;n=null}this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0};var d="opacity,"+o(a);h.enableTransition=function(){if(!this.isTransitioning){var t=this.layout.options.transitionDuration;t="number"==typeof t?t+"ms":t,this.css({transitionProperty:d,transitionDuration:t,transitionDelay:this.staggerDelay||0}),this.element.addEventListener(u,this,!1)}},h.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},h.onotransitionend=function(t){this.ontransitionend(t)};var c={"-webkit-transform":"transform"};h.ontransitionend=function(t){if(t.target===this.element){var e=this._transn,n=c[t.propertyName]||t.propertyName;if(delete e.ingProperties[n],i(e.ingProperties)&&this.disableTransition(),n in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[n]),n in e.onEnd){var o=e.onEnd[n];o.call(this),delete e.onEnd[n]}this.emitEvent("transitionEnd",[this])}},h.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(u,this,!1),this.isTransitioning=!1},h._removeStyles=function(t){var e={};for(var i in t)e[i]="";this.css(e)};var p={transitionProperty:"",transitionDuration:"",transitionDelay:""};return h.removeTransitionStyles=function(){this.css(p)},h.stagger=function(t){t=isNaN(t)?0:t,this.staggerDelay=t+"ms"},h.removeElem=function(){this.element.parentNode.removeChild(this.element),this.css({display:""}),this.emitEvent("remove",[this])},h.remove=function(){return s&&parseFloat(this.layout.options.transitionDuration)?(this.once("transitionEnd",function(){this.removeElem()}),void this.hide()):void this.removeElem()},h.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("visibleStyle");e[i]=this.onRevealTransitionEnd,this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0,onTransitionEnd:e})},h.onRevealTransitionEnd=function(){this.isHidden||this.emitEvent("reveal")},h.getHideRevealTransitionEndProperty=function(t){var e=this.layout.options[t];if(e.opacity)return"opacity";for(var i in e)return i},h.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("hiddenStyle");e[i]=this.onHideTransitionEnd,this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:e})},h.onHideTransitionEnd=function(){this.isHidden&&(this.css({display:"none"}),this.emitEvent("hide"))},h.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},n}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("outlayer/outlayer",["ev-emitter/ev-emitter","get-size/get-size","fizzy-ui-utils/utils","./item"],function(i,n,o,r){return e(t,i,n,o,r)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter"),require("get-size"),require("fizzy-ui-utils"),require("./item")):t.Outlayer=e(t,t.EvEmitter,t.getSize,t.fizzyUIUtils,t.Outlayer.Item)}(window,function s(t,e,i,n,o){"use strict";function r(t,e){var i=n.getQueryElement(t);if(!i)return void(u&&u.error("Bad element for "+this.constructor.namespace+": "+(i||t)));this.element=i,l&&(this.$element=l(this.element)),this.options=n.extend({},this.constructor.defaults),this.option(e);var o=++d;this.element.outlayerGUID=o,c[o]=this,this._create();var r=this._getOption("initLayout");r&&this.layout()}function s(t){function e(){t.apply(this,arguments)}return e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e}function a(t){if("number"==typeof t)return t;var e=t.match(/(^\d*\.?\d*)(\w*)/),i=e&&e[1],n=e&&e[2];if(!i.length)return 0;i=parseFloat(i);var o=f[n]||1;return i*o}var u=t.console,l=t.jQuery,h=function(){},d=0,c={};r.namespace="outlayer",r.Item=o,r.defaults={containerStyle:{position:"relative"},initLayout:!0,originLeft:!0,originTop:!0,resize:!0,resizeContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}};var p=r.prototype;n.extend(p,e.prototype),p.option=function(t){n.extend(this.options,t)},p._getOption=function(t){var e=this.constructor.compatOptions[t];return e&&void 0!==this.options[e]?this.options[e]:this.options[t]},r.compatOptions={initLayout:"isInitLayout",horizontal:"isHorizontal",layoutInstant:"isLayoutInstant",originLeft:"isOriginLeft",originTop:"isOriginTop",resize:"isResizeBound",resizeContainer:"isResizingContainer"},p._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),n.extend(this.element.style,this.options.containerStyle);var t=this._getOption("resize");t&&this.bindResize()},p.reloadItems=function(){this.items=this._itemize(this.element.children)},p._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,n=[],o=0;o<e.length;o++){var r=e[o],s=new i(r,this);n.push(s)}return n},p._filterFindItemElements=function(t){return n.filterFindElements(t,this.options.itemSelector)},p.getItemElements=function(){return this.items.map(function(t){return t.element})},p.layout=function(){this._resetLayout(),this._manageStamps();var t=this._getOption("layoutInstant"),e=void 0!==t?t:!this._isLayoutInited;this.layoutItems(this.items,e),this._isLayoutInited=!0},p._init=p.layout,p._resetLayout=function(){this.getSize()},p.getSize=function(){this.size=i(this.element)},p._getMeasurement=function(t,e){var n=this.options[t],o;n?("string"==typeof n?o=this.element.querySelector(n):n instanceof HTMLElement&&(o=n),this[t]=o?i(o)[e]:n):this[t]=0},p.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},p._getItemsForLayout=function(t){return t.filter(function(t){return!t.isIgnored})},p._layoutItems=function(t,e){if(this._emitCompleteOnItems("layout",t),t&&t.length){var i=[];t.forEach(function(t){var n=this._getItemLayoutPosition(t);n.item=t,n.isInstant=e||t.isLayoutInstant,i.push(n)},this),this._processLayoutQueue(i)}},p._getItemLayoutPosition=function(){return{x:0,y:0}},p._processLayoutQueue=function(t){this.updateStagger(),t.forEach(function(t,e){this._positionItem(t.item,t.x,t.y,t.isInstant,e)},this)},p.updateStagger=function(){var t=this.options.stagger;return null===t||void 0===t?void(this.stagger=0):(this.stagger=a(t),this.stagger)},p._positionItem=function(t,e,i,n,o){n?t.goTo(e,i):(t.stagger(o*this.stagger),t.moveTo(e,i))},p._postLayout=function(){this.resizeContainer()},p.resizeContainer=function(){var t=this._getOption("resizeContainer");if(t){var e=this._getContainerSize();e&&(this._setContainerMeasure(e.width,!0),this._setContainerMeasure(e.height,!1))}},p._getContainerSize=h,p._setContainerMeasure=function(t,e){if(void 0!==t){var i=this.size;i.isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px"}},p._emitCompleteOnItems=function(t,e){function i(){o.dispatchEvent(t+"Complete",null,[e])}function n(){s++,s==r&&i()}var o=this,r=e.length;if(!e||!r)return void i();var s=0;e.forEach(function(e){e.once(t,n)})},p.dispatchEvent=function(t,e,i){var n=e?[e].concat(i):i;if(this.emitEvent(t,n),l)if(this.$element=this.$element||l(this.element),e){var o=l.Event(e);o.type=t,this.$element.trigger(o,i)}else this.$element.trigger(t,i)},p.ignore=function(t){var e=this.getItem(t);e&&(e.isIgnored=!0)},p.unignore=function(t){var e=this.getItem(t);e&&delete e.isIgnored},p.stamp=function(t){t=this._find(t),t&&(this.stamps=this.stamps.concat(t),t.forEach(this.ignore,this))},p.unstamp=function(t){t=this._find(t),t&&t.forEach(function(t){n.removeFrom(this.stamps,t),this.unignore(t)},this)},p._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=n.makeArray(t)):void 0},p._manageStamps=function(){this.stamps&&this.stamps.length&&(this._getBoundingRect(),this.stamps.forEach(this._manageStamp,this))},p._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},p._manageStamp=h,p._getElementOffset=function(t){var e=t.getBoundingClientRect(),n=this._boundingRect,o=i(t),r={left:e.left-n.left-o.marginLeft,top:e.top-n.top-o.marginTop,right:n.right-e.right-o.marginRight,bottom:n.bottom-e.bottom-o.marginBottom};return r},p.handleEvent=n.handleEvent,p.bindResize=function(){t.addEventListener("resize",this),this.isResizeBound=!0},p.unbindResize=function(){t.removeEventListener("resize",this),this.isResizeBound=!1},p.onresize=function(){this.resize()},n.debounceMethod(r,"onresize",100),p.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},p.needsResizeLayout=function(){var t=i(this.element),e=this.size&&t;return e&&t.innerWidth!==this.size.innerWidth},p.addItems=function(t){var e=this._itemize(t);return e.length&&(this.items=this.items.concat(e)),e},p.appended=function(t){var e=this.addItems(t);e.length&&(this.layoutItems(e,!0),this.reveal(e))},p.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(i)}},p.reveal=function(t){if(this._emitCompleteOnItems("reveal",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.reveal()})}},p.hide=function(t){if(this._emitCompleteOnItems("hide",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.hide()})}},p.revealItemElements=function(t){var e=this.getItems(t);this.reveal(e)},p.hideItemElements=function(t){var e=this.getItems(t);this.hide(e)},p.getItem=function(t){for(var e=0;e<this.items.length;e++){var i=this.items[e];if(i.element==t)return i}},p.getItems=function(t){t=n.makeArray(t);var e=[];return t.forEach(function(t){var i=this.getItem(t);i&&e.push(i)},this),e},p.remove=function(t){var e=this.getItems(t);this._emitCompleteOnItems("remove",e),e&&e.length&&e.forEach(function(t){t.remove(),n.removeFrom(this.items,t)},this)},p.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="",this.items.forEach(function(t){t.destroy()}),this.unbindResize();var e=this.element.outlayerGUID;delete c[e],delete this.element.outlayerGUID,l&&l.removeData(this.element,this.constructor.namespace)},r.data=function(t){t=n.getQueryElement(t);var e=t&&t.outlayerGUID;return e&&c[e]},r.create=function(t,e){var i=s(r);return i.defaults=n.extend({},r.defaults),n.extend(i.defaults,e),i.compatOptions=n.extend({},r.compatOptions),i.namespace=t,i.data=r.data,i.Item=s(o),n.htmlInit(i,t),l&&l.bridget&&l.bridget(t,i),i};var f={ms:1,s:1e3};return r.Item=o,r}),function(t,e){"function"==typeof define&&define.amd?define("enviratope/item",["outlayer/outlayer"],e):"object"==typeof module&&module.exports?module.exports=e(require("outlayer")):(t.Enviratope=t.Enviratope||{},t.Enviratope.Item=e(t.Outlayer))}(window,function a(t){"use strict";function e(){t.Item.apply(this,arguments)}var i=e.prototype=Object.create(t.Item.prototype),n=i._create;i._create=function(){this.id=this.layout.itemGUID++,n.call(this),this.sortData={}},i.updateSortData=function(){if(!this.isIgnored){this.sortData.id=this.id,this.sortData["original-order"]=this.id,this.sortData.random=Math.random();var t=this.layout.options.getSortData,e=this.layout._sorters;for(var i in t){var n=e[i];this.sortData[i]=n(this.element,this)}}};var o=i.destroy;return i.destroy=function(){o.apply(this,arguments),this.css({display:""})},e}),function(t,e){"function"==typeof define&&define.amd?define("enviratope/layout-mode",["get-size/get-size","outlayer/outlayer"],e):"object"==typeof module&&module.exports?module.exports=e(require("get-size"),require("outlayer")):(t.Enviratope=t.Enviratope||{},t.Enviratope.LayoutMode=e(t.getSize,t.Outlayer))}(window,function u(t,e){"use strict";function i(t){this.enviratope=t,t&&(this.options=t.options[this.namespace],this.element=t.element,this.items=t.filteredItems,this.size=t.size)}var n=i.prototype,o=["_resetLayout","_getItemLayoutPosition","_manageStamp","_getContainerSize","_getElementOffset","needsResizeLayout","_getOption"];return o.forEach(function(t){n[t]=function(){return e.prototype[t].apply(this.enviratope,arguments)}}),n.needsVerticalResizeLayout=function(){var e=t(this.enviratope.element),i=this.enviratope.size&&e;return i&&e.innerHeight!=this.enviratope.size.innerHeight},n._getMeasurement=function(){this.enviratope._getMeasurement.apply(this,arguments)},n.getColumnWidth=function(){this.getSegmentSize("column","Width")},n.getRowHeight=function(){this.getSegmentSize("row","Height")},n.getSegmentSize=function(t,e){var i=t+e,n="outer"+e;if(this._getMeasurement(i,n),!this[i]){var o=this.getFirstItemSize();this[i]=o&&o[n]||this.enviratope.size["inner"+e]}},n.getFirstItemSize=function(){var e=this.enviratope.filteredItems[0];return e&&e.element&&t(e.element)},n.layout=function(){this.enviratope.layout.apply(this.enviratope,arguments)},n.getSize=function(){this.enviratope.getSize(),this.size=this.enviratope.size},i.modes={},i.create=function(t,e){function o(){i.apply(this,arguments)}return o.prototype=Object.create(n),o.prototype.constructor=o,e&&(o.options=e),o.prototype.namespace=t,i.modes[t]=o,o},i}),function(t,e){"function"==typeof define&&define.amd?define("masonry/masonry",["outlayer/outlayer","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("outlayer"),require("get-size")):t.Masonry=e(t.Outlayer,t.getSize)}(window,function l(t,e){var i=t.create("masonry");return i.compatOptions.fitWidth="isFitWidth",i.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns(),this.colYs=[];for(var t=0;t<this.cols;t++)this.colYs.push(0);this.maxY=0},i.prototype.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var t=this.items[0],i=t&&t.element;this.columnWidth=i&&e(i).outerWidth||this.containerWidth}var n=this.columnWidth+=this.gutter,o=this.containerWidth+this.gutter,r=o/n,s=n-o%n,a=s&&1>s?"round":"floor";r=Math[a](r),this.cols=Math.max(r,1)},i.prototype.getContainerWidth=function(){var t=this._getOption("fitWidth"),i=t?this.element.parentNode:this.element,n=e(i);this.containerWidth=n&&n.innerWidth},i.prototype._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,i=e&&1>e?"round":"ceil",n=Math[i](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var o=this._getColGroup(n),r=Math.min.apply(Math,o),s=o.indexOf(r),a={x:this.columnWidth*s,y:r},u=r+t.size.outerHeight,l=this.cols+1-o.length,h=0;l>h;h++)this.colYs[s+h]=u;return a},i.prototype._getColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;i>n;n++){var o=this.colYs.slice(n,n+t);e[n]=Math.max.apply(Math,o)}return e},i.prototype._manageStamp=function(t){var i=e(t),n=this._getElementOffset(t),o=this._getOption("originLeft"),r=o?n.left:n.right,s=r+i.outerWidth,a=Math.floor(r/this.columnWidth);a=Math.max(0,a);var u=Math.floor(s/this.columnWidth);u-=s%this.columnWidth?0:1,u=Math.min(this.cols-1,u);for(var l=this._getOption("originTop"),h=(l?n.top:n.bottom)+i.outerHeight,d=a;u>=d;d++)this.colYs[d]=Math.max(h,this.colYs[d])},i.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this._getOption("fitWidth")&&(t.width=this._getContainerFitWidth()),t},i.prototype._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},i.prototype.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!=this.containerWidth},i}),function(t,e){"function"==typeof define&&define.amd?define("enviratope/layout-modes/masonry",["../layout-mode","masonry/masonry"],e):"object"==typeof module&&module.exports?module.exports=e(require("../layout-mode"),require("masonry-layout")):e(t.Enviratope.LayoutMode,t.Masonry)}(window,function h(t,e){"use strict";var i=t.create("masonry"),n=i.prototype,o={_getElementOffset:!0,layout:!0,_getMeasurement:!0};for(var r in e.prototype)o[r]||(n[r]=e.prototype[r]);var s=n.measureColumns;n.measureColumns=function(){this.items=this.enviratope.filteredItems,s.call(this)};var a=n._getOption;return n._getOption=function(t){return"fitWidth"==t?void 0!==this.options.isFitWidth?this.options.isFitWidth:this.options.fitWidth:a.apply(this.enviratope,arguments);
2
- },i}),function(t,e){"function"==typeof define&&define.amd?define("enviratope/layout-modes/fit-rows",["../layout-mode"],e):"object"==typeof exports?module.exports=e(require("../layout-mode")):e(t.Enviratope.LayoutMode)}(window,function d(t){"use strict";var e=t.create("fitRows"),i=e.prototype;return i._resetLayout=function(){this.x=0,this.y=0,this.maxY=0,this._getMeasurement("gutter","outerWidth")},i._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth+this.gutter,i=this.enviratope.size.innerWidth+this.gutter;0!==this.x&&e+this.x>i&&(this.x=0,this.y=this.maxY);var n={x:this.x,y:this.y};return this.maxY=Math.max(this.maxY,this.y+t.size.outerHeight),this.x+=e,n},i._getContainerSize=function(){return{height:this.maxY}},e}),function(t,e){"function"==typeof define&&define.amd?define("enviratope/layout-modes/vertical",["../layout-mode"],e):"object"==typeof module&&module.exports?module.exports=e(require("../layout-mode")):e(t.Enviratope.LayoutMode)}(window,function c(t){"use strict";var e=t.create("vertical",{horizontalAlignment:0}),i=e.prototype;return i._resetLayout=function(){this.y=0},i._getItemLayoutPosition=function(t){t.getSize();var e=(this.enviratope.size.innerWidth-t.size.outerWidth)*this.options.horizontalAlignment,i=this.y;return this.y+=t.size.outerHeight,{x:e,y:i}},i._getContainerSize=function(){return{height:this.y}},e}),function(t,e){"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size","desandro-matches-selector/matches-selector","fizzy-ui-utils/utils","./item","./layout-mode","./layout-modes/masonry","./layout-modes/fit-rows","./layout-modes/vertical"],function(i,n,o,r,s,a){return e(t,i,n,o,r,s,a)}):"object"==typeof module&&module.exports?module.exports=e(t,require("outlayer"),require("get-size"),require("desandro-matches-selector"),require("fizzy-ui-utils"),require("./item"),require("./layout-mode"),require("./layout-modes/masonry"),require("./layout-modes/fit-rows"),require("./layout-modes/vertical")):t.Enviratope=e(t,t.Outlayer,t.getSize,t.matchesSelector,t.fizzyUIUtils,t.Enviratope.Item,t.Enviratope.LayoutMode)}(window,function p(t,e,i,n,o,r,s){function a(t,e){return function i(n,o){for(var r=0;r<t.length;r++){var s=t[r],a=n.sortData[s],u=o.sortData[s];if(a>u||u>a){var l=void 0!==e[s]?e[s]:e,h=l?1:-1;return(a>u?1:-1)*h}}return 0}}var u=t.jQuery,l=String.prototype.trim?function(t){return t.trim()}:function(t){return t.replace(/^\s+|\s+$/g,"")},h=e.create("enviratope",{layoutMode:"masonry",isJQueryFiltering:!0,sortAscending:!0});h.Item=r,h.LayoutMode=s;var d=h.prototype;d._create=function(){this.itemGUID=0,this._sorters={},this._getSorters(),e.prototype._create.call(this),this.modes={},this.filteredItems=this.items,this.sortHistory=["original-order"];for(var t in s.modes)this._initLayoutMode(t)},d.reloadItems=function(){this.itemGUID=0,e.prototype.reloadItems.call(this)},d._itemize=function(){for(var t=e.prototype._itemize.apply(this,arguments),i=0;i<t.length;i++){var n=t[i];n.id=this.itemGUID++}return this._updateItemsSortData(t),t},d._initLayoutMode=function(t){var e=s.modes[t],i=this.options[t]||{};this.options[t]=e.options?o.extend(e.options,i):i,this.modes[t]=new e(this)},d.layout=function(){return!this._isLayoutInited&&this._getOption("initLayout")?void this.arrange():void this._layout()},d._layout=function(){var t=this._getIsInstant();this._resetLayout(),this._manageStamps(),this.layoutItems(this.filteredItems,t),this._isLayoutInited=!0},d.arrange=function(t){this.option(t),this._getIsInstant();var e=this._filter(this.items);this.filteredItems=e.matches,this._bindArrangeComplete(),this._isInstant?this._noTransition(this._hideReveal,[e]):this._hideReveal(e),this._sort(),this._layout()},d._init=d.arrange,d._hideReveal=function(t){this.reveal(t.needReveal),this.hide(t.needHide)},d._getIsInstant=function(){var t=this._getOption("layoutInstant"),e=void 0!==t?t:!this._isLayoutInited;return this._isInstant=e,e},d._bindArrangeComplete=function(){function t(){e&&i&&n&&o.dispatchEvent("arrangeComplete",null,[o.filteredItems])}var e,i,n,o=this;this.once("layoutComplete",function(){e=!0,t()}),this.once("hideComplete",function(){i=!0,t()}),this.once("revealComplete",function(){n=!0,t()})},d._filter=function(t){var e=this.options.filter;e=e||"*";for(var i=[],n=[],o=[],r=this._getFilterTest(e),s=0;s<t.length;s++){var a=t[s];if(!a.isIgnored){var u=r(a);u&&i.push(a),u&&a.isHidden?n.push(a):u||a.isHidden||o.push(a)}}return{matches:i,needReveal:n,needHide:o}},d._getFilterTest=function(t){return u&&this.options.isJQueryFiltering?function(e){return u(e.element).is(t)}:"function"==typeof t?function(e){return t(e.element)}:function(e){return n(e.element,t)}},d.updateSortData=function(t){var e;t?(t=o.makeArray(t),e=this.getItems(t)):e=this.items,this._getSorters(),this._updateItemsSortData(e)},d._getSorters=function(){var t=this.options.getSortData;for(var e in t){var i=t[e];this._sorters[e]=c(i)}},d._updateItemsSortData=function(t){for(var e=t&&t.length,i=0;e&&e>i;i++){var n=t[i];n.updateSortData()}};var c=function(){function t(t){if("string"!=typeof t)return t;var i=l(t).split(" "),n=i[0],o=n.match(/^\[(.+)\]$/),r=o&&o[1],s=e(r,n),a=h.sortDataParsers[i[1]];return t=a?function(t){return t&&a(s(t))}:function(t){return t&&s(t)}}function e(t,e){return t?function i(e){return e.getAttribute(t)}:function n(t){var i=t.querySelector(e);return i&&i.textContent}}return t}();h.sortDataParsers={parseInt:function(t){return parseInt(t,10)},parseFloat:function(t){return parseFloat(t)}},d._sort=function(){var t=this.options.sortBy;if(t){var e=[].concat.apply(t,this.sortHistory),i=a(e,this.options.sortAscending);this.filteredItems.sort(i),t!=this.sortHistory[0]&&this.sortHistory.unshift(t)}},d._mode=function(){var t=this.options.layoutMode,e=this.modes[t];if(!e)throw new Error("No layout mode: "+t);return e.options=this.options[t],e},d._resetLayout=function(){e.prototype._resetLayout.call(this),this._mode()._resetLayout()},d._getItemLayoutPosition=function(t){return this._mode()._getItemLayoutPosition(t)},d._manageStamp=function(t){this._mode()._manageStamp(t)},d._getContainerSize=function(){return this._mode()._getContainerSize()},d.needsResizeLayout=function(){return this._mode().needsResizeLayout()},d.appended=function(t){var e=this.addItems(t);if(e.length){var i=this._filterRevealAdded(e);this.filteredItems=this.filteredItems.concat(i)}},d.prepended=function(t){var e=this._itemize(t);if(e.length){this._resetLayout(),this._manageStamps();var i=this._filterRevealAdded(e);this.layoutItems(this.filteredItems),this.filteredItems=i.concat(this.filteredItems),this.items=e.concat(this.items)}},d._filterRevealAdded=function(t){var e=this._filter(t);return this.hide(e.needHide),this.reveal(e.matches),this.layoutItems(e.matches,!0),e.matches},d.insert=function(t){var e=this.addItems(t);if(e.length){var i,n,o=e.length;for(i=0;o>i;i++)n=e[i],this.element.appendChild(n.element);var r=this._filter(e).matches;for(i=0;o>i;i++)e[i].isLayoutInstant=!0;for(this.arrange(),i=0;o>i;i++)delete e[i].isLayoutInstant;this.reveal(r)}};var p=d.remove;return d.remove=function(t){t=o.makeArray(t);var e=this.getItems(t);p.call(this,t);for(var i=e&&e.length,n=0;i&&i>n;n++){var r=e[n];o.removeFrom(this.filteredItems,r)}},d.shuffle=function(){for(var t=0;t<this.items.length;t++){var e=this.items[t];e.sortData.random=Math.random()}this.options.sortBy="random",this._sort(),this._layout()},d._noTransition=function(t,e){var i=this.options.transitionDuration;this.options.transitionDuration=0;var n=t.apply(this,e);return this.options.transitionDuration=i,n},d.getFilteredItemElements=function(){return this.filteredItems.map(function(t){return t.element})},h}),function(t,e,$,i){"use strict";var n=$("html"),o=$(t),r=$(e),s=$.envirabox=function(){s.open.apply(this,arguments)},a=navigator.userAgent.match(/msie/i),u=null,l=e.createTouch!==i,h=function(t){return t&&t.hasOwnProperty&&t instanceof $},d=function(t){return t&&"string"===$.type(t)},c=function(t){return d(t)&&t.indexOf("%")>0},p=function(t){return t&&!(t.style.overflow&&"hidden"===t.style.overflow)&&(t.clientWidth&&t.scrollWidth>t.clientWidth||t.clientHeight&&t.scrollHeight>t.clientHeight)},f=function(t,e){var i=parseInt(t,10)||0;return e&&c(t)&&(i=s.getViewport()[e]/100*i),Math.ceil(i)},m=function(t,e){return f(t,e)+"px"};$.extend(s,{version:"2.1.5",defaults:{padding:15,margin:40,width:800,height:600,minWidth:100,minHeight:100,maxWidth:9999,maxHeight:9999,pixelRatio:1,autoSize:!0,autoHeight:!1,autoWidth:!1,autoResize:!0,autoCenter:!l,fitToView:!0,aspectRatio:!1,topRatio:.5,leftRatio:.5,scrolling:"auto",wrapCSS:"",arrows:!0,closeBtn:!0,closeClick:!1,nextClick:!1,mouseWheel:!0,autoPlay:!1,playSpeed:3e3,preload:3,modal:!1,loop:!0,ajax:{dataType:"html",headers:{"X-envirabox":!0}},iframe:{scrolling:"auto",preload:!0},swf:{wmode:"transparent",allowfullscreen:"true",allowscriptaccess:"always"},keys:{next:{13:"left",34:"up",39:"left",40:"up"},prev:{8:"right",33:"down",37:"right",38:"down"},close:[27],play:[32],toggle:[70]},direction:{next:"left",prev:"right"},scrollOutside:!0,index:0,type:null,href:null,content:null,title:null,tpl:{wrap:'<div class="envirabox-wrap" tabIndex="-1"><div class="envirabox-skin"><div class="envirabox-outer"><div class="envirabox-inner"></div></div></div></div>',image:'<img class="envirabox-image" src="{href}" />',iframe:'<iframe id="envirabox-frame{rnd}" name="envirabox-frame{rnd}" class="envirabox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen'+(a?' allowtransparency="true"':"")+"></iframe>",error:'<p class="envirabox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',closeBtn:'<a title="Close" class="envirabox-item envirabox-close" href="javascript:;"></a>',next:'<a title="Next" class="envirabox-nav envirabox-next" href="javascript:;"><span></span></a>',prev:'<a title="Previous" class="envirabox-nav envirabox-prev" href="javascript:;"><span></span></a>'},openEffect:"fade",openSpeed:250,openEasing:"swing",openOpacity:!0,openMethod:"zoomIn",closeEffect:"fade",closeSpeed:250,closeEasing:"swing",closeOpacity:!0,closeMethod:"zoomOut",nextEffect:"elastic",nextSpeed:250,nextEasing:"swing",nextMethod:"changeIn",prevEffect:"elastic",prevSpeed:250,prevEasing:"swing",prevMethod:"changeOut",helpers:{overlay:!0,title:!0},onCancel:$.noop,beforeLoad:$.noop,afterLoad:$.noop,beforeShow:$.noop,afterShow:$.noop,beforeChange:$.noop,beforeClose:$.noop,afterClose:$.noop},group:{},opts:{},previous:null,coming:null,current:null,isActive:!1,isOpen:!1,isOpened:!1,wrap:null,skin:null,outer:null,inner:null,player:{timer:null,isActive:!1},ajaxLoad:null,imgPreload:null,transitions:{},helpers:{},open:function(t,e){return t&&($.isPlainObject(e)||(e={}),!1!==s.close(!0))?($.isArray(t)||(t=h(t)?$(t).get():[t]),$.each(t,function(n,o){var r={},a,u,l,c,p,f,m;"object"===$.type(o)&&(o.nodeType&&(o=$(o)),h(o)?(r={href:o.data("envirabox-href")||o.attr("href"),title:$("<div/>").text(o.data("envirabox-title")||o.attr("title")).html(),isDom:!0,element:o},$.metadata&&$.extend(!0,r,o.metadata())):r=o),a=e.href||r.href||(d(o)?o:null),u=e.title!==i?e.title:r.title||"",l=e.content||r.content,c=l?"html":e.type||r.type,!c&&r.isDom&&(c=o.data("envirabox-type"),c||(p=o.prop("class").match(/envirabox\.(\w+)/),c=p?p[1]:null)),d(a)&&(c||(s.isImage(a)?c="image":s.isSWF(a)?c="swf":"#"===a.charAt(0)?c="inline":d(o)&&(c="html",l=o)),"ajax"===c&&(f=a.split(/\s+/,2),a=f.shift(),m=f.shift())),l||("inline"===c?a?l=$(d(a)?a.replace(/.*(?=#[^\s]+$)/,""):a):r.isDom&&(l=o):"html"===c?l=a:c||a||!r.isDom||(c="inline",l=o)),$.extend(r,{href:a,type:c,content:l,title:u,selector:m}),t[n]=r}),s.opts=$.extend(!0,{},s.defaults,e),e.keys!==i&&(s.opts.keys=e.keys?$.extend({},s.defaults.keys,e.keys):!1),s.group=t,s._start(s.opts.index)):void 0},cancel:function(){var t=s.coming;t&&!1===s.trigger("onCancel")||(s.hideLoading(),t&&(s.ajaxLoad&&s.ajaxLoad.abort(),s.ajaxLoad=null,s.imgPreload&&(s.imgPreload.onload=s.imgPreload.onerror=null),t.wrap&&t.wrap.stop(!0,!0).trigger("onReset").remove(),s.coming=null,s.current||s._afterZoomOut(t)))},close:function(t){s.cancel(),!1!==s.trigger("beforeClose")&&(s.unbindEvents(),s.isActive&&(s.isOpen&&t!==!0?(s.isOpen=s.isOpened=!1,s.isClosing=!0,$(".envirabox-item, .envirabox-nav").remove(),s.wrap.stop(!0,!0).removeClass("envirabox-opened"),s.transitions[s.current.closeMethod]()):($(".envirabox-wrap").stop(!0).trigger("onReset").remove(),s._afterZoomOut())))},play:function(t){var e=function(){clearTimeout(s.player.timer)},i=function(){e(),s.current&&s.player.isActive&&(s.player.timer=setTimeout(s.next,s.current.playSpeed))},n=function(){e(),r.unbind(".player"),s.player.isActive=!1,s.trigger("onPlayEnd")},o=function(){s.current&&(s.current.loop||s.current.index<s.group.length-1)&&(s.player.isActive=!0,r.bind({"onCancel.player beforeClose.player":n,"onUpdate.player":i,"beforeLoad.player":e}),i(),s.trigger("onPlayStart"))};t===!0||!s.player.isActive&&t!==!1?o():n()},next:function(t){var e=s.current;e&&(d(t)||(t=e.direction.next),s.jumpto(e.index+1,t,"next"))},prev:function(t){var e=s.current;e&&(d(t)||(t=e.direction.prev),s.jumpto(e.index-1,t,"prev"))},jumpto:function(t,e,n){var o=s.current;o&&(t=f(t),s.direction=e||o.direction[t>=o.index?"next":"prev"],s.router=n||"jumpto",o.loop&&(0>t&&(t=o.group.length+t%o.group.length),t%=o.group.length),o.group[t]!==i&&(s.cancel(),s._start(t)))},reposition:function(t,e){var i=s.current,n=i?i.wrap:null,o;n&&(o=s._getPosition(e),t&&"scroll"===t.type?(delete o.position,n.stop(!0,!0).animate(o,200)):(n.css(o),i.pos=$.extend({},i.dim,o)))},update:function(t){var e=t&&t.originalEvent&&t.originalEvent.type,i=!e||"orientationchange"===e;i&&(clearTimeout(u),u=null),s.isOpen&&!u&&(u=setTimeout(function(){var n=s.current;n&&!s.isClosing&&(s.wrap.removeClass("envirabox-tmp"),(i||"load"===e||"resize"===e&&n.autoResize)&&s._setDimension(),"scroll"===e&&n.canShrink||s.reposition(t),s.trigger("onUpdate"),u=null)},i&&!l?0:300))},toggle:function(t){s.isOpen&&(s.current.fitToView="boolean"===$.type(t)?t:!s.current.fitToView,l&&(s.wrap.removeAttr("style").addClass("envirabox-tmp"),s.trigger("onUpdate")),s.update())},hideLoading:function(){r.unbind(".loading"),$("#envirabox-loading").remove()},showLoading:function(){var t,e;s.hideLoading(),t=$('<div id="envirabox-loading"><div></div></div>').click(s.cancel).appendTo("body"),r.bind("keydown.loading",function(t){27===(t.which||t.keyCode)&&(t.preventDefault(),s.cancel())}),s.defaults.fixed||(e=s.getViewport(),t.css({position:"absolute",top:.5*e.h+e.y,left:.5*e.w+e.x})),s.trigger("onLoading")},getViewport:function(){var e=s.current&&s.current.locked||!1,i={x:o.scrollLeft(),y:o.scrollTop()};return e&&e.length?(i.w=e[0].clientWidth,i.h=e[0].clientHeight):(i.w=l&&t.innerWidth?t.innerWidth:o.width(),i.h=l&&t.innerHeight?t.innerHeight:o.height()),i},unbindEvents:function(){s.wrap&&h(s.wrap)&&s.wrap.unbind(".fb"),r.unbind(".fb"),o.unbind(".fb")},bindEvents:function(){var t=s.current,e;t&&(o.bind("orientationchange.fb"+(l?"":" resize.fb")+(t.autoCenter&&!t.locked?" scroll.fb":""),s.update),e=t.keys,e&&r.bind("keydown.fb",function(n){var o=n.which||n.keyCode,r=n.target||n.srcElement;return 27===o&&s.coming?!1:void(n.ctrlKey||n.altKey||n.shiftKey||n.metaKey||r&&(r.type||$(r).is("[contenteditable]"))||$.each(e,function(e,r){return t.group.length>1&&r[o]!==i?(s[e](r[o]),n.preventDefault(),!1):$.inArray(o,r)>-1?(s[e](),n.preventDefault(),!1):void 0}))}),$.fn.mousewheel&&t.mouseWheel&&s.wrap.bind("mousewheel.fb",function(e,i,n,o){for(var r=e.target||null,a=$(r),u=!1;a.length&&!(u||a.is(".envirabox-skin")||a.is(".envirabox-wrap"));)u=p(a[0]),a=$(a).parent();0===i||u||s.group.length>1&&!t.canShrink&&(o>0||n>0?s.prev(o>0?"down":"left"):(0>o||0>n)&&s.next(0>o?"up":"right"),e.preventDefault())}))},trigger:function(t,e){var i,n=e||s.coming||s.current;if(n){if($.isFunction(n[t])&&(i=n[t].apply(n,Array.prototype.slice.call(arguments,1))),i===!1)return!1;n.helpers&&$.each(n.helpers,function(e,i){i&&s.helpers[e]&&$.isFunction(s.helpers[e][t])&&s.helpers[e][t]($.extend(!0,{},s.helpers[e].defaults,i),n)})}r.trigger(t)},isImage:function(t){return d(t)&&t.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i)},isSWF:function(t){return d(t)&&t.match(/\.(swf)((\?|#).*)?$/i)},_start:function(t){var e={},i,n,o,r,a;if(t=f(t),i=s.group[t]||null,!i)return!1;if(e=$.extend(!0,{},s.opts,i),r=e.margin,a=e.padding,"number"===$.type(r)&&(e.margin=[r,r,r,r]),"number"===$.type(a)&&(e.padding=[a,a,a,a]),e.modal&&$.extend(!0,e,{closeBtn:!1,closeClick:!1,nextClick:!1,arrows:!1,mouseWheel:!1,keys:null,helpers:{overlay:{closeClick:!1}}}),e.autoSize&&(e.autoWidth=e.autoHeight=!0),"auto"===e.width&&(e.autoWidth=!0),"auto"===e.height&&(e.autoHeight=!0),e.group=s.group,e.index=t,s.coming=e,!1===s.trigger("beforeLoad"))return void(s.coming=null);if(o=e.type,n=e.href,!o)return s.coming=null,s.current&&s.router&&"jumpto"!==s.router?(s.current.index=t,s[s.router](s.direction)):!1;if(s.isActive=!0,("image"===o||"swf"===o)&&(e.autoHeight=e.autoWidth=!1,e.scrolling="visible"),"image"===o&&(e.aspectRatio=!0),"iframe"===o&&l&&(e.scrolling="scroll"),e.wrap=$(e.tpl.wrap).addClass("envirabox-"+(l?"mobile":"desktop")+" envirabox-type-"+o+" envirabox-tmp "+e.wrapCSS).appendTo(e.parent||"body"),$.extend(e,{skin:$(".envirabox-skin",e.wrap),outer:$(".envirabox-outer",e.wrap),inner:$(".envirabox-inner",e.wrap)}),$.each(["Top","Right","Bottom","Left"],function(t,i){e.skin.css("padding"+i,m(e.padding[t]))}),s.trigger("onReady"),"inline"===o||"html"===o){if(!e.content||!e.content.length)return s._error("content")}else if(!n)return s._error("href");"image"===o?s._loadImage():"ajax"===o?s._loadAjax():"iframe"===o?s._loadIframe():s._afterLoad()},_error:function(t){$.extend(s.coming,{type:"html",autoWidth:!0,autoHeight:!0,minWidth:0,minHeight:0,scrolling:"no",hasError:t,content:s.coming.tpl.error}),s._afterLoad()},_loadImage:function(){var t=s.imgPreload=new Image;t.onload=function(){this.onload=this.onerror=null,s.coming.width=this.width/s.opts.pixelRatio,s.coming.height=this.height/s.opts.pixelRatio,s._afterLoad()},t.onerror=function(){this.onload=this.onerror=null,s._error("image")},t.src=s.coming.href,t.complete!==!0&&s.showLoading()},_loadAjax:function(){var t=s.coming;s.showLoading(),s.ajaxLoad=$.ajax($.extend({},t.ajax,{url:t.href,error:function(t,e){s.coming&&"abort"!==e?s._error("ajax",t):s.hideLoading()},success:function(e,i){"success"===i&&(t.content=e,s._afterLoad())}}))},_loadIframe:function(){var t=s.coming,e=$(t.tpl.iframe.replace(/\{rnd\}/g,(new Date).getTime())).attr("scrolling",l?"auto":t.iframe.scrolling).attr("src",t.href);$(t.wrap).bind("onReset",function(){try{$(this).find("iframe").hide().attr("src","//about:blank").end().empty()}catch(t){}}),t.iframe.preload&&(s.showLoading(),e.one("load",function(){$(this).data("ready",1),l||$(this).bind("load.fb",s.update),$(this).parents(".envirabox-wrap").width("100%").removeClass("envirabox-tmp").show(),s._afterLoad()})),t.content=e.appendTo(t.inner),t.iframe.preload||s._afterLoad()},_preloadImages:function(){var t=s.group,e=s.current,i=t.length,n=e.preload?Math.min(e.preload,i-1):0,o,r;for(r=1;n>=r;r+=1)o=t[(e.index+r)%i],"image"===o.type&&o.href&&((new Image).src=o.href)},_afterLoad:function(){var t=s.coming,e=s.current,i="envirabox-placeholder",n,o,r,a,u,l;if(s.hideLoading(),t&&s.isActive!==!1){if(!1===s.trigger("afterLoad",t,e))return t.wrap.stop(!0).trigger("onReset").remove(),void(s.coming=null);switch(e&&(s.trigger("beforeChange",e),e.wrap.stop(!0).removeClass("envirabox-opened").find(".envirabox-item, .envirabox-nav").remove()),s.unbindEvents(),n=t,o=t.content,r=t.type,a=t.scrolling,$.extend(s,{wrap:n.wrap,skin:n.skin,outer:n.outer,inner:n.inner,current:n,previous:e}),u=n.href,r){case"inline":case"ajax":case"html":n.selector?o=$("<div>").html(o).find(n.selector):h(o)&&(o.data(i)||o.data(i,$('<div class="'+i+'"></div>').insertAfter(o).hide()),o=o.show().detach(),n.wrap.bind("onReset",function(){$(this).find(o).length&&o.hide().replaceAll(o.data(i)).data(i,!1)}));break;case"image":o=n.tpl.image.replace(/\{href\}/g,u);break;case"swf":o='<object id="envirabox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="'+u+'"></param>',l="",$.each(n.swf,function(t,e){o+='<param name="'+t+'" value="'+e+'"></param>',l+=" "+t+'="'+e+'"'}),o+='<embed src="'+u+'" type="application/x-shockwave-flash" width="100%" height="100%"'+l+"></embed></object>"}h(o)&&o.parent().is(n.inner)||n.inner.append(o),s.trigger("beforeShow"),n.inner.css("overflow","yes"===a?"scroll":"no"===a?"hidden":a),s._setDimension(),s.reposition(),s.isOpen=!1,s.coming=null,s.bindEvents(),s.isOpened?e.prevMethod&&s.transitions[e.prevMethod]():$(".envirabox-wrap").not(n.wrap).stop(!0).trigger("onReset").remove(),s.transitions[s.isOpened?n.nextMethod:n.openMethod](),s._preloadImages()}},_setDimension:function(){var t=s.getViewport(),e=0,i=!1,n=!1,o=s.wrap,r=s.skin,a=s.inner,u=s.current,l=u.width,h=u.height,d=u.minWidth,p=u.minHeight,g=u.maxWidth,v=u.maxHeight,y=u.scrolling,w=u.scrollOutside?u.scrollbarWidth:0,b=u.margin,x=f(b[1]+b[3]),_=f(b[0]+b[2]),I,E,S,T,O,L,z,M,C,k,W,P,j,D,R;if(o.add(r).add(a).width("auto").height("auto").removeClass("envirabox-tmp"),I=f(r.outerWidth(!0)-r.width()),E=f(r.outerHeight(!0)-r.height()),S=x+I,T=_+E,O=c(l)?(t.w-S)*f(l)/100:l,L=c(h)?(t.h-T)*f(h)/100:h,"iframe"===u.type){if(D=u.content,u.autoHeight&&1===D.data("ready"))try{D[0].contentWindow.document.location&&(a.width(O).height(9999),R=D.contents().find("body"),w&&R.css("overflow-x","hidden"),L=R.outerHeight(!0))}catch(A){}}else(u.autoWidth||u.autoHeight)&&(a.addClass("envirabox-tmp"),u.autoWidth||a.width(O),u.autoHeight||a.height(L),u.autoWidth&&(O=a.width()),u.autoHeight&&(L=a.height()),a.removeClass("envirabox-tmp"));if(l=f(O),h=f(L),C=O/L,d=f(c(d)?f(d,"w")-S:d),g=f(c(g)?f(g,"w")-S:g),p=f(c(p)?f(p,"h")-T:p),v=f(c(v)?f(v,"h")-T:v),z=g,M=v,u.fitToView&&(g=Math.min(t.w-S,g),v=Math.min(t.h-T,v)),P=t.w-x,j=t.h-_,u.aspectRatio?(l>g&&(l=g,h=f(l/C)),h>v&&(h=v,l=f(h*C)),d>l&&(l=d,h=f(l/C)),p>h&&(h=p,l=f(h*C))):(l=Math.max(d,Math.min(l,g)),u.autoHeight&&"iframe"!==u.type&&(a.width(l),h=a.height()),h=Math.max(p,Math.min(h,v))),u.fitToView)if(a.width(l).height(h),o.width(l+I),k=o.width(),W=o.height(),u.aspectRatio)for(;(k>P||W>j)&&l>d&&h>p&&!(e++>19);)h=Math.max(p,Math.min(v,h-10)),l=f(h*C),d>l&&(l=d,h=f(l/C)),l>g&&(l=g,h=f(l/C)),a.width(l).height(h),o.width(l+I),k=o.width(),W=o.height();else l=Math.max(d,Math.min(l,l-(k-P))),h=Math.max(p,Math.min(h,h-(W-j)));w&&"auto"===y&&L>h&&P>l+I+w&&(l+=w),a.width(l).height(h),o.width(l+I),k=o.width(),W=o.height(),i=(k>P||W>j)&&l>d&&h>p,n=u.aspectRatio?z>l&&M>h&&O>l&&L>h:(z>l||M>h)&&(O>l||L>h),$.extend(u,{dim:{width:m(k),height:m(W)},origWidth:O,origHeight:L,canShrink:i,canExpand:n,wPadding:I,hPadding:E,wrapSpace:W-r.outerHeight(!0),skinSpace:r.height()-h}),!D&&u.autoHeight&&h>p&&v>h&&!n&&a.height("auto")},_getPosition:function(t){var e=s.current,i=s.getViewport(),n=e.margin,o=s.wrap.width()+n[1]+n[3],r=s.wrap.height()+n[0]+n[2],a={position:"absolute",top:n[0],left:n[3]};return e.helpers.title.type&&"float"==e.helpers.title.type&&(r+=$(".envirabox-skin .envirabox-title").height()),e.autoCenter&&e.fixed&&!t&&r<=i.h&&o<=i.w?a.position="fixed":e.locked||(a.top+=i.y,a.left+=i.x),a.top=m(Math.max(a.top,a.top+(i.h-r)*e.topRatio)),a.left=m(Math.max(a.left,a.left+(i.w-o)*e.leftRatio)),a},_afterZoomIn:function(){var t=s.current;t&&(s.isOpen=s.isOpened=!0,s.wrap.css("overflow","visible").addClass("envirabox-opened").hide().show(0),s.update(),(t.closeClick||t.nextClick&&s.group.length>1)&&s.inner.css("cursor","pointer").bind("click.fb",function(e){$(e.target).is("a")||$(e.target).parent().is("a")||(e.preventDefault(),s[t.closeClick?"close":"next"]())}),t.closeBtn&&$(t.tpl.closeBtn).appendTo(s.skin).bind("click.fb",function(t){t.preventDefault(),s.close()}),t.arrows&&s.group.length>1&&((t.loop||t.index>0)&&$(t.tpl.prev).appendTo(s.outer).bind("click.fb",s.prev),(t.loop||t.index<s.group.length-1)&&$(t.tpl.next).appendTo(s.outer).bind("click.fb",s.next)),s.trigger("afterShow"),t.loop||t.index!==t.group.length-1?s.opts.autoPlay&&!s.player.isActive&&(s.opts.autoPlay=!1,s.play(!0)):s.play(!1))},_afterZoomOut:function(t){t=t||s.current,$(".envirabox-wrap").trigger("onReset").remove(),$.extend(s,{group:{},opts:{},router:!1,current:null,isActive:!1,isOpened:!1,isOpen:!1,isClosing:!1,wrap:null,skin:null,outer:null,inner:null}),s.trigger("afterClose",t)}}),s.transitions={getOrigPosition:function(){var t=s.current,e=t.element,i=t.orig,n={},o=50,r=50,a=t.hPadding,u=t.wPadding,l=s.getViewport();return!i&&t.isDom&&e.is(":visible")&&(i=e.find("img:first"),i.length||(i=e)),h(i)?(n=i.offset(),i.is("img")&&(o=i.outerWidth(),r=i.outerHeight())):(n.top=l.y+(l.h-r)*t.topRatio,n.left=l.x+(l.w-o)*t.leftRatio),("fixed"===s.wrap.css("position")||t.locked)&&(n.top-=l.y,n.left-=l.x),n={top:m(n.top-a*t.topRatio),left:m(n.left-u*t.leftRatio),width:m(o+u),height:m(r+a)}},step:function(t,e){var i,n,o,r=e.prop,a=s.current,u=a.wrapSpace,l=a.skinSpace;("width"===r||"height"===r)&&(i=e.end===e.start?1:(t-e.start)/(e.end-e.start),s.isClosing&&(i=1-i),n="width"===r?a.wPadding:a.hPadding,o=t-n,s.skin[r](f("width"===r?o:o-u*i)),s.inner[r](f("width"===r?o:o-u*i-l*i)))},zoomIn:function(){var t=s.current,e=t.pos,i=t.openEffect,n="elastic"===i,o=$.extend({opacity:1},e);delete o.position,n?(e=this.getOrigPosition(),t.openOpacity&&(e.opacity=.1)):"fade"===i&&(e.opacity=.1),s.wrap.css(e).animate(o,{duration:"none"===i?0:t.openSpeed,easing:t.openEasing,step:n?this.step:null,complete:s._afterZoomIn})},zoomOut:function(){var t=s.current,e=t.closeEffect,i="elastic"===e,n={opacity:.1};i&&(n=this.getOrigPosition(),t.closeOpacity&&(n.opacity=.1)),s.wrap.animate(n,{duration:"none"===e?0:t.closeSpeed,easing:t.closeEasing,step:i?this.step:null,complete:s._afterZoomOut})},changeIn:function(){var t=s.current,e=t.nextEffect,i=t.pos,n={opacity:1},o=s.direction,r=200,a;i.opacity=.1,"elastic"===e&&(a="down"===o||"up"===o?"top":"left","down"===o||"right"===o?(i[a]=m(f(i[a])-r),n[a]="+="+r+"px"):(i[a]=m(f(i[a])+r),n[a]="-="+r+"px")),"none"===e?s._afterZoomIn():s.wrap.css(i).animate(n,{duration:t.nextSpeed,easing:t.nextEasing,complete:s._afterZoomIn})},changeOut:function(){var t=s.previous,e=t.prevEffect,i={opacity:.1},n=s.direction,o=200;"elastic"===e&&(i["down"===n||"up"===n?"top":"left"]=("up"===n||"left"===n?"-":"+")+"="+o+"px"),t.wrap.animate(i,{duration:"none"===e?0:t.prevSpeed,easing:t.prevEasing,complete:function(){$(this).trigger("onReset").remove()}})}},s.helpers.overlay={defaults:{closeClick:!0,speedOut:200,showEarly:!0,css:{},locked:!l,fixed:!0},overlay:null,fixed:!1,el:$("html"),create:function(t){var e;t=$.extend({},this.defaults,t),this.overlay&&this.close(),e=s.coming?s.coming.parent:t.parent,this.overlay=$('<div class="envirabox-overlay"></div>').appendTo(e&&e.lenth?e:"body"),this.fixed=!1,t.fixed&&s.defaults.fixed&&(this.overlay.addClass("envirabox-overlay-fixed"),this.fixed=!0)},open:function(t){var e=this;t=$.extend({},this.defaults,t),this.overlay?this.overlay.unbind(".overlay").width("auto").height("auto"):this.create(t),this.fixed||(o.bind("resize.overlay",$.proxy(this.update,this)),this.update()),t.closeClick&&this.overlay.bind("click.overlay",function(t){return $(t.target).hasClass("envirabox-overlay")?(s.isActive?s.close():e.close(),!1):void 0}),this.overlay.css(t.css).show()},close:function(){o.unbind("resize.overlay"),this.el.hasClass("envirabox-lock")&&($(".envirabox-margin").removeClass("envirabox-margin"),this.el.removeClass("envirabox-lock"),o.scrollTop(this.scrollV).scrollLeft(this.scrollH)),$(".envirabox-overlay").remove().hide(),$.extend(this,{overlay:null,fixed:!1})},update:function(){var t="100%",i;this.overlay.width(t).height("100%"),a?(i=Math.max(e.documentElement.offsetWidth,e.body.offsetWidth),r.width()>i&&(t=r.width())):r.width()>o.width()&&(t=r.width()),this.overlay.width(t).height(r.height())},onReady:function(t,e){var i=this.overlay;$(".envirabox-overlay").stop(!0,!0),i||this.create(t),t.locked&&this.fixed&&e.fixed&&(e.locked=this.overlay.append(e.wrap),e.fixed=!1),t.showEarly===!0&&this.beforeShow.apply(this,arguments)},beforeShow:function(t,e){e.locked&&!this.el.hasClass("envirabox-lock")&&(this.fixPosition!==!1&&$("*").filter(function(){return"fixed"===$(this).css("position")&&!$(this).hasClass("envirabox-overlay")&&!$(this).hasClass("envirabox-wrap")}).addClass("envirabox-margin"),this.el.addClass("envirabox-margin"),this.scrollV=o.scrollTop(),this.scrollH=o.scrollLeft(),this.el.addClass("envirabox-lock"),o.scrollTop(this.scrollV).scrollLeft(this.scrollH)),this.open(t)},onUpdate:function(){this.fixed||this.update()},afterClose:function(t){this.overlay&&!s.coming&&this.overlay.fadeOut(t.speedOut,$.proxy(this.close,this))}},s.helpers.title={defaults:{type:"float",position:"bottom"},beforeShow:function(t){var e=s.current,i=e.title,n=t.type,o,r;if($.isFunction(i)&&(i=i.call(e.element,e)),d(i)&&""!==$.trim(i)){switch(o=$('<div class="envirabox-title envirabox-title-'+n+'-wrap">'+i+"</div>"),n){case"inside":r=s.skin;break;case"outside":r=s.wrap;break;case"over":r=s.inner;break;default:r=s.skin,o.appendTo("body"),a&&o.width(o.width()),o.wrapInner('<span class="child"></span>'),s.current.margin[2]+=Math.abs(f(o.css("margin-bottom")))}o["top"===t.position?"prependTo":"appendTo"](r)}}},$.fn.envirabox=function(t){var e,i=$(this),n=this.selector||"",o=function(o){var r=$(this).blur(),a=e,u,l;o.ctrlKey||o.altKey||o.shiftKey||o.metaKey||r.is(".envirabox-wrap")||(u=t.groupAttr||"data-envirabox-group",l=r.attr(u),l||(u="rel",l=r.get(0)[u]),l&&""!==l&&"nofollow"!==l&&(r=n.length?$(n):i,r=r.filter("["+u+'="'+l+'"]'),a=r.index(this)),t.index=a,s.open(r,t)!==!1&&o.preventDefault())};return t=t||{},e=t.index||0,n&&t.live!==!1?r.undelegate(n,"click.fb-start").delegate(n+":not('.envirabox-item, .envirabox-nav')","click.fb-start",o):i.unbind("click.fb-start").bind("click.fb-start",o),this.filter("[data-envirabox-start=1]").trigger("click"),this},r.ready(function(){var e,o;$.scrollbarWidth===i&&($.scrollbarWidth=function(){var t=$('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo("body"),e=t.children(),i=e.innerWidth()-e.height(99).innerWidth();return t.remove(),i}),$.support.fixedPosition===i&&($.support.fixedPosition=function(){var t=$('<div style="position:fixed;top:20px;"></div>').appendTo("body"),e=20===t[0].offsetTop||15===t[0].offsetTop;return t.remove(),e}()),$.extend(s.defaults,{scrollbarWidth:$.scrollbarWidth(),fixed:$.support.fixedPosition,parent:$("body")}),e=$(t).width(),n.addClass("envirabox-lock-test"),o=$(t).width(),n.removeClass("envirabox-lock-test"),$("<style type='text/css'>.envirabox-margin{margin-right:"+(o-e)+"px;}</style>").appendTo("head")})}(window,document,jQuery),function($){var t=$.envirabox;t.helpers.buttons={defaults:{skipSingle:!1,position:"top",inline:!1,tpl:'<div id="envirabox-buttons"><ul><li><a class="btnPrev" title="Previous" href="javascript:;"></a></li><li><a class="btnPlay" title="Start slideshow" href="javascript:;"></a></li><li><a class="btnNext" title="Next" href="javascript:;"></a></li><li><a class="btnToggle" title="Toggle size" href="javascript:;"></a></li><li><a class="btnClose" title="Close" href="javascript:;"></a></li></ul></div>'},list:null,buttons:null,beforeLoad:function(t,e){return t.skipSingle&&e.group.length<2?(e.helpers.buttons=!1,void(e.closeBtn=!0)):(e.margin["bottom"===t.position?2:0]+=30,void 0!=e.helpers.thumbs&&"top"==t.position&&"top"==e.helpers.thumbs.position&&(e.helpers.thumbs.position="top has-other-content"),void(void 0!=e.helpers.thumbs&&"bottom"==t.position&&"bottom"==e.helpers.thumbs.position&&(e.helpers.thumbs.position="bottom has-other-content")))},onPlayStart:function(){this.buttons&&this.buttons.play.attr("title","Pause slideshow").addClass("btnPlayOn");
3
- },onPlayEnd:function(){this.buttons&&this.buttons.play.attr("title","Start slideshow").removeClass("btnPlayOn")},afterShow:function(e,i){var n=this.buttons;n||(this.list=$(e.tpl).addClass(e.position).appendTo("body"),e.inline&&this.list.addClass("inline"),n={prev:this.list.find(".btnPrev").click(t.prev),next:this.list.find(".btnNext").click(t.next),play:this.list.find(".btnPlay").click(t.play),toggle:this.list.find(".btnToggle").click(t.toggle),close:this.list.find(".btnClose").click(t.close)}),i.index>0||i.loop?n.prev.removeClass("btnDisabled"):n.prev.addClass("btnDisabled"),i.loop||i.index<i.group.length-1?(n.next.removeClass("btnDisabled"),n.play.removeClass("btnDisabled")):(n.next.addClass("btnDisabled"),n.play.addClass("btnDisabled")),this.buttons=n,this.onUpdate(e,i)},onUpdate:function(t,e){var i;this.buttons&&(i=this.buttons.toggle.removeClass("btnDisabled btnToggleOn"),e.canShrink?i.addClass("btnToggleOn"):e.canExpand||i.addClass("btnDisabled"))},beforeClose:function(){this.list&&this.list.remove(),this.list=null,this.buttons=null}}}(jQuery),function($){"use strict";var t=$.envirabox,e=function(t,e,i){return i=i||"","object"===$.type(i)&&(i=$.param(i,!0)),$.each(e,function(e,i){t=t.replace("$"+e,i||"")}),i.length&&(t+=(t.indexOf("?")>0?"&":"?")+i),t};t.helpers.media={defaults:{youtube:{matcher:/(youtube\.com|youtu\.be|youtube-nocookie\.com)\/(watch\?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*)).*/i,params:{autoplay:1,autohide:1,fs:1,rel:0,hd:1,wmode:"opaque",enablejsapi:1},type:"iframe",url:"//www.youtube.com/embed/$3"},vimeo:{matcher:/(?:vimeo(?:pro)?.com)\/(?:[^\d]+)?(\d+)(?:.*)/,params:{autoplay:1,hd:1,show_title:1,show_byline:1,show_portrait:0,fullscreen:1},type:"iframe",url:"//player.vimeo.com/video/$1"},metacafe:{matcher:/metacafe.com\/(?:watch|fplayer)\/([\w\-]{1,10})/,params:{autoPlay:"yes"},type:"swf",url:function(t,e,i){return i.swf.flashVars="playerVars="+$.param(e,!0),"//www.metacafe.com/fplayer/"+t[1]+"/.swf"}},dailymotion:{matcher:/dailymotion.com\/video\/(.*)\/?(.*)/,params:{additionalInfos:0,autoStart:1},type:"swf",url:"//www.dailymotion.com/swf/video/$1"},twitvid:{matcher:/twitvid\.com\/([a-zA-Z0-9_\-\?\=]+)/i,params:{autoplay:0},type:"iframe",url:"//www.twitvid.com/embed.php?guid=$1"},twitpic:{matcher:/twitpic\.com\/(?!(?:place|photos|events)\/)([a-zA-Z0-9\?\=\-]+)/i,type:"image",url:"//twitpic.com/show/full/$1/"},instagram:{matcher:/(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i,type:"image",url:"//$1/p/$2/media/?size=l"},google_maps:{matcher:/maps\.google\.([a-z]{2,3}(\.[a-z]{2})?)\/(\?ll=|maps\?)(.*)/i,type:"iframe",url:function(t){return"//maps.google."+t[1]+"/"+t[3]+t[4]+"&output="+(t[4].indexOf("layer=c")>0?"svembed":"embed")}}},beforeLoad:function(t,i){var n=i.href||"",o=!1,r,s,a,u;for(r in t)if(t.hasOwnProperty(r)&&(s=t[r],a=n.match(s.matcher))){o=s.type,u=$.extend(!0,{},s.params,i[r]||($.isPlainObject(t[r])?t[r].params:null)),n="function"===$.type(s.url)?s.url.call(this,a,u,i):e(s.url,a,u);break}o&&(i.href=n,i.type=o,i.autoHeight=!1)}}}(jQuery),function($){var t=$.envirabox;t.helpers.thumbs={defaults:{width:50,height:50,position:"bottom",inline:!1,source:function(t){var e;return t.element&&(e=$(t.element).find("img").attr("src")),!e&&"image"===t.type&&t.href&&(e=t.href),e}},wrap:null,list:null,width:0,init:function(t,e){var i=this,n,o=t.width,r=t.height,s=t.source;n="";for(var a=0;a<e.group.length;a++)n+='<li><a style="width:'+o+"px;height:"+r+'px;" href="javascript:jQuery.envirabox.jumpto('+a+');"></a></li>';this.wrap=$('<div id="envirabox-thumbs"></div>').addClass(t.position).appendTo("body"),this.list=$("<ul>"+n+"</ul>").appendTo(this.wrap),$.each(e.group,function(t){var n=e.group[t],a=s(n);a&&$("<img />").load(function(){var e=this.width,n=this.height,s,a,u;i.list&&e&&n&&(s=e/o,a=n/r,u=i.list.children().eq(t).find("a"),s>=1&&a>=1&&(s>a?(e=Math.floor(e/a),n=r):(e=o,n=Math.floor(n/s))),$(this).css({width:e,height:n,top:Math.floor(r/2-n/2),left:Math.floor(o/2-e/2)}),u.width(o).height(r),$(this).hide().appendTo(u).fadeIn(300))}).attr("src",a).attr("title",n.title)});var u=this.list.children().eq(0),l=$("a",$(u));this.width=parseInt(l.css("border-left-width"))+parseInt(l.css("border-left-width"))+parseInt(u.css("margin-left"))+parseInt(u.css("margin-right"))+parseInt(u.css("width")),this.list.width(this.width*e.group.length).css("left",Math.floor(.5*$(window).width()-(e.index*this.width+.5*this.width)))},beforeLoad:function(t,e){return e.group.length<2?void(e.helpers.thumbs=!1):void(e.margin["top"===t.position?0:2]+=t.height+15)},afterShow:function(t,e){this.list?this.onUpdate(t,e):this.init(t,e),t.inline&&this.wrap.addClass("inline"),this.list.children().removeClass("active").eq(e.index).addClass("active")},onUpdate:function(t,e){this.list&&this.list.stop(!0).animate({left:Math.floor(.5*$(window).width()-(e.index*this.width+.5*this.width))},150)},beforeClose:function(){this.wrap&&this.wrap.remove(),this.wrap=null,this.list=null,this.width=0}}}(jQuery),function($){"use strict";var t=$.envirabox,e=function(t,e,i){return i=i||"","object"===$.type(i)&&(i=$.param(i,!0)),t};t.helpers.video={defaults:{autoplay:0,playpause:0,progress:0,current:0,duration:0,volume:0},beforeLoad:function(t,e){var i=/\.(mp4|flv|ogv|webm|MP4|FLV|OGV|WEBM)$/i.test(e.href);if(i){var n="";switch(e.href.split(".").pop()){case"mp4":n="video/mp4";break;case"ogv":n="video/ogg";break;case"ogg":n="application/ogg";break;case"webm":n="video/webm"}var o=$('a[href="'+e.href+'"]').attr("data-video-width"),r=$('a[href="'+e.href+'"]').attr("data-video-height");e.content='<div class="envira-video-container" style="max-width:'+o+"px;max-height:"+r+'px;"><video class="envira-video" width="'+o+'" height="'+r+'" preload="metadata" style="width:'+o+"px;height:"+o+'px;"><source type="'+n+'" src="'+e.href+'" /></video></div>',e.type="html";var s=[];1===t.playpause&&s.push("playpause"),1===t.progress&&s.push("progress"),1===t.current&&s.push("current"),1===t.duration&&s.push("duration"),1===t.volume&&s.push("volume")}},afterShow:function(t,e){var i=/\.(mp4|flv|ogv|webm|MP4|FLV|OGV|WEBM)$/i.test(e.href);if(i){var n=[];1===t.playpause&&n.push("playpause"),1===t.progress&&n.push("progress"),1===t.current&&n.push("current"),1===t.duration&&n.push("duration"),1===t.volume&&n.push("volume");var o=$(".envira-video").mediaelementplayer({features:n,videoWidth:"100%",videoHeight:"100%",enableAutosize:!0,success:function(e,i){1===t.autoplay&&e.addEventListener("canplay",function(){e.play()},!1)}});setTimeout(function(){$(window).trigger("resize")},500)}}}}(jQuery),jQuery.easing.jswing=jQuery.easing.swing,jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(t,e,i,n,o){return jQuery.easing[jQuery.easing.def](t,e,i,n,o)},easeInQuad:function(t,e,i,n,o){return n*(e/=o)*e+i},easeOutQuad:function(t,e,i,n,o){return-n*(e/=o)*(e-2)+i},easeInOutQuad:function(t,e,i,n,o){return(e/=o/2)<1?n/2*e*e+i:-n/2*(--e*(e-2)-1)+i},easeInCubic:function(t,e,i,n,o){return n*(e/=o)*e*e+i},easeOutCubic:function(t,e,i,n,o){return n*((e=e/o-1)*e*e+1)+i},easeInOutCubic:function(t,e,i,n,o){return(e/=o/2)<1?n/2*e*e*e+i:n/2*((e-=2)*e*e+2)+i},easeInQuart:function(t,e,i,n,o){return n*(e/=o)*e*e*e+i},easeOutQuart:function(t,e,i,n,o){return-n*((e=e/o-1)*e*e*e-1)+i},easeInOutQuart:function(t,e,i,n,o){return(e/=o/2)<1?n/2*e*e*e*e+i:-n/2*((e-=2)*e*e*e-2)+i},easeInQuint:function(t,e,i,n,o){return n*(e/=o)*e*e*e*e+i},easeOutQuint:function(t,e,i,n,o){return n*((e=e/o-1)*e*e*e*e+1)+i},easeInOutQuint:function(t,e,i,n,o){return(e/=o/2)<1?n/2*e*e*e*e*e+i:n/2*((e-=2)*e*e*e*e+2)+i},easeInSine:function(t,e,i,n,o){return-n*Math.cos(e/o*(Math.PI/2))+n+i},easeOutSine:function(t,e,i,n,o){return n*Math.sin(e/o*(Math.PI/2))+i},easeInOutSine:function(t,e,i,n,o){return-n/2*(Math.cos(Math.PI*e/o)-1)+i},easeInExpo:function(t,e,i,n,o){return 0==e?i:n*Math.pow(2,10*(e/o-1))+i},easeOutExpo:function(t,e,i,n,o){return e==o?i+n:n*(-Math.pow(2,-10*e/o)+1)+i},easeInOutExpo:function(t,e,i,n,o){return 0==e?i:e==o?i+n:(e/=o/2)<1?n/2*Math.pow(2,10*(e-1))+i:n/2*(-Math.pow(2,-10*--e)+2)+i},easeInCirc:function(t,e,i,n,o){return-n*(Math.sqrt(1-(e/=o)*e)-1)+i},easeOutCirc:function(t,e,i,n,o){return n*Math.sqrt(1-(e=e/o-1)*e)+i},easeInOutCirc:function(t,e,i,n,o){return(e/=o/2)<1?-n/2*(Math.sqrt(1-e*e)-1)+i:n/2*(Math.sqrt(1-(e-=2)*e)+1)+i},easeInElastic:function(t,e,i,n,o){var r=1.70158,s=0,a=n;if(0==e)return i;if(1==(e/=o))return i+n;if(s||(s=.3*o),a<Math.abs(n)){a=n;var r=s/4}else var r=s/(2*Math.PI)*Math.asin(n/a);return-(a*Math.pow(2,10*(e-=1))*Math.sin((e*o-r)*(2*Math.PI)/s))+i},easeOutElastic:function(t,e,i,n,o){var r=1.70158,s=0,a=n;if(0==e)return i;if(1==(e/=o))return i+n;if(s||(s=.3*o),a<Math.abs(n)){a=n;var r=s/4}else var r=s/(2*Math.PI)*Math.asin(n/a);return a*Math.pow(2,-10*e)*Math.sin((e*o-r)*(2*Math.PI)/s)+n+i},easeInOutElastic:function(t,e,i,n,o){var r=1.70158,s=0,a=n;if(0==e)return i;if(2==(e/=o/2))return i+n;if(s||(s=o*(.3*1.5)),a<Math.abs(n)){a=n;var r=s/4}else var r=s/(2*Math.PI)*Math.asin(n/a);return 1>e?-.5*(a*Math.pow(2,10*(e-=1))*Math.sin((e*o-r)*(2*Math.PI)/s))+i:a*Math.pow(2,-10*(e-=1))*Math.sin((e*o-r)*(2*Math.PI)/s)*.5+n+i},easeInBack:function(t,e,i,n,o,r){return void 0==r&&(r=1.70158),n*(e/=o)*e*((r+1)*e-r)+i},easeOutBack:function(t,e,i,n,o,r){return void 0==r&&(r=1.70158),n*((e=e/o-1)*e*((r+1)*e+r)+1)+i},easeInOutBack:function(t,e,i,n,o,r){return void 0==r&&(r=1.70158),(e/=o/2)<1?n/2*(e*e*(((r*=1.525)+1)*e-r))+i:n/2*((e-=2)*e*(((r*=1.525)+1)*e+r)+2)+i},easeInBounce:function(t,e,i,n,o){return n-jQuery.easing.easeOutBounce(t,o-e,0,n,o)+i},easeOutBounce:function(t,e,i,n,o){return(e/=o)<1/2.75?n*(7.5625*e*e)+i:2/2.75>e?n*(7.5625*(e-=1.5/2.75)*e+.75)+i:2.5/2.75>e?n*(7.5625*(e-=2.25/2.75)*e+.9375)+i:n*(7.5625*(e-=2.625/2.75)*e+.984375)+i},easeInOutBounce:function(t,e,i,n,o){return o/2>e?.5*jQuery.easing.easeInBounce(t,2*e,0,n,o)+i:.5*jQuery.easing.easeOutBounce(t,2*e-o,0,n,o)+.5*n+i}}),function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof exports?module.exports=t:t(jQuery)}(function($){function t(t){var n=t||window.event,o=r.call(arguments,1),u=0,h=0,d=0,c=0,p=0,f=0;if(t=$.event.fix(n),t.type="mousewheel","detail"in n&&(d=-1*n.detail),"wheelDelta"in n&&(d=n.wheelDelta),"wheelDeltaY"in n&&(d=n.wheelDeltaY),"wheelDeltaX"in n&&(h=-1*n.wheelDeltaX),"axis"in n&&n.axis===n.HORIZONTAL_AXIS&&(h=-1*d,d=0),u=0===d?h:d,"deltaY"in n&&(d=-1*n.deltaY,u=d),"deltaX"in n&&(h=n.deltaX,0===d&&(u=-1*h)),0!==d||0!==h){if(1===n.deltaMode){var m=$.data(this,"mousewheel-line-height");u*=m,d*=m,h*=m}else if(2===n.deltaMode){var g=$.data(this,"mousewheel-page-height");u*=g,d*=g,h*=g}if(c=Math.max(Math.abs(d),Math.abs(h)),(!a||a>c)&&(a=c,i(n,c)&&(a/=40)),i(n,c)&&(u/=40,h/=40,d/=40),u=Math[u>=1?"floor":"ceil"](u/a),h=Math[h>=1?"floor":"ceil"](h/a),d=Math[d>=1?"floor":"ceil"](d/a),l.settings.normalizeOffset&&this.getBoundingClientRect){var v=this.getBoundingClientRect();p=t.clientX-v.left,f=t.clientY-v.top}return t.deltaX=h,t.deltaY=d,t.deltaFactor=a,t.offsetX=p,t.offsetY=f,t.deltaMode=0,o.unshift(t,u,h,d),s&&clearTimeout(s),s=setTimeout(e,200),($.event.dispatch||$.event.handle).apply(this,o)}}function e(){a=null}function i(t,e){return l.settings.adjustOldDeltas&&"mousewheel"===t.type&&e%120===0}var n=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],o="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],r=Array.prototype.slice,s,a;if($.event.fixHooks)for(var u=n.length;u;)$.event.fixHooks[n[--u]]=$.event.mouseHooks;var l=$.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var e=o.length;e;)this.addEventListener(o[--e],t,!1);else this.onmousewheel=t;$.data(this,"mousewheel-line-height",l.getLineHeight(this)),$.data(this,"mousewheel-page-height",l.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var e=o.length;e;)this.removeEventListener(o[--e],t,!1);else this.onmousewheel=null;$.removeData(this,"mousewheel-line-height"),$.removeData(this,"mousewheel-page-height")},getLineHeight:function(t){var e=$(t),i=e["offsetParent"in $.fn?"offsetParent":"parent"]();return i.length||(i=$("body")),parseInt(i.css("fontSize"),10)||parseInt(e.css("fontSize"),10)||16},getPageHeight:function(t){return $(t).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};$.fn.extend({mousewheel:function(t){return t?this.bind("mousewheel",t):this.trigger("mousewheel")},unmousewheel:function(t){return this.unbind("mousewheel",t)}})}),jQuery(document).ready(function($){var t="ontouchstart"in document.documentElement;t&&$("body").addClass("envira-touch")}),function(t){"function"==typeof define&&define.amd&&define.amd.jQuery?define(["jquery"],t):t(jQuery)}(function($){"use strict";function t(t){return!t||void 0!==t.allowPageScroll||void 0===t.swipe&&void 0===t.swipeStatus||(t.allowPageScroll=u),void 0!==t.click&&void 0===t.tap&&(t.tap=t.click),t||(t={}),t=$.extend({},$.fn.swipe.defaults,t),this.each(function(){var i=$(this),n=i.data(O);n||(n=new e(this,t),i.data(O,n))})}function e(t,e){function m(t){if(!(lt()||$(t.target).closest(e.excludedElements,Nt).length>0)){var i=t.originalEvent?t.originalEvent:t,n,o=E?i.touches[0]:i;return Ut=b,E?Yt=i.touches.length:t.preventDefault(),jt=0,Dt=null,Qt=null,Rt=0,At=0,Ht=0,qt=1,Bt=0,Vt=ft(),Ft=vt(),at(),!E||Yt===e.fingers||e.fingers===y||Q()?(dt(0,o),$t=Tt(),2==Yt&&(dt(1,i.touches[1]),At=Ht=bt(Vt[0].start,Vt[1].start)),(e.swipeStatus||e.pinchStatus)&&(n=P(i,Ut))):n=!1,n===!1?(Ut=I,P(i,Ut),n):(e.hold&&(te=setTimeout($.proxy(function(){Nt.trigger("hold",[i.target]),e.hold&&(n=e.hold.call(Nt,i,i.target))},this),e.longTapThreshold)),ht(!0),null)}}function L(t){var i=t.originalEvent?t.originalEvent:t;if(Ut!==_&&Ut!==I&&!ut()){var n,o=E?i.touches[0]:i,r=ct(o);if(Xt=Tt(),E&&(Yt=i.touches.length),e.hold&&clearTimeout(te),Ut=x,2==Yt&&(0==At?(dt(1,i.touches[1]),At=Ht=bt(Vt[0].start,Vt[1].start)):(ct(i.touches[1]),Ht=bt(Vt[0].end,Vt[1].end),Qt=_t(Vt[0].end,Vt[1].end)),qt=xt(At,Ht),Bt=Math.abs(At-Ht)),Yt===e.fingers||e.fingers===y||!E||Q()){if(Dt=St(r.start,r.end),q(t,Dt),jt=It(r.start,r.end),Rt=wt(),mt(Dt,jt),(e.swipeStatus||e.pinchStatus)&&(n=P(i,Ut)),!e.triggerOnTouchEnd||e.triggerOnTouchLeave){var s=!0;if(e.triggerOnTouchLeave){var a=Ot(this);s=Lt(r.end,a)}!e.triggerOnTouchEnd&&s?Ut=W(x):e.triggerOnTouchLeave&&!s&&(Ut=W(_)),(Ut==I||Ut==_)&&P(i,Ut)}}else Ut=I,P(i,Ut);n===!1&&(Ut=I,P(i,Ut))}}function z(t){var i=t.originalEvent;return E&&i.touches.length>0?(st(),!0):(ut()&&(Yt=Gt),Xt=Tt(),Rt=wt(),R()||!D()?(Ut=I,P(i,Ut)):e.triggerOnTouchEnd||0==e.triggerOnTouchEnd&&Ut===x?(t.preventDefault(),Ut=_,P(i,Ut)):!e.triggerOnTouchEnd&&Z()?(Ut=_,j(i,Ut,c)):Ut===x&&(Ut=I,P(i,Ut)),ht(!1),null)}function M(){Yt=0,Xt=0,$t=0,At=0,Ht=0,qt=1,at(),ht(!1)}function C(t){var i=t.originalEvent;e.triggerOnTouchLeave&&(Ut=W(_),P(i,Ut))}function k(){Nt.unbind(Mt,m),Nt.unbind(Pt,M),Nt.unbind(Ct,L),Nt.unbind(kt,z),Wt&&Nt.unbind(Wt,C),ht(!1)}function W(t){var i=t,n=H(),o=D(),r=R();return!n||r?i=I:!o||t!=x||e.triggerOnTouchEnd&&!e.triggerOnTouchLeave?!o&&t==_&&e.triggerOnTouchLeave&&(i=I):i=_,i}function P(t,e){var i=void 0;return Y()||U()?i=j(t,e,h):(F()||Q())&&i!==!1&&(i=j(t,e,d)),ot()&&i!==!1?i=j(t,e,p):rt()&&i!==!1?i=j(t,e,f):nt()&&i!==!1&&(i=j(t,e,c)),e===I&&M(t),e===_&&(E?0==t.touches.length&&M(t):M(t)),i}function j(t,u,l){var m=void 0;if(l==h){if(Nt.trigger("swipeStatus",[u,Dt||null,jt||0,Rt||0,Yt,Vt]),e.swipeStatus&&(m=e.swipeStatus.call(Nt,t,u,Dt||null,jt||0,Rt||0,Yt,Vt),m===!1))return!1;if(u==_&&N()){if(Nt.trigger("swipe",[Dt,jt,Rt,Yt,Vt]),e.swipe&&(m=e.swipe.call(Nt,t,Dt,jt,Rt,Yt,Vt),m===!1))return!1;switch(Dt){case i:Nt.trigger("swipeLeft",[Dt,jt,Rt,Yt,Vt]),e.swipeLeft&&(m=e.swipeLeft.call(Nt,t,Dt,jt,Rt,Yt,Vt));break;case n:Nt.trigger("swipeRight",[Dt,jt,Rt,Yt,Vt]),e.swipeRight&&(m=e.swipeRight.call(Nt,t,Dt,jt,Rt,Yt,Vt));break;case o:Nt.trigger("swipeUp",[Dt,jt,Rt,Yt,Vt]),e.swipeUp&&(m=e.swipeUp.call(Nt,t,Dt,jt,Rt,Yt,Vt));break;case r:Nt.trigger("swipeDown",[Dt,jt,Rt,Yt,Vt]),e.swipeDown&&(m=e.swipeDown.call(Nt,t,Dt,jt,Rt,Yt,Vt))}}}if(l==d){if(Nt.trigger("pinchStatus",[u,Qt||null,Bt||0,Rt||0,Yt,qt,Vt]),e.pinchStatus&&(m=e.pinchStatus.call(Nt,t,u,Qt||null,Bt||0,Rt||0,Yt,qt,Vt),m===!1))return!1;if(u==_&&B())switch(Qt){case s:Nt.trigger("pinchIn",[Qt||null,Bt||0,Rt||0,Yt,qt,Vt]),e.pinchIn&&(m=e.pinchIn.call(Nt,t,Qt||null,Bt||0,Rt||0,Yt,qt,Vt));break;case a:Nt.trigger("pinchOut",[Qt||null,Bt||0,Rt||0,Yt,qt,Vt]),e.pinchOut&&(m=e.pinchOut.call(Nt,t,Qt||null,Bt||0,Rt||0,Yt,qt,Vt))}}return l==c?(u===I||u===_)&&(clearTimeout(Jt),clearTimeout(te),G()&&!tt()?(Kt=Tt(),Jt=setTimeout($.proxy(function(){Kt=null,Nt.trigger("tap",[t.target]),e.tap&&(m=e.tap.call(Nt,t,t.target))},this),e.doubleTapThreshold)):(Kt=null,Nt.trigger("tap",[t.target]),e.tap&&(m=e.tap.call(Nt,t,t.target)))):l==p?(u===I||u===_)&&(clearTimeout(Jt),Kt=null,Nt.trigger("doubletap",[t.target]),e.doubleTap&&(m=e.doubleTap.call(Nt,t,t.target))):l==f&&(u===I||u===_)&&(clearTimeout(Jt),Kt=null,Nt.trigger("longtap",[t.target]),e.longTap&&(m=e.longTap.call(Nt,t,t.target))),m}function D(){var t=!0;return null!==e.threshold&&(t=jt>=e.threshold),t}function R(){var t=!1;return null!==e.cancelThreshold&&null!==Dt&&(t=gt(Dt)-jt>=e.cancelThreshold),t}function A(){return null!==e.pinchThreshold?Bt>=e.pinchThreshold:!0}function H(){var t;return t=e.maxTimeThreshold&&Rt>=e.maxTimeThreshold?!1:!0}function q(t,s){if(e.allowPageScroll===u||Q())t.preventDefault();else{var a=e.allowPageScroll===l;switch(s){case i:(e.swipeLeft&&a||!a&&e.allowPageScroll!=g)&&t.preventDefault();break;case n:(e.swipeRight&&a||!a&&e.allowPageScroll!=g)&&t.preventDefault();break;case o:(e.swipeUp&&a||!a&&e.allowPageScroll!=v)&&t.preventDefault();break;case r:(e.swipeDown&&a||!a&&e.allowPageScroll!=v)&&t.preventDefault()}}}function B(){var t=V(),e=X(),i=A();return t&&e&&i}function Q(){return!!(e.pinchStatus||e.pinchIn||e.pinchOut)}function F(){return!(!B()||!Q())}function N(){var t=H(),e=D(),i=V(),n=X(),o=R(),r=!o&&n&&i&&e&&t;return r}function U(){return!!(e.swipe||e.swipeStatus||e.swipeLeft||e.swipeRight||e.swipeUp||e.swipeDown)}function Y(){return!(!N()||!U())}function V(){return Yt===e.fingers||e.fingers===y||!E}function X(){return 0!==Vt[0].end.x}function Z(){return!!e.tap}function G(){return!!e.doubleTap}function K(){return!!e.longTap}function J(){if(null==Kt)return!1;var t=Tt();return G()&&t-Kt<=e.doubleTapThreshold}function tt(){return J()}function et(){return(1===Yt||!E)&&(isNaN(jt)||jt<e.threshold)}function it(){return Rt>e.longTapThreshold&&w>jt}function nt(){return!(!et()||!Z())}function ot(){return!(!J()||!G())}function rt(){return!(!it()||!K())}function st(){Zt=Tt(),Gt=event.touches.length+1}function at(){Zt=0,Gt=0}function ut(){var t=!1;if(Zt){var i=Tt()-Zt;i<=e.fingerReleaseThreshold&&(t=!0)}return t}function lt(){return!(Nt.data(O+"_intouch")!==!0)}function ht(t){t===!0?(Nt.bind(Ct,L),Nt.bind(kt,z),Wt&&Nt.bind(Wt,C)):(Nt.unbind(Ct,L,!1),Nt.unbind(kt,z,!1),Wt&&Nt.unbind(Wt,C,!1)),Nt.data(O+"_intouch",t===!0)}function dt(t,e){var i=void 0!==e.identifier?e.identifier:0;return Vt[t].identifier=i,Vt[t].start.x=Vt[t].end.x=e.pageX||e.clientX,Vt[t].start.y=Vt[t].end.y=e.pageY||e.clientY,Vt[t]}function ct(t){var e=void 0!==t.identifier?t.identifier:0,i=pt(e);return i.end.x=t.pageX||t.clientX,i.end.y=t.pageY||t.clientY,i}function pt(t){for(var e=0;e<Vt.length;e++)if(Vt[e].identifier==t)return Vt[e]}function ft(){for(var t=[],e=0;5>=e;e++)t.push({start:{x:0,y:0},end:{x:0,y:0},identifier:0});return t}function mt(t,e){e=Math.max(e,gt(t)),Ft[t].distance=e}function gt(t){return Ft[t]?Ft[t].distance:void 0}function vt(){var t={};return t[i]=yt(i),t[n]=yt(n),t[o]=yt(o),t[r]=yt(r),t}function yt(t){return{direction:t,distance:0}}function wt(){return Xt-$t}function bt(t,e){var i=Math.abs(t.x-e.x),n=Math.abs(t.y-e.y);return Math.round(Math.sqrt(i*i+n*n))}function xt(t,e){var i=e/t*1;return i.toFixed(2)}function _t(){return 1>qt?a:s}function It(t,e){return Math.round(Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2)))}function Et(t,e){var i=t.x-e.x,n=e.y-t.y,o=Math.atan2(n,i),r=Math.round(180*o/Math.PI);return 0>r&&(r=360-Math.abs(r)),r}function St(t,e){var s=Et(t,e);return 45>=s&&s>=0?i:360>=s&&s>=315?i:s>=135&&225>=s?n:s>45&&135>s?r:o}function Tt(){var t=new Date;return t.getTime()}function Ot(t){t=$(t);var e=t.offset(),i={left:e.left,right:e.left+t.outerWidth(),top:e.top,bottom:e.top+t.outerHeight()};return i}function Lt(t,e){return t.x>e.left&&t.x<e.right&&t.y>e.top&&t.y<e.bottom}var zt=E||T||!e.fallbackToMouseEvents,Mt=zt?T?S?"MSPointerDown":"pointerdown":"touchstart":"mousedown",Ct=zt?T?S?"MSPointerMove":"pointermove":"touchmove":"mousemove",kt=zt?T?S?"MSPointerUp":"pointerup":"touchend":"mouseup",Wt=zt?null:"mouseleave",Pt=T?S?"MSPointerCancel":"pointercancel":"touchcancel",jt=0,Dt=null,Rt=0,At=0,Ht=0,qt=1,Bt=0,Qt=0,Ft=null,Nt=$(t),Ut="start",Yt=0,Vt=null,$t=0,Xt=0,Zt=0,Gt=0,Kt=0,Jt=null,te=null;try{Nt.bind(Mt,m),Nt.bind(Pt,M)}catch(ee){$.error("events not supported "+Mt+","+Pt+" on jQuery.swipe")}this.enable=function(){return Nt.bind(Mt,m),Nt.bind(Pt,M),Nt},this.disable=function(){return k(),Nt},this.destroy=function(){k(),Nt.data(O,null),Nt=null},this.option=function(t,i){if(void 0!==e[t]){if(void 0===i)return e[t];e[t]=i}else $.error("Option "+t+" does not exist on jQuery.swipe.options");return null}}var i="left",n="right",o="up",r="down",s="in",a="out",u="none",l="auto",h="swipe",d="pinch",c="tap",p="doubletap",f="longtap",m="hold",g="horizontal",v="vertical",y="all",w=10,b="start",x="move",_="end",I="cancel",E="ontouchstart"in window,S=window.navigator.msPointerEnabled&&!window.navigator.pointerEnabled,T=window.navigator.pointerEnabled||window.navigator.msPointerEnabled,O="TouchSwipe",L={fingers:1,threshold:75,cancelThreshold:null,pinchThreshold:20,maxTimeThreshold:null,fingerReleaseThreshold:250,longTapThreshold:500,doubleTapThreshold:200,swipe:null,swipeLeft:null,swipeRight:null,swipeUp:null,swipeDown:null,swipeStatus:null,pinchIn:null,pinchOut:null,pinchStatus:null,click:null,tap:null,doubleTap:null,longTap:null,hold:null,triggerOnTouchEnd:!0,triggerOnTouchLeave:!1,allowPageScroll:"auto",fallbackToMouseEvents:!0,excludedElements:"label, button, input, select, textarea, a, .noSwipe"};$.fn.swipe=function(e){var i=$(this),n=i.data(O);if(n&&"string"==typeof e){if(n[e])return n[e].apply(this,Array.prototype.slice.call(arguments,1));$.error("Method "+e+" does not exist on jQuery.swipe")}else if(!(n||"object"!=typeof e&&e))return t.apply(this,arguments);return i},$.fn.swipe.defaults=L,$.fn.swipe.phases={PHASE_START:b,PHASE_MOVE:x,PHASE_END:_,PHASE_CANCEL:I},$.fn.swipe.directions={LEFT:i,RIGHT:n,UP:o,DOWN:r,IN:s,OUT:a},$.fn.swipe.pageScroll={NONE:u,HORIZONTAL:g,VERTICAL:v,AUTO:l},$.fn.swipe.fingers={ONE:1,TWO:2,THREE:3,ALL:y}}),jQuery(document).ready(function($){$("body").on("click",'div.envirabox-title a[href*="#"]:not([href="#"])',function(t){return location.pathname.replace(/^\//,"")==this.pathname.replace(/^\//,"")&&location.hostname==this.hostname?($.envirabox.close(),!1):void 0})});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * envira.js is a placeholder, which CodeKit attaches the following JS files to, before compiling as min/envira-min.js:
3
+ * - lib/jquery.justifiedGallery.js
4
+ * - lib/enviraJustifiedGallery-extension.js
5
+ * - lib/touchswipe.js
6
+ * - lib/mousewheel.js
7
+ * - lib/imagesloaded.js
8
+ * - lib/isotope.js
9
+ * - lib/fancybox.js
10
+ * - lib/fancybox-buttons.js
11
+ * - lib/fancybox-media.js
12
+ * - lib/fancybox-thumbs.js
13
+ *
14
+ * To load more JS resources:
15
+ * - Add them to the lib subfolder
16
+ * - Add the to the imports directive of this file in CodeKit
17
+ */
18
+
19
+ /**
20
+ * If a lightbox caption's link is an anchor, close the lightbox
21
+ */
22
+ jQuery( document ).ready( function( $ ) {
23
+
24
+ $( 'body' ).on( 'click', 'div.envirabox-title a[href*="#"]:not([href="#"])', function( e ) {
25
+
26
+ if ( location.pathname.replace( /^\//, '' ) == this.pathname.replace( /^\//, '' ) && location.hostname == this.hostname ) {
27
+ $.envirabox.close();
28
+ return false;
29
+ }
30
+
31
+ } );
32
+
33
+ } );
34
+
35
+ function jg_effect_desaturate(src) {
36
+ var supportsCanvas = !!document.createElement('canvas').getContext;
37
+ if (supportsCanvas) {
38
+ var canvas = document.createElement('canvas'),
39
+ context = canvas.getContext('2d'),
40
+ imageData, px, length, i = 0, gray,
41
+ img = new Image();
42
+
43
+ img.src = src;
44
+ canvas.width = img.width;
45
+ canvas.height = img.height;
46
+ context.drawImage(img, 0, 0);
47
+
48
+ imageData = context.getImageData(0, 0, canvas.width, canvas.height);
49
+ px = imageData.data;
50
+ length = px.length;
51
+
52
+ for (; i < length; i += 4) {
53
+ gray = px[i] * .3 + px[i + 1] * .59 + px[i + 2] * .11;
54
+ px[i] = px[i + 1] = px[i + 2] = gray;
55
+ }
56
+
57
+ context.putImageData(imageData, 0, 0);
58
+ return canvas.toDataURL();
59
+ } else {
60
+ return src;
61
+ }
62
+ }
63
+
64
+ function jg_effect_threshold(src) {
65
+ var supportsCanvas = !!document.createElement('canvas').getContext;
66
+ if (supportsCanvas) {
67
+ var canvas = document.createElement('canvas'),
68
+ context = canvas.getContext('2d'),
69
+ imageData, px, length, i = 0, gray,
70
+ img = new Image();
71
+
72
+ img.src = src;
73
+ canvas.width = img.width;
74
+ canvas.height = img.height;
75
+ context.drawImage(img, 0, 0);
76
+
77
+ imageData = context.getImageData(0, 0, canvas.width, canvas.height);
78
+ px = imageData.data;
79
+ length = px.length;
80
+
81
+ threshold = 120;
82
+
83
+ for (var i=0; i<length; i+=4) {
84
+ var r = px[i];
85
+ var g = px[i+1];
86
+ var b = px[i+2];
87
+ var v = (0.2126*r + 0.7152*g + 0.0722*b >= threshold) ? 255 : 0;
88
+ px[i] = px[i+1] = px[i+2] = v
89
+ }
90
+
91
+ context.putImageData(imageData, 0, 0);
92
+ return canvas.toDataURL();
93
+ } else {
94
+ return src;
95
+ }
96
+ }
97
+
98
+ function jg_effect_blur(src) {
99
+ var supportsCanvas = !!document.createElement('canvas').getContext;
100
+ if (supportsCanvas) {
101
+ var canvas = document.createElement('canvas'),
102
+ context = canvas.getContext('2d'),
103
+ imageData, px, length, i = 0, gray, top_x = 0, top_y = 0, radius = 30, iterations = 1
104
+ img = new Image();
105
+
106
+ img.src = src;
107
+ canvas.width = img.width;
108
+ canvas.height = img.height;
109
+ context.drawImage(img, 0, 0);
110
+
111
+ var imageData;
112
+ var width = img.width;
113
+ var height = img.height;
114
+
115
+ imageData = context.getImageData( top_x, top_y, width, height );
116
+ var pixels = imageData.data;
117
+
118
+ var rsum,gsum,bsum,asum,x,y,i,p,p1,p2,yp,yi,yw,idx;
119
+ var wm = width - 1;
120
+ var hm = height - 1;
121
+ var wh = width * height;
122
+ var rad1 = radius + 1;
123
+
124
+ var r = [];
125
+ var g = [];
126
+ var b = [];
127
+
128
+ var mul_sum = mul_table[radius];
129
+ var shg_sum = shg_table[radius];
130
+
131
+ var vmin = [];
132
+ var vmax = [];
133
+
134
+ while ( iterations-- > 0 ){
135
+ yw = yi = 0;
136
+
137
+ for ( y=0; y < height; y++ ){
138
+ rsum = pixels[yw] * rad1;
139
+ gsum = pixels[yw+1] * rad1;
140
+ bsum = pixels[yw+2] * rad1;
141
+
142
+ for( i = 1; i <= radius; i++ ){
143
+ p = yw + (((i > wm ? wm : i )) << 2 );
144
+ rsum += pixels[p++];
145
+ gsum += pixels[p++];
146
+ bsum += pixels[p++];
147
+ }
148
+
149
+ for ( x = 0; x < width; x++ ){
150
+ r[yi] = rsum;
151
+ g[yi] = gsum;
152
+ b[yi] = bsum;
153
+
154
+ if( y==0) {
155
+ vmin[x] = ( ( p = x + rad1) < wm ? p : wm ) << 2;
156
+ vmax[x] = ( ( p = x - radius) > 0 ? p << 2 : 0 );
157
+ }
158
+
159
+ p1 = yw + vmin[x];
160
+ p2 = yw + vmax[x];
161
+
162
+ rsum += pixels[p1++] - pixels[p2++];
163
+ gsum += pixels[p1++] - pixels[p2++];
164
+ bsum += pixels[p1++] - pixels[p2++];
165
+
166
+ yi++;
167
+ }
168
+ yw += ( width << 2 );
169
+ }
170
+
171
+ for ( x = 0; x < width; x++ ){
172
+ yp = x;
173
+ rsum = r[yp] * rad1;
174
+ gsum = g[yp] * rad1;
175
+ bsum = b[yp] * rad1;
176
+
177
+ for( i = 1; i <= radius; i++ ){
178
+ yp += ( i > hm ? 0 : width );
179
+ rsum += r[yp];
180
+ gsum += g[yp];
181
+ bsum += b[yp];
182
+ }
183
+
184
+ yi = x << 2;
185
+ for ( y = 0; y < height; y++){
186
+ pixels[yi] = (rsum * mul_sum) >>> shg_sum;
187
+ pixels[yi+1] = (gsum * mul_sum) >>> shg_sum;
188
+ pixels[yi+2] = (bsum * mul_sum) >>> shg_sum;
189
+
190
+ if( x == 0 ) {
191
+ vmin[y] = ( ( p = y + rad1) < hm ? p : hm ) * width;
192
+ vmax[y] = ( ( p = y - radius) > 0 ? p * width : 0 );
193
+ }
194
+
195
+ p1 = x + vmin[y];
196
+ p2 = x + vmax[y];
197
+
198
+ rsum += r[p1] - r[p2];
199
+ gsum += g[p1] - g[p2];
200
+ bsum += b[p1] - b[p2];
201
+
202
+ yi += width << 2;
203
+ }
204
+ }
205
+ }
206
+ context.putImageData( imageData, top_x, top_y );
207
+
208
+ return canvas.toDataURL();
209
+
210
+ } else {
211
+ return src;
212
+ }
213
+ }
214
+
215
+ function jg_effect_vintage( img ) {
216
+ var options = {
217
+ onError: function() {
218
+ alert('ERROR');
219
+ }
220
+ };
221
+ var effect = {
222
+ vignette: 1,
223
+ sepia: true,
224
+ noise: 50,
225
+ desaturate: .2,
226
+ lighten: .1
227
+
228
+ };
229
+ new VintageJS(img, options, effect);
230
+ }
231
+
232
+ /*!
233
+ * Justified Gallery - v3.6.2
234
+ * http://miromannino.github.io/Justified-Gallery/
235
+ * Copyright (c) 2016 Miro Mannino
236
+ * Licensed under the MIT license.
237
+ */
238
+ (function($) {
239
+
240
+ function hasScrollBar() {
241
+ return $("body").height() > $(window).height();
242
+ }
243
+ /**
244
+ * Justified Gallery controller constructor
245
+ *
246
+ * @param $gallery the gallery to build
247
+ * @param settings the settings (the defaults are in $.fn.justifiedGallery.defaults)
248
+ * @constructor
249
+ */
250
+ var JustifiedGallery = function ($gallery, settings) {
251
+
252
+ this.settings = settings;
253
+ this.checkSettings();
254
+
255
+ this.imgAnalyzerTimeout = null;
256
+ this.entries = null;
257
+ this.buildingRow = {
258
+ entriesBuff : [],
259
+ width : 0,
260
+ height : 0,
261
+ aspectRatio : 0
262
+ };
263
+ this.lastAnalyzedIndex = -1;
264
+ this.yield = {
265
+ every : 2, // do a flush every n flushes (must be greater than 1)
266
+ flushed : 0 // flushed rows without a yield
267
+ };
268
+ this.border = settings.border >= 0 ? settings.border : settings.margins;
269
+ this.maxRowHeight = this.retrieveMaxRowHeight();
270
+ this.suffixRanges = this.retrieveSuffixRanges();
271
+ this.offY = this.border;
272
+ this.rows = 0;
273
+ this.spinner = {
274
+ phase : 0,
275
+ timeSlot : 150,
276
+ $el : $('<div class="spinner"><span></span><span></span><span></span></div>'),
277
+ intervalId : null
278
+ };
279
+ this.checkWidthIntervalId = null;
280
+ this.galleryWidth = $gallery.width();
281
+ this.$gallery = $gallery;
282
+
283
+ };
284
+
285
+ /** @returns {String} the best suffix given the width and the height */
286
+ JustifiedGallery.prototype.getSuffix = function (width, height) {
287
+ var longestSide, i;
288
+ longestSide = (width > height) ? width : height;
289
+ for (i = 0; i < this.suffixRanges.length; i++) {
290
+ if (longestSide <= this.suffixRanges[i]) {
291
+ return this.settings.sizeRangeSuffixes[this.suffixRanges[i]];
292
+ }
293
+ }
294
+ return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]];
295
+ };
296
+
297
+ /**
298
+ * Remove the suffix from the string
299
+ *
300
+ * @returns {string} a new string without the suffix
301
+ */
302
+ JustifiedGallery.prototype.removeSuffix = function (str, suffix) {
303
+ return str.substring(0, str.length - suffix.length);
304
+ };
305
+
306
+ /**
307
+ * @returns {boolean} a boolean to say if the suffix is contained in the str or not
308
+ */
309
+ JustifiedGallery.prototype.endsWith = function (str, suffix) {
310
+ return str.indexOf(suffix, str.length - suffix.length) !== -1;
311
+ };
312
+
313
+ /**
314
+ * Get the used suffix of a particular url
315
+ *
316
+ * @param str
317
+ * @returns {String} return the used suffix
318
+ */
319
+ JustifiedGallery.prototype.getUsedSuffix = function (str) {
320
+ for (var si in this.settings.sizeRangeSuffixes) {
321
+ if (this.settings.sizeRangeSuffixes.hasOwnProperty(si)) {
322
+ if (this.settings.sizeRangeSuffixes[si].length === 0) continue;
323
+ if (this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si];
324
+ }
325
+ }
326
+ return '';
327
+ };
328
+
329
+ /**
330
+ * Given an image src, with the width and the height, returns the new image src with the
331
+ * best suffix to show the best quality thumbnail.
332
+ *
333
+ * @returns {String} the suffix to use
334
+ */
335
+ JustifiedGallery.prototype.newSrc = function (imageSrc, imgWidth, imgHeight) {
336
+ var newImageSrc;
337
+
338
+ if (this.settings.thumbnailPath) {
339
+ newImageSrc = this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight);
340
+ } else {
341
+ var matchRes = imageSrc.match(this.settings.extension);
342
+ var ext = (matchRes !== null) ? matchRes[0] : '';
343
+ newImageSrc = imageSrc.replace(this.settings.extension, '');
344
+ newImageSrc = this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc));
345
+ newImageSrc += this.getSuffix(imgWidth, imgHeight) + ext;
346
+ }
347
+
348
+ return newImageSrc;
349
+ };
350
+
351
+ /**
352
+ * Shows the images that is in the given entry
353
+ *
354
+ * @param $entry the entry
355
+ * @param callback the callback that is called when the show animation is finished
356
+ */
357
+ JustifiedGallery.prototype.showImg = function ($entry, callback) {
358
+ if (this.settings.cssAnimation) {
359
+ $entry.addClass('entry-visible');
360
+ if (callback) callback();
361
+ } else {
362
+ $entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback);
363
+ }
364
+ };
365
+
366
+ /**
367
+ * Extract the image src form the image, looking from the 'safe-src', and if it can't be found, from the
368
+ * 'src' attribute. It saves in the image data the 'jg.originalSrc' field, with the extracted src.
369
+ *
370
+ * @param $image the image to analyze
371
+ * @returns {String} the extracted src
372
+ */
373
+ JustifiedGallery.prototype.extractImgSrcFromImage = function ($image) {
374
+ var imageSrc = (typeof $image.data('safe-src') !== 'undefined') ? $image.data('safe-src') : $image.attr('src');
375
+ $image.data('jg.originalSrc', imageSrc);
376
+ return imageSrc;
377
+ };
378
+
379
+ /** @returns {jQuery} the image in the given entry */
380
+ JustifiedGallery.prototype.imgFromEntry = function ($entry) {
381
+ var $img = $entry.find('> img');
382
+ if ($img.length === 0) $img = $entry.find('> a > img');
383
+ return $img.length === 0 ? null : $img;
384
+ };
385
+
386
+ /** @returns {jQuery} the caption in the given entry */
387
+ JustifiedGallery.prototype.captionFromEntry = function ($entry) {
388
+ var $caption = $entry.find('> .caption');
389
+ return $caption.length === 0 ? null : $caption;
390
+ };
391
+
392
+ /**
393
+ * Display the entry
394
+ *
395
+ * @param {jQuery} $entry the entry to display
396
+ * @param {int} x the x position where the entry must be positioned
397
+ * @param y the y position where the entry must be positioned
398
+ * @param imgWidth the image width
399
+ * @param imgHeight the image height
400
+ * @param rowHeight the row height of the row that owns the entry
401
+ */
402
+ JustifiedGallery.prototype.displayEntry = function ($entry, x, y, imgWidth, imgHeight, rowHeight) {
403
+ $entry.width(imgWidth);
404
+ $entry.height(rowHeight);
405
+ $entry.css('top', y);
406
+ $entry.css('left', x);
407
+
408
+ var $image = this.imgFromEntry($entry);
409
+ if ($image !== null) {
410
+ $image.css('width', imgWidth);
411
+ $image.css('height', imgHeight);
412
+ $image.css('margin-left', - imgWidth / 2);
413
+ $image.css('margin-top', - imgHeight / 2);
414
+
415
+ // Image reloading for an high quality of thumbnails
416
+ var imageSrc = $image.attr('src');
417
+ var newImageSrc = this.newSrc(imageSrc, imgWidth, imgHeight);
418
+
419
+ $image.one('error', function () {
420
+ $image.attr('src', $image.data('jg.originalSrc')); //revert to the original thumbnail, we got it.
421
+ });
422
+
423
+ var loadNewImage = function () {
424
+ if (imageSrc !== newImageSrc) { //load the new image after the fadeIn
425
+ $image.attr('src', newImageSrc);
426
+ }
427
+ };
428
+
429
+ if ($entry.data('jg.loaded') === 'skipped') {
430
+ this.onImageEvent(imageSrc, $.proxy(function() {
431
+ this.showImg($entry, loadNewImage);
432
+ $entry.data('jg.loaded', true);
433
+ }, this));
434
+ } else {
435
+ this.showImg($entry, loadNewImage);
436
+ }
437
+
438
+ } else {
439
+ this.showImg($entry);
440
+ }
441
+
442
+ this.displayEntryCaption($entry);
443
+ };
444
+
445
+ /**
446
+ * Display the entry caption. If the caption element doesn't exists, it creates the caption using the 'alt'
447
+ * or the 'title' attributes.
448
+ *
449
+ * @param {jQuery} $entry the entry to process
450
+ */
451
+ JustifiedGallery.prototype.displayEntryCaption = function ($entry) {
452
+ var $image = this.imgFromEntry($entry);
453
+ if ($image !== null && this.settings.captions) {
454
+ var $imgCaption = this.captionFromEntry($entry);
455
+
456
+ // Create it if it doesn't exists
457
+ if ($imgCaption === null) {
458
+ var caption = $image.attr('alt');
459
+ if (!this.isValidCaption(caption)) caption = $entry.attr('title');
460
+ if (this.isValidCaption(caption)) { // Create only we found something
461
+ $imgCaption = $('<div class="caption">' + caption + '</div>');
462
+ $entry.append($imgCaption);
463
+ $entry.data('jg.createdCaption', true);
464
+ }
465
+ }
466
+
467
+ // Create events (we check again the $imgCaption because it can be still inexistent)
468
+ if ($imgCaption !== null) {
469
+ if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity);
470
+ this.addCaptionEventsHandlers($entry);
471
+ }
472
+ } else {
473
+ this.removeCaptionEventsHandlers($entry);
474
+ }
475
+ };
476
+
477
+ /**
478
+ * Validates the caption
479
+ *
480
+ * @param caption The caption that should be validated
481
+ * @return {boolean} Validation result
482
+ */
483
+ JustifiedGallery.prototype.isValidCaption = function (caption) {
484
+ return (typeof caption !== 'undefined' && caption.length > 0);
485
+ };
486
+
487
+ /**
488
+ * The callback for the event 'mouseenter'. It assumes that the event currentTarget is an entry.
489
+ * It shows the caption using jQuery (or using CSS if it is configured so)
490
+ *
491
+ * @param {Event} eventObject the event object
492
+ */
493
+ JustifiedGallery.prototype.onEntryMouseEnterForCaption = function (eventObject) {
494
+ var $caption = this.captionFromEntry($(eventObject.currentTarget));
495
+ if (this.settings.cssAnimation) {
496
+ $caption.addClass('caption-visible').removeClass('caption-hidden');
497
+ } else {
498
+ $caption.stop().fadeTo(this.settings.captionSettings.animationDuration,
499
+ this.settings.captionSettings.visibleOpacity);
500
+ }
501
+ };
502
+
503
+ /**
504
+ * The callback for the event 'mouseleave'. It assumes that the event currentTarget is an entry.
505
+ * It hides the caption using jQuery (or using CSS if it is configured so)
506
+ *
507
+ * @param {Event} eventObject the event object
508
+ */
509
+ JustifiedGallery.prototype.onEntryMouseLeaveForCaption = function (eventObject) {
510
+ var $caption = this.captionFromEntry($(eventObject.currentTarget));
511
+ if (this.settings.cssAnimation) {
512
+ $caption.removeClass('caption-visible').removeClass('caption-hidden');
513
+ } else {
514
+ $caption.stop().fadeTo(this.settings.captionSettings.animationDuration,
515
+ this.settings.captionSettings.nonVisibleOpacity);
516
+ }
517
+ };
518
+
519
+ /**
520
+ * Add the handlers of the entry for the caption
521
+ *
522
+ * @param $entry the entry to modify
523
+ */
524
+ JustifiedGallery.prototype.addCaptionEventsHandlers = function ($entry) {
525
+ var captionMouseEvents = $entry.data('jg.captionMouseEvents');
526
+ if (typeof captionMouseEvents === 'undefined') {
527
+ captionMouseEvents = {
528
+ mouseenter: $.proxy(this.onEntryMouseEnterForCaption, this),
529
+ mouseleave: $.proxy(this.onEntryMouseLeaveForCaption, this)
530
+ };
531
+ $entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter);
532
+ $entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave);
533
+ $entry.data('jg.captionMouseEvents', captionMouseEvents);
534
+ }
535
+ };
536
+
537
+ /**
538
+ * Remove the handlers of the entry for the caption
539
+ *
540
+ * @param $entry the entry to modify
541
+ */
542
+ JustifiedGallery.prototype.removeCaptionEventsHandlers = function ($entry) {
543
+ var captionMouseEvents = $entry.data('jg.captionMouseEvents');
544
+ if (typeof captionMouseEvents !== 'undefined') {
545
+ $entry.off('mouseenter', undefined, captionMouseEvents.mouseenter);
546
+ $entry.off('mouseleave', undefined, captionMouseEvents.mouseleave);
547
+ $entry.removeData('jg.captionMouseEvents');
548
+ }
549
+ };
550
+
551
+ /**
552
+ * Justify the building row, preparing it to
553
+ *
554
+ * @param isLastRow
555
+ * @returns a boolean to know if the row has been justified or not
556
+ */
557
+ JustifiedGallery.prototype.prepareBuildingRow = function (isLastRow) {
558
+ var i, $entry, imgAspectRatio, newImgW, newImgH, justify = true;
559
+ var minHeight = 0;
560
+ var availableWidth = this.galleryWidth - 2 * this.border - (
561
+ (this.buildingRow.entriesBuff.length - 1) * this.settings.margins);
562
+ var rowHeight = availableWidth / this.buildingRow.aspectRatio;
563
+ var defaultRowHeight = this.settings.rowHeight;
564
+ var justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold;
565
+
566
+ //Skip the last row if we can't justify it and the lastRow == 'hide'
567
+ if (isLastRow && this.settings.lastRow === 'hide' && !justifiable) {
568
+ for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
569
+ $entry = this.buildingRow.entriesBuff[i];
570
+ if (this.settings.cssAnimation)
571
+ $entry.removeClass('entry-visible');
572
+ else
573
+ $entry.stop().fadeTo(0, 0);
574
+ }
575
+ return -1;
576
+ }
577
+
578
+ // With lastRow = nojustify, justify if is justificable (the images will not become too big)
579
+ if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') {
580
+ justify = false;
581
+
582
+ if (this.rows > 0) {
583
+ defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows;
584
+ if (defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold) {
585
+ justify = true;
586
+ } else {
587
+ justify = false;
588
+ }
589
+ }
590
+ }
591
+
592
+ for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
593
+ $entry = this.buildingRow.entriesBuff[i];
594
+ imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height');
595
+
596
+ if (justify) {
597
+ newImgW = (i === this.buildingRow.entriesBuff.length - 1) ? availableWidth : rowHeight * imgAspectRatio;
598
+ newImgH = rowHeight;
599
+
600
+ /* With fixedHeight the newImgH must be greater than rowHeight.
601
+ In some cases here this is not satisfied (due to the justification).
602
+ But we comment it, because is better to have a shorter but justified row instead
603
+ to have a cropped image at the end. */
604
+ /*if (this.settings.fixedHeight && newImgH < this.settings.rowHeight) {
605
+ newImgW = this.settings.rowHeight * imgAspectRatio;
606
+ newImgH = this.settings.rowHeight;
607
+ }*/
608
+
609
+ } else {
610
+ newImgW = defaultRowHeight * imgAspectRatio;
611
+ newImgH = defaultRowHeight;
612
+ }
613
+
614
+ availableWidth -= Math.round(newImgW);
615
+ $entry.data('jg.jwidth', Math.round(newImgW));
616
+ $entry.data('jg.jheight', Math.ceil(newImgH));
617
+ if (i === 0 || minHeight > newImgH) minHeight = newImgH;
618
+ }
619
+
620
+ if (this.settings.fixedHeight && minHeight > this.settings.rowHeight)
621
+ minHeight = this.settings.rowHeight;
622
+
623
+ this.buildingRow.height = minHeight;
624
+ return justify;
625
+ };
626
+
627
+ /**
628
+ * Clear the building row data to be used for a new row
629
+ */
630
+ JustifiedGallery.prototype.clearBuildingRow = function () {
631
+ this.buildingRow.entriesBuff = [];
632
+ this.buildingRow.aspectRatio = 0;
633
+ this.buildingRow.width = 0;
634
+ };
635
+
636
+ /**
637
+ * Flush a row: justify it, modify the gallery height accordingly to the row height
638
+ *
639
+ * @param isLastRow
640
+ */
641
+ JustifiedGallery.prototype.flushRow = function (isLastRow) {
642
+ var settings = this.settings;
643
+ var $entry, buildingRowRes, offX = this.border, i;
644
+
645
+ buildingRowRes = this.prepareBuildingRow(isLastRow);
646
+ if (isLastRow && settings.lastRow === 'hide' && buildingRowRes === -1) {
647
+ this.clearBuildingRow();
648
+ return;
649
+ }
650
+
651
+ if (this.maxRowHeight.isPercentage) {
652
+ if (this.maxRowHeight.value * settings.rowHeight < this.buildingRow.height) {
653
+ this.buildingRow.height = this.maxRowHeight.value * settings.rowHeight;
654
+ }
655
+ } else {
656
+ if (this.maxRowHeight.value > 0 && this.maxRowHeight.value < this.buildingRow.height) {
657
+ this.buildingRow.height = this.maxRowHeight.value;
658
+ }
659
+ }
660
+
661
+ //Align last (unjustified) row
662
+ if (settings.lastRow === 'center' || settings.lastRow === 'right') {
663
+ var availableWidth = this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins;
664
+
665
+ for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
666
+ $entry = this.buildingRow.entriesBuff[i];
667
+ availableWidth -= $entry.data('jg.jwidth');
668
+ }
669
+
670
+ if (settings.lastRow === 'center')
671
+ offX += availableWidth / 2;
672
+ else if (settings.lastRow === 'right')
673
+ offX += availableWidth;
674
+ }
675
+
676
+ for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
677
+ $entry = this.buildingRow.entriesBuff[i];
678
+ this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height);
679
+ offX += $entry.data('jg.jwidth') + settings.margins;
680
+ }
681
+
682
+ //Gallery Height
683
+ this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border;
684
+ this.$gallery.height(this.galleryHeightToSet + this.getSpinnerHeight());
685
+
686
+ if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowRes)) {
687
+ //Ready for a new row
688
+ this.offY += this.buildingRow.height + settings.margins;
689
+ this.rows += 1;
690
+ this.clearBuildingRow();
691
+ this.$gallery.trigger('jg.rowflush');
692
+ }
693
+ };
694
+
695
+ /**
696
+ * Checks the width of the gallery container, to know if a new justification is needed
697
+ */
698
+ var scrollBarOn = false;
699
+ JustifiedGallery.prototype.checkWidth = function () {
700
+ this.checkWidthIntervalId = setInterval($.proxy(function () {
701
+ var galleryWidth = parseFloat(this.$gallery.width());
702
+ if (hasScrollBar() === scrollBarOn){
703
+
704
+ if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) {
705
+ this.galleryWidth = galleryWidth;
706
+ this.rewind();
707
+
708
+ // Restart to analyze
709
+ this.startImgAnalyzer(true);
710
+ }
711
+ } else {
712
+ scrollBarOn = hasScrollBar();
713
+ this.galleryWidth = galleryWidth;
714
+ }
715
+ }, this), this.settings.refreshTime);
716
+ };
717
+
718
+ /**
719
+ * @returns {boolean} a boolean saying if the spinner is active or not
720
+ */
721
+ JustifiedGallery.prototype.isSpinnerActive = function () {
722
+ return this.spinner.intervalId !== null;
723
+ };
724
+
725
+ /**
726
+ * @returns {int} the spinner height
727
+ */
728
+ JustifiedGallery.prototype.getSpinnerHeight = function () {
729
+ return this.spinner.$el.innerHeight();
730
+ };
731
+
732
+ /**
733
+ * Stops the spinner animation and modify the gallery height to exclude the spinner
734
+ */
735
+ JustifiedGallery.prototype.stopLoadingSpinnerAnimation = function () {
736
+ clearInterval(this.spinner.intervalId);
737
+ this.spinner.intervalId = null;
738
+ this.$gallery.height(this.$gallery.height() - this.getSpinnerHeight());
739
+ this.spinner.$el.detach();
740
+ };
741
+
742
+ /**
743
+ * Starts the spinner animation
744
+ */
745
+ JustifiedGallery.prototype.startLoadingSpinnerAnimation = function () {
746
+ var spinnerContext = this.spinner;
747
+ var $spinnerPoints = spinnerContext.$el.find('span');
748
+ clearInterval(spinnerContext.intervalId);
749
+ this.$gallery.append(spinnerContext.$el);
750
+ this.$gallery.height(this.offY + this.buildingRow.height + this.getSpinnerHeight());
751
+ spinnerContext.intervalId = setInterval(function () {
752
+ if (spinnerContext.phase < $spinnerPoints.length) {
753
+ $spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1);
754
+ } else {
755
+ $spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0);
756
+ }
757
+ spinnerContext.phase = (spinnerContext.phase + 1) % ($spinnerPoints.length * 2);
758
+ }, spinnerContext.timeSlot);
759
+ };
760
+
761
+ /**
762
+ * Rewind the image analysis to start from the first entry.
763
+ */
764
+ JustifiedGallery.prototype.rewind = function () {
765
+ this.lastAnalyzedIndex = -1;
766
+ this.offY = this.border;
767
+ this.rows = 0;
768
+ this.clearBuildingRow();
769
+ };
770
+
771
+ /**
772
+ * Update the entries searching it from the justified gallery HTML element
773
+ *
774
+ * @param norewind if norewind only the new entries will be changed (i.e. randomized, sorted or filtered)
775
+ * @returns {boolean} true if some entries has been founded
776
+ */
777
+ JustifiedGallery.prototype.updateEntries = function (norewind) {
778
+ this.entries = this.$gallery.find(this.settings.selector).toArray();
779
+ if (this.entries.length === 0) return false;
780
+
781
+ // Filter
782
+ if (this.settings.filter) {
783
+ this.modifyEntries(this.filterArray, norewind);
784
+ } else {
785
+ this.modifyEntries(this.resetFilters, norewind);
786
+ }
787
+
788
+ // Sort or randomize
789
+ if ($.isFunction(this.settings.sort)) {
790
+ this.modifyEntries(this.sortArray, norewind);
791
+ } else if (this.settings.randomize) {
792
+ this.modifyEntries(this.shuffleArray, norewind);
793
+ }
794
+
795
+ return true;
796
+ };
797
+
798
+ /**
799
+ * Apply the entries order to the DOM, iterating the entries and appending the images
800
+ *
801
+ * @param entries the entries that has been modified and that must be re-ordered in the DOM
802
+ */
803
+ JustifiedGallery.prototype.insertToGallery = function (entries) {
804
+ var that = this;
805
+ $.each(entries, function () {
806
+ $(this).appendTo(that.$gallery);
807
+ });
808
+ };
809
+
810
+ /**
811
+ * Shuffle the array using the Fisher-Yates shuffle algorithm
812
+ *
813
+ * @param a the array to shuffle
814
+ * @return the shuffled array
815
+ */
816
+ JustifiedGallery.prototype.shuffleArray = function (a) {
817
+ var i, j, temp;
818
+ for (i = a.length - 1; i > 0; i--) {
819
+ j = Math.floor(Math.random() * (i + 1));
820
+ temp = a[i];
821
+ a[i] = a[j];
822
+ a[j] = temp;
823
+ }
824
+ this.insertToGallery(a);
825
+ return a;
826
+ };
827
+
828
+ /**
829
+ * Sort the array using settings.comparator as comparator
830
+ *
831
+ * @param a the array to sort (it is sorted)
832
+ * @return the sorted array
833
+ */
834
+ JustifiedGallery.prototype.sortArray = function (a) {
835
+ a.sort(this.settings.sort);
836
+ this.insertToGallery(a);
837
+ return a;
838
+ };
839
+
840
+ /**
841
+ * Reset the filters removing the 'jg-filtered' class from all the entries
842
+ *
843
+ * @param a the array to reset
844
+ */
845
+ JustifiedGallery.prototype.resetFilters = function (a) {
846
+ for (var i = 0; i < a.length; i++) $(a[i]).removeClass('jg-filtered');
847
+ return a;
848
+ };
849
+
850
+ /**
851
+ * Filter the entries considering theirs classes (if a string has been passed) or using a function for filtering.
852
+ *
853
+ * @param a the array to filter
854
+ * @return the filtered array
855
+ */
856
+ JustifiedGallery.prototype.filterArray = function (a) {
857
+ var settings = this.settings;
858
+ if ($.type(settings.filter) === 'string') {
859
+ // Filter only keeping the entries passed in the string
860
+ return a.filter(function (el) {
861
+ var $el = $(el);
862
+ if ($el.is(settings.filter)) {
863
+ $el.removeClass('jg-filtered');
864
+ return true;
865
+ } else {
866
+ $el.addClass('jg-filtered');
867
+ return false;
868
+ }
869
+ });
870
+ } else if ($.isFunction(settings.filter)) {
871
+ // Filter using the passed function
872
+ return a.filter(settings.filter);
873
+ }
874
+ };
875
+
876
+ /**
877
+ * Modify the entries. With norewind only the new inserted images will be modified (the ones after lastAnalyzedIndex)
878
+ *
879
+ * @param functionToApply the function to call to modify the entries (e.g. sorting, randomization, filtering)
880
+ * @param norewind specify if the norewind has been called or not
881
+ */
882
+ JustifiedGallery.prototype.modifyEntries = function (functionToApply, norewind) {
883
+ var lastEntries = norewind ?
884
+ this.entries.splice(this.lastAnalyzedIndex + 1, this.entries.length - this.lastAnalyzedIndex - 1)
885
+ : this.entries;
886
+ lastEntries = functionToApply.call(this, lastEntries);
887
+ this.entries = norewind ? this.entries.concat(lastEntries) : lastEntries;
888
+ };
889
+
890
+ /**
891
+ * Destroy the Justified Gallery instance.
892
+ *
893
+ * It clears all the css properties added in the style attributes. We doesn't backup the original
894
+ * values for those css attributes, because it costs (performance) and because in general one
895
+ * shouldn't use the style attribute for an uniform set of images (where we suppose the use of
896
+ * classes). Creating a backup is also difficult because JG could be called multiple times and
897
+ * with different style attributes.
898
+ */
899
+ JustifiedGallery.prototype.destroy = function () {
900
+ clearInterval(this.checkWidthIntervalId);
901
+
902
+ $.each(this.entries, $.proxy(function(_, entry) {
903
+ var $entry = $(entry);
904
+
905
+ // Reset entry style
906
+ $entry.css('width', '');
907
+ $entry.css('height', '');
908
+ $entry.css('top', '');
909
+ $entry.css('left', '');
910
+ $entry.data('jg.loaded', undefined);
911
+ $entry.removeClass('jg-entry');
912
+
913
+ // Reset image style
914
+ var $img = this.imgFromEntry($entry);
915
+ $img.css('width', '');
916
+ $img.css('height', '');
917
+ $img.css('margin-left', '');
918
+ $img.css('margin-top', '');
919
+ $img.attr('src', $img.data('jg.originalSrc'));
920
+ $img.data('jg.originalSrc', undefined);
921
+
922
+ // Remove caption
923
+ this.removeCaptionEventsHandlers($entry);
924
+ var $caption = this.captionFromEntry($entry);
925
+ if ($entry.data('jg.createdCaption')) {
926
+ // remove also the caption element (if created by jg)
927
+ $entry.data('jg.createdCaption', undefined);
928
+ if ($caption !== null) $caption.remove();
929
+ } else {
930
+ if ($caption !== null) $caption.fadeTo(0, 1);
931
+ }
932
+
933
+ }, this));
934
+
935
+ this.$gallery.css('height', '');
936
+ this.$gallery.removeClass('justified-gallery');
937
+ this.$gallery.data('jg.controller', undefined);
938
+ };
939
+
940
+ /**
941
+ * Analyze the images and builds the rows. It returns if it found an image that is not loaded.
942
+ *
943
+ * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end
944
+ */
945
+ JustifiedGallery.prototype.analyzeImages = function (isForResize) {
946
+ for (var i = this.lastAnalyzedIndex + 1; i < this.entries.length; i++) {
947
+ var $entry = $(this.entries[i]);
948
+ if ($entry.data('jg.loaded') === true || $entry.data('jg.loaded') === 'skipped') {
949
+ var availableWidth = this.galleryWidth - 2 * this.border - (
950
+ (this.buildingRow.entriesBuff.length - 1) * this.settings.margins);
951
+ var imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height');
952
+ if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) {
953
+ this.flushRow(false);
954
+ if(++this.yield.flushed >= this.yield.every) {
955
+ this.startImgAnalyzer(isForResize);
956
+ return;
957
+ }
958
+ }
959
+
960
+ this.buildingRow.entriesBuff.push($entry);
961
+ this.buildingRow.aspectRatio += imgAspectRatio;
962
+ this.buildingRow.width += imgAspectRatio * this.settings.rowHeight;
963
+ this.lastAnalyzedIndex = i;
964
+
965
+ } else if ($entry.data('jg.loaded') !== 'error') {
966
+ return;
967
+ }
968
+ }
969
+
970
+ // Last row flush (the row is not full)
971
+ if (this.buildingRow.entriesBuff.length > 0) this.flushRow(true);
972
+
973
+ if (this.isSpinnerActive()) {
974
+ this.stopLoadingSpinnerAnimation();
975
+ }
976
+
977
+ /* Stop, if there is, the timeout to start the analyzeImages.
978
+ This is because an image can be set loaded, and the timeout can be set,
979
+ but this image can be analyzed yet.
980
+ */
981
+ this.stopImgAnalyzerStarter();
982
+
983
+ //On complete callback
984
+ this.$gallery.trigger(isForResize ? 'jg.resize' : 'jg.complete');
985
+ this.$gallery.height(this.galleryHeightToSet);
986
+ };
987
+
988
+ /**
989
+ * Stops any ImgAnalyzer starter (that has an assigned timeout)
990
+ */
991
+ JustifiedGallery.prototype.stopImgAnalyzerStarter = function () {
992
+ this.yield.flushed = 0;
993
+ if (this.imgAnalyzerTimeout !== null) clearTimeout(this.imgAnalyzerTimeout);
994
+ };
995
+
996
+ /**
997
+ * Starts the image analyzer. It is not immediately called to let the browser to update the view
998
+ *
999
+ * @param isForResize specifies if the image analyzer must be called for resizing or not
1000
+ */
1001
+ JustifiedGallery.prototype.startImgAnalyzer = function (isForResize) {
1002
+ var that = this;
1003
+ this.stopImgAnalyzerStarter();
1004
+ this.imgAnalyzerTimeout = setTimeout(function () {
1005
+ that.analyzeImages(isForResize);
1006
+ }, 0.001); // we can't start it immediately due to a IE different behaviour
1007
+ };
1008
+
1009
+ /**
1010
+ * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property,
1011
+ * because some browsers, with a 404 set complete = true.
1012
+ *
1013
+ * @param imageSrc the image src to load
1014
+ * @param onLoad callback that is called when the image has been loaded
1015
+ * @param onError callback that is called in case of an error
1016
+ */
1017
+ JustifiedGallery.prototype.onImageEvent = function (imageSrc, onLoad, onError) {
1018
+ if (!onLoad && !onError) return;
1019
+
1020
+ var memImage = new Image();
1021
+ var $memImage = $(memImage);
1022
+ if (onLoad) {
1023
+ $memImage.one('load', function () {
1024
+ $memImage.off('load error');
1025
+ onLoad(memImage);
1026
+ });
1027
+ }
1028
+ if (onError) {
1029
+ $memImage.one('error', function() {
1030
+ $memImage.off('load error');
1031
+ onError(memImage);
1032
+ });
1033
+ }
1034
+ memImage.src = imageSrc;
1035
+ };
1036
+
1037
+ /**
1038
+ * Init of Justified Gallery controlled
1039
+ * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images)
1040
+ */
1041
+ JustifiedGallery.prototype.init = function () {
1042
+ var imagesToLoad = false, skippedImages = false, that = this;
1043
+ $.each(this.entries, function (index, entry) {
1044
+ var $entry = $(entry);
1045
+ var $image = that.imgFromEntry($entry);
1046
+
1047
+ $entry.addClass('jg-entry');
1048
+
1049
+ if ($entry.data('jg.loaded') !== true && $entry.data('jg.loaded') !== 'skipped') {
1050
+
1051
+ // Link Rel global overwrite
1052
+ if (that.settings.rel !== null) $entry.attr('rel', that.settings.rel);
1053
+
1054
+ // Link Target global overwrite
1055
+ if (that.settings.target !== null) $entry.attr('target', that.settings.target);
1056
+
1057
+ if ($image !== null) {
1058
+
1059
+ // Image src
1060
+ var imageSrc = that.extractImgSrcFromImage($image);
1061
+ $image.attr('src', imageSrc);
1062
+
1063
+ /* If we have the height and the width, we don't wait that the image is loaded, but we start directly
1064
+ * with the justification */
1065
+ if (that.settings.waitThumbnailsLoad === false) {
1066
+ var width = parseFloat($image.attr('width'));
1067
+ var height = parseFloat($image.attr('height'));
1068
+ if (!isNaN(width) && !isNaN(height)) {
1069
+ $entry.data('jg.width', width);
1070
+ $entry.data('jg.height', height);
1071
+ $entry.data('jg.loaded', 'skipped');
1072
+ skippedImages = true;
1073
+ that.startImgAnalyzer(false);
1074
+ return true; // continue
1075
+ }
1076
+ }
1077
+
1078
+ $entry.data('jg.loaded', false);
1079
+ imagesToLoad = true;
1080
+
1081
+ // Spinner start
1082
+ if (!that.isSpinnerActive()) that.startLoadingSpinnerAnimation();
1083
+
1084
+ that.onImageEvent(imageSrc, function (loadImg) { // image loaded
1085
+ $entry.data('jg.width', loadImg.width);
1086
+ $entry.data('jg.height', loadImg.height);
1087
+ $entry.data('jg.loaded', true);
1088
+ that.startImgAnalyzer(false);
1089
+ }, function () { // image load error
1090
+ $entry.data('jg.loaded', 'error');
1091
+ that.startImgAnalyzer(false);
1092
+ });
1093
+
1094
+ } else {
1095
+ $entry.data('jg.loaded', true);
1096
+ $entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1);
1097
+ $entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1);
1098
+ }
1099
+
1100
+ }
1101
+
1102
+ });
1103
+
1104
+ if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false);
1105
+ this.checkWidth();
1106
+ };
1107
+
1108
+ /**
1109
+ * Checks that it is a valid number. If a string is passed it is converted to a number
1110
+ *
1111
+ * @param settingContainer the object that contains the setting (to allow the conversion)
1112
+ * @param settingName the setting name
1113
+ */
1114
+ JustifiedGallery.prototype.checkOrConvertNumber = function (settingContainer, settingName) {
1115
+ if ($.type(settingContainer[settingName]) === 'string') {
1116
+ settingContainer[settingName] = parseFloat(settingContainer[settingName]);
1117
+ }
1118
+
1119
+ if ($.type(settingContainer[settingName]) === 'number') {
1120
+ if (isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName;
1121
+ } else {
1122
+ throw settingName + ' must be a number';
1123
+ }
1124
+ };
1125
+
1126
+ /**
1127
+ * Checks the sizeRangeSuffixes and, if necessary, converts
1128
+ * its keys from string (e.g. old settings with 'lt100') to int.
1129
+ */
1130
+ JustifiedGallery.prototype.checkSizeRangesSuffixes = function () {
1131
+ if ($.type(this.settings.sizeRangeSuffixes) !== 'object') {
1132
+ throw 'sizeRangeSuffixes must be defined and must be an object';
1133
+ }
1134
+
1135
+ var suffixRanges = [];
1136
+ for (var rangeIdx in this.settings.sizeRangeSuffixes) {
1137
+ if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx);
1138
+ }
1139
+
1140
+ var newSizeRngSuffixes = {0: ''};
1141
+ for (var i = 0; i < suffixRanges.length; i++) {
1142
+ if ($.type(suffixRanges[i]) === 'string') {
1143
+ try {
1144
+ var numIdx = parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10);
1145
+ newSizeRngSuffixes[numIdx] = this.settings.sizeRangeSuffixes[suffixRanges[i]];
1146
+ } catch (e) {
1147
+ throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')';
1148
+ }
1149
+ } else {
1150
+ newSizeRngSuffixes[suffixRanges[i]] = this.settings.sizeRangeSuffixes[suffixRanges[i]];
1151
+ }
1152
+ }
1153
+
1154
+ this.settings.sizeRangeSuffixes = newSizeRngSuffixes;
1155
+ };
1156
+
1157
+ /**
1158
+ * check and convert the maxRowHeight setting
1159
+ */
1160
+ JustifiedGallery.prototype.retrieveMaxRowHeight = function () {
1161
+ var newMaxRowHeight = { };
1162
+
1163
+ if ($.type(this.settings.maxRowHeight) === 'string') {
1164
+ if (this.settings.maxRowHeight.match(/^[0-9]+%$/)) {
1165
+ newMaxRowHeight.value = parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100;
1166
+ newMaxRowHeight.isPercentage = false;
1167
+ } else {
1168
+ newMaxRowHeight.value = parseFloat(this.settings.maxRowHeight);
1169
+ newMaxRowHeight.isPercentage = true;
1170
+ }
1171
+ } else if ($.type(this.settings.maxRowHeight) === 'number') {
1172
+ newMaxRowHeight.value = this.settings.maxRowHeight;
1173
+ newMaxRowHeight.isPercentage = false;
1174
+ } else {
1175
+ throw 'maxRowHeight must be a number or a percentage';
1176
+ }
1177
+
1178
+ // check if the converted value is not a number
1179
+ if (isNaN(newMaxRowHeight.value)) throw 'invalid number for maxRowHeight';
1180
+
1181
+ // check values
1182
+ if (newMaxRowHeight.isPercentage) {
1183
+ if (newMaxRowHeight.value < 100) newMaxRowHeight.value = 100;
1184
+ } else {
1185
+ if (newMaxRowHeight.value > 0 && newMaxRowHeight.value < this.settings.rowHeight) {
1186
+ newMaxRowHeight.value = this.settings.rowHeight;
1187
+ }
1188
+ }
1189
+
1190
+ return newMaxRowHeight;
1191
+
1192
+ };
1193
+
1194
+ /**
1195
+ * Checks the settings
1196
+ */
1197
+ JustifiedGallery.prototype.checkSettings = function () {
1198
+ this.checkSizeRangesSuffixes();
1199
+
1200
+ this.checkOrConvertNumber(this.settings, 'rowHeight');
1201
+ this.checkOrConvertNumber(this.settings, 'margins');
1202
+ this.checkOrConvertNumber(this.settings, 'border');
1203
+
1204
+ var lastRowModes = [
1205
+ 'justify',
1206
+ 'nojustify',
1207
+ 'left',
1208
+ 'center',
1209
+ 'right',
1210
+ 'hide'
1211
+ ];
1212
+ if (lastRowModes.indexOf(this.settings.lastRow) === -1) {
1213
+ throw 'lastRow must be one of: ' + lastRowModes.join(', ');
1214
+ }
1215
+
1216
+ this.checkOrConvertNumber(this.settings, 'justifyThreshold');
1217
+ if (this.settings.justifyThreshold < 0 || this.settings.justifyThreshold > 1) {
1218
+ throw 'justifyThreshold must be in the interval [0,1]';
1219
+ }
1220
+ if ($.type(this.settings.cssAnimation) !== 'boolean') {
1221
+ throw 'cssAnimation must be a boolean';
1222
+ }
1223
+
1224
+ if ($.type(this.settings.captions) !== 'boolean') throw 'captions must be a boolean';
1225
+ this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration');
1226
+
1227
+ this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity');
1228
+ if (this.settings.captionSettings.visibleOpacity < 0 ||
1229
+ this.settings.captionSettings.visibleOpacity > 1) {
1230
+ throw 'captionSettings.visibleOpacity must be in the interval [0, 1]';
1231
+ }
1232
+
1233
+ this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity');
1234
+ if (this.settings.captionSettings.nonVisibleOpacity < 0 ||
1235
+ this.settings.captionSettings.nonVisibleOpacity > 1) {
1236
+ throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]';
1237
+ }
1238
+
1239
+ if ($.type(this.settings.fixedHeight) !== 'boolean') throw 'fixedHeight must be a boolean';
1240
+ this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration');
1241
+ this.checkOrConvertNumber(this.settings, 'refreshTime');
1242
+ this.checkOrConvertNumber(this.settings, 'refreshSensitivity');
1243
+ if ($.type(this.settings.randomize) !== 'boolean') throw 'randomize must be a boolean';
1244
+ if ($.type(this.settings.selector) !== 'string') throw 'selector must be a string';
1245
+
1246
+ if (this.settings.sort !== false && !$.isFunction(this.settings.sort)) {
1247
+ throw 'sort must be false or a comparison function';
1248
+ }
1249
+
1250
+ if (this.settings.filter !== false && !$.isFunction(this.settings.filter) &&
1251
+ $.type(this.settings.filter) !== 'string') {
1252
+ throw 'filter must be false, a string or a filter function';
1253
+ }
1254
+ };
1255
+
1256
+ /**
1257
+ * It brings all the indexes from the sizeRangeSuffixes and it orders them. They are then sorted and returned.
1258
+ * @returns {Array} sorted suffix ranges
1259
+ */
1260
+ JustifiedGallery.prototype.retrieveSuffixRanges = function () {
1261
+ var suffixRanges = [];
1262
+ for (var rangeIdx in this.settings.sizeRangeSuffixes) {
1263
+ if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10));
1264
+ }
1265
+ suffixRanges.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; });
1266
+ return suffixRanges;
1267
+ };
1268
+
1269
+ /**
1270
+ * Update the existing settings only changing some of them
1271
+ *
1272
+ * @param newSettings the new settings (or a subgroup of them)
1273
+ */
1274
+ JustifiedGallery.prototype.updateSettings = function (newSettings) {
1275
+ // In this case Justified Gallery has been called again changing only some options
1276
+ this.settings = $.extend({}, this.settings, newSettings);
1277
+ this.checkSettings();
1278
+
1279
+ // As reported in the settings: negative value = same as margins, 0 = disabled
1280
+ this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins;
1281
+
1282
+ this.maxRowHeight = this.retrieveMaxRowHeight();
1283
+ this.suffixRanges = this.retrieveSuffixRanges();
1284
+ };
1285
+
1286
+ /**
1287
+ * Justified Gallery plugin for jQuery
1288
+ *
1289
+ * Events
1290
+ * - jg.complete : called when all the gallery has been created
1291
+ * - jg.resize : called when the gallery has been resized
1292
+ * - jg.rowflush : when a new row appears
1293
+ *
1294
+ * @param arg the action (or the settings) passed when the plugin is called
1295
+ * @returns {*} the object itself
1296
+ */
1297
+ $.fn.justifiedGallery = function (arg) {
1298
+ return this.each(function (index, gallery) {
1299
+
1300
+ var $gallery = $(gallery);
1301
+ $gallery.addClass('justified-gallery');
1302
+
1303
+ var controller = $gallery.data('jg.controller');
1304
+ if (typeof controller === 'undefined') {
1305
+ // Create controller and assign it to the object data
1306
+ if (typeof arg !== 'undefined' && arg !== null && $.type(arg) !== 'object') {
1307
+ if (arg === 'destroy') return; // Just a call to an unexisting object
1308
+ throw 'The argument must be an object';
1309
+ }
1310
+ controller = new JustifiedGallery($gallery, $.extend({}, $.fn.justifiedGallery.defaults, arg));
1311
+ $gallery.data('jg.controller', controller);
1312
+ } else if (arg === 'norewind') {
1313
+ // In this case we don't rewind: we analyze only the latest images (e.g. to complete the last unfinished row
1314
+ // ... left to be more readable
1315
+ } else if (arg === 'destroy') {
1316
+ controller.destroy();
1317
+ return;
1318
+ } else {
1319
+ // In this case Justified Gallery has been called again changing only some options
1320
+ controller.updateSettings(arg);
1321
+ controller.rewind();
1322
+ }
1323
+
1324
+ // Update the entries list
1325
+ if (!controller.updateEntries(arg === 'norewind')) return;
1326
+
1327
+ // Init justified gallery
1328
+ controller.init();
1329
+
1330
+ });
1331
+ };
1332
+
1333
+ // Default options
1334
+ $.fn.justifiedGallery.defaults = {
1335
+ sizeRangeSuffixes: { }, /* e.g. Flickr configuration
1336
+ {
1337
+ 100: '_t', // used when longest is less than 100px
1338
+ 240: '_m', // used when longest is between 101px and 240px
1339
+ 320: '_n', // ...
1340
+ 500: '',
1341
+ 640: '_z',
1342
+ 1024: '_b' // used as else case because it is the last
1343
+ }
1344
+ */
1345
+ thumbnailPath: undefined, /* If defined, sizeRangeSuffixes is not used, and this function is used to determine the
1346
+ path relative to a specific thumbnail size. The function should accept respectively three arguments:
1347
+ current path, width and height */
1348
+ rowHeight: 120,
1349
+ maxRowHeight: -1, // negative value = no limits, number to express the value in pixels,
1350
+ // '[0-9]+%' to express in percentage (e.g. 300% means that the row height
1351
+ // can't exceed 3 * rowHeight)
1352
+ margins: 1,
1353
+ border: -1, // negative value = same as margins, 0 = disabled, any other value to set the border
1354
+
1355
+ lastRow: 'nojustify', // … which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide'
1356
+
1357
+ justifyThreshold: 0.90, /* if row width / available space > 0.90 it will be always justified
1358
+ * (i.e. lastRow setting is not considered) */
1359
+ fixedHeight: false,
1360
+ waitThumbnailsLoad: true,
1361
+ captions: true,
1362
+ cssAnimation: false,
1363
+ imagesAnimationDuration: 500, // ignored with css animations
1364
+ captionSettings: { // ignored with css animations
1365
+ animationDuration: 500,
1366
+ visibleOpacity: 0.7,
1367
+ nonVisibleOpacity: 0.0
1368
+ },
1369
+ rel: null, // rewrite the rel of each analyzed links
1370
+ target: null, // rewrite the target of all links
1371
+ extension: /\.[^.\\/]+$/, // regexp to capture the extension of an image
1372
+ refreshTime: 200, // time interval (in ms) to check if the page changes its width
1373
+ refreshSensitivity: 0, // change in width allowed (in px) without re-building the gallery
1374
+ randomize: false,
1375
+ sort: false, /*
1376
+ - false: to do not sort
1377
+ - function: to sort them using the function as comparator (see Array.prototype.sort())
1378
+ */
1379
+ filter: false, /*
1380
+ - false: for a disabled filter
1381
+ - a string: an entry is kept if entry.is(filter string) returns true
1382
+ see jQuery's .is() function for further information
1383
+ - a function: invoked with arguments (entry, index, array). Return true to keep the entry, false otherwise.
1384
+ see Array.prototype.filter for further information.
1385
+ */
1386
+ selector: '> a, > div:not(.spinner)' // The selector that is used to know what are the entries of the gallery
1387
+ };
1388
+
1389
+ }(jQuery));
1390
+
1391
+ /*!
1392
+ * Justified Gallery / Envira Extensions and Overrides - v3.6.2
1393
+ * Copyright (c) 2016 David Bisset, Benjamin Rojas
1394
+ * Licensed under the MIT license.
1395
+ */
1396
+
1397
+ (function ($) {
1398
+ var justifiedGallery = $.fn.justifiedGallery;
1399
+ var EnviraJustifiedGallery = {};
1400
+
1401
+ $.fn.enviraJustifiedGallery = function () {
1402
+ var obj = justifiedGallery.apply(this, arguments);
1403
+ EnviraJustifiedGallery = obj.data('jg.controller');
1404
+
1405
+ EnviraJustifiedGallery.displayEntryCaption = function ($entry) {
1406
+
1407
+ var $image = this.imgFromEntry($entry);
1408
+ if ($image !== null && this.settings.captions) {
1409
+ var $imgCaption = this.captionFromEntry($entry);
1410
+
1411
+ // Create it if it doesn't exists
1412
+ if ($imgCaption === null) {
1413
+
1414
+ var caption = $image.data('envira-caption');
1415
+
1416
+ if (this.isValidCaption(caption)) { // Create only we found something
1417
+ $imgCaption = $('<div class="caption">' + caption + '</div>');
1418
+ $entry.append($imgCaption);
1419
+ $entry.data('jg.createdCaption', true);
1420
+ }
1421
+ }
1422
+
1423
+ // Create events (we check again the $imgCaption because it can be still inexistent)
1424
+ if ($imgCaption !== null) {
1425
+ if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity);
1426
+ this.addCaptionEventsHandlers($entry);
1427
+ }
1428
+ } else {
1429
+ this.removeCaptionEventsHandlers($entry);
1430
+ }
1431
+ };
1432
+
1433
+ return EnviraJustifiedGallery;
1434
+
1435
+ };
1436
+ })(jQuery);
1437
+
1438
+ /*!
1439
+ * vintageJS
1440
+ * Add a retro/vintage effect to images using the HTML5 canvas element
1441
+ *
1442
+ * @license Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
1443
+ * @author Robert Fleischmann <rendro87@gmail.com>
1444
+ * @version 1.1.5
1445
+ */
1446
+
1447
+ !function(a,b){"function"==typeof define&&define.amd?define("vintagejs",["jquery"],function(c){return a.VintageJS=b(c)}):"object"==typeof exports?module.exports=b(require("jquery")):a.VintageJS=b(jQuery)}(this,function(a){var b=function(a,b,c){if(!1==a instanceof HTMLImageElement)throw"The element (1st parameter) must be an instance of HTMLImageElement";var d,e,f,g,h,i,j,k,l,m=new Image,n=new Image,o=document.createElement("canvas"),p=o.getContext("2d"),q={onStart:function(){},onStop:function(){},onError:function(){},mime:"image/jpeg"},r={curves:!1,screen:!1,desaturate:!1,vignette:!1,lighten:!1,noise:!1,viewFinder:!1,sepia:!1,brightness:!1,contrast:!1};m.onerror=q.onError,m.onload=function(){i=o.width=m.width,j=o.height=m.height,d()},n.onerror=q.onError,n.onload=function(){p.clearRect(0,0,i,j),p.drawImage(n,0,0,i,j),(window.vjsImageCache||(window.vjsImageCache={}))[l]=p.getImageData(0,0,i,j).data,d()},e=function(a){q.onStart(),k={};for(var b in r)k[b]=a[b]||r[b];g=[],k.viewFinder&&g.push(k.viewFinder),m.src==h?d():m.src=h},d=function(){if(0===g.length)return f();var a=g.pop();return l=[i,j,a].join("-"),window.vjsImageCache&&window.vjsImageCache[l]?d():void(n.src=a)},f=function(){var b,c,d;p.clearRect(0,0,i,j),p.drawImage(m,0,0,i,j),(k.vignette||k.lighten)&&(b=Math.sqrt(Math.pow(i/2,2)+Math.pow(j/2,2))),k.vignette&&(p.globalCompositeOperation="source-over",c=p.createRadialGradient(i/2,j/2,0,i/2,j/2,b),c.addColorStop(0,"rgba(0,0,0,0)"),c.addColorStop(.5,"rgba(0,0,0,0)"),c.addColorStop(1,["rgba(0,0,0,",k.vignette,")"].join("")),p.fillStyle=c,p.fillRect(0,0,i,j)),k.lighten&&(p.globalCompositeOperation="lighter",c=p.createRadialGradient(i/2,j/2,0,i/2,j/2,b),c.addColorStop(0,["rgba(255,255,255,",k.lighten,")"].join("")),c.addColorStop(.5,"rgba(255,255,255,0)"),c.addColorStop(1,"rgba(0,0,0,0)"),p.fillStyle=c,p.fillRect(0,0,i,j)),d=p.getImageData(0,0,i,j);var e,f,g,h,l,n,o,r,s,t=d.data;k.contrast&&(s=259*(k.contrast+255)/(255*(259-k.contrast))),k.viewFinder&&(r=window.vjsImageCache[[i,j,k.viewFinder].join("-")]);for(var u=i*j;u>=0;--u)for(e=u<<2,k.curves&&(t[e]=k.curves.r[t[e]],t[e+1]=k.curves.g[t[e+1]],t[e+2]=k.curves.b[t[e+2]]),k.contrast&&(t[e]=s*(t[e]-128)+128,t[e+1]=s*(t[e+1]-128)+128,t[e+2]=s*(t[e+2]-128)+128),k.brightness&&(t[e]+=k.brightness,t[e+1]+=k.brightness,t[e+2]+=k.brightness),k.screen&&(t[e]=255-(255-t[e])*(255-k.screen.r*k.screen.a)/255,t[e+1]=255-(255-t[e+1])*(255-k.screen.g*k.screen.a)/255,t[e+2]=255-(255-t[e+2])*(255-k.screen.b*k.screen.a)/255),k.noise&&(o=k.noise-Math.random()*k.noise/2,t[e]+=o,t[e+1]+=o,t[e+2]+=o),k.viewFinder&&(t[e]=t[e]*r[e]/255,t[e+1]=t[e+1]*r[e+1]/255,t[e+2]=t[e+2]*r[e+2]/255),k.sepia&&(g=t[e],h=t[e+1],l=t[e+2],t[e]=.393*g+.769*h+.189*l,t[e+1]=.349*g+.686*h+.168*l,t[e+2]=.272*g+.534*h+.131*l),k.desaturate&&(n=(t[e]+t[e+1]+t[e+2])/3,t[e]+=(n-t[e])*k.desaturate,t[e+1]+=(n-t[e+1])*k.desaturate,t[e+2]+=(n-t[e+2])*k.desaturate),f=2;f>=0;--f)t[e+f]=~~(t[e+f]>255?255:t[e+f]<0?0:t[e+f]);p.putImageData(d,0,0),a.src=p.canvas.toDataURL(q.mime),q.onStop()},h=a.src,b=b||{};for(var s in q)q[s]=b[s]||q[s];return c&&e(c),{apply:function(){h=a.src},reset:function(){a.src=h},vintage:e}};return a.fn.vintage=function(c,d){return this.each(function(){a.data(this,"vintageJS")||a.data(this,"vintageJS",new b(this,c,d))})},b});
1448
+
1449
+
1450
+ /*
1451
+
1452
+ Superfast Blur - a fast Box Blur For Canvas
1453
+
1454
+ Version: 0.5
1455
+ Author: Mario Klingemann
1456
+ Contact: mario@quasimondo.com
1457
+ Website: http://www.quasimondo.com/BoxBlurForCanvas
1458
+ Twitter: @quasimondo
1459
+
1460
+ In case you find this class useful - especially in commercial projects -
1461
+ I am not totally unhappy for a small donation to my PayPal account
1462
+ mario@quasimondo.de
1463
+
1464
+ Or support me on flattr:
1465
+ https://flattr.com/thing/140066/Superfast-Blur-a-pretty-fast-Box-Blur-Effect-for-CanvasJavascript
1466
+
1467
+ Copyright (c) 2011 Mario Klingemann
1468
+
1469
+ Permission is hereby granted, free of charge, to any person
1470
+ obtaining a copy of this software and associated documentation
1471
+ files (the "Software"), to deal in the Software without
1472
+ restriction, including without limitation the rights to use,
1473
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
1474
+ copies of the Software, and to permit persons to whom the
1475
+ Software is furnished to do so, subject to the following
1476
+ conditions:
1477
+
1478
+ The above copyright notice and this permission notice shall be
1479
+ included in all copies or substantial portions of the Software.
1480
+
1481
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1482
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
1483
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1484
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1485
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1486
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1487
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1488
+ OTHER DEALINGS IN THE SOFTWARE.
1489
+ */
1490
+ var mul_table = [ 1,57,41,21,203,34,97,73,227,91,149,62,105,45,39,137,241,107,3,173,39,71,65,238,219,101,187,87,81,151,141,133,249,117,221,209,197,187,177,169,5,153,73,139,133,127,243,233,223,107,103,99,191,23,177,171,165,159,77,149,9,139,135,131,253,245,119,231,224,109,211,103,25,195,189,23,45,175,171,83,81,79,155,151,147,9,141,137,67,131,129,251,123,30,235,115,113,221,217,53,13,51,50,49,193,189,185,91,179,175,43,169,83,163,5,79,155,19,75,147,145,143,35,69,17,67,33,65,255,251,247,243,239,59,29,229,113,111,219,27,213,105,207,51,201,199,49,193,191,47,93,183,181,179,11,87,43,85,167,165,163,161,159,157,155,77,19,75,37,73,145,143,141,35,138,137,135,67,33,131,129,255,63,250,247,61,121,239,237,117,29,229,227,225,111,55,109,216,213,211,209,207,205,203,201,199,197,195,193,48,190,47,93,185,183,181,179,178,176,175,173,171,85,21,167,165,41,163,161,5,79,157,78,154,153,19,75,149,74,147,73,144,143,71,141,140,139,137,17,135,134,133,66,131,65,129,1];
1491
+
1492
+
1493
+ var shg_table = [0,9,10,10,14,12,14,14,16,15,16,15,16,15,15,17,18,17,12,18,16,17,17,19,19,18,19,18,18,19,19,19,20,19,20,20,20,20,20,20,15,20,19,20,20,20,21,21,21,20,20,20,21,18,21,21,21,21,20,21,17,21,21,21,22,22,21,22,22,21,22,21,19,22,22,19,20,22,22,21,21,21,22,22,22,18,22,22,21,22,22,23,22,20,23,22,22,23,23,21,19,21,21,21,23,23,23,22,23,23,21,23,22,23,18,22,23,20,22,23,23,23,21,22,20,22,21,22,24,24,24,24,24,22,21,24,23,23,24,21,24,23,24,22,24,24,22,24,24,22,23,24,24,24,20,23,22,23,24,24,24,24,24,24,24,23,21,23,22,23,24,24,24,22,24,24,24,23,22,24,24,25,23,25,25,23,24,25,25,24,22,25,25,25,24,23,24,25,25,25,25,25,25,25,25,25,25,25,25,23,25,23,24,25,25,25,25,25,25,25,25,25,24,22,25,25,23,25,25,20,24,25,24,25,25,22,24,25,24,25,24,25,25,24,25,25,25,25,22,25,25,25,24,25,24,25,18];
1494
+
1495
+
1496
+ function boxBlurImage( imageID, canvasID, radius, blurAlphaChannel, iterations ){
1497
+
1498
+ var img = document.getElementById( imageID );
1499
+ var w = img.naturalWidth;
1500
+ var h = img.naturalHeight;
1501
+
1502
+ var canvas = document.getElementById( canvasID );
1503
+
1504
+ canvas.style.width = w + "px";
1505
+ canvas.style.height = h + "px";
1506
+ canvas.width = w;
1507
+ canvas.height = h;
1508
+
1509
+ var context = canvas.getContext("2d");
1510
+ context.clearRect( 0, 0, w, h );
1511
+ context.drawImage( img, 0, 0 );
1512
+
1513
+ if ( isNaN(radius) || radius < 1 ) return;
1514
+
1515
+ if ( blurAlphaChannel )
1516
+ {
1517
+ boxBlurCanvasRGBA( canvasID, 0, 0, w, h, radius, iterations );
1518
+ } else {
1519
+ boxBlurCanvasRGB( canvasID, 0, 0, w, h, radius, iterations );
1520
+ }
1521
+
1522
+ }
1523
+
1524
+
1525
+ function boxBlurCanvasRGBA( id, top_x, top_y, width, height, radius, iterations ){
1526
+ if ( isNaN(radius) || radius < 1 ) return;
1527
+
1528
+ radius |= 0;
1529
+
1530
+ if ( isNaN(iterations) ) iterations = 1;
1531
+ iterations |= 0;
1532
+ if ( iterations > 3 ) iterations = 3;
1533
+ if ( iterations < 1 ) iterations = 1;
1534
+
1535
+ var canvas = document.getElementById( id );
1536
+ var context = canvas.getContext("2d");
1537
+ var imageData;
1538
+
1539
+ try {
1540
+ try {
1541
+ imageData = context.getImageData( top_x, top_y, width, height );
1542
+ } catch(e) {
1543
+
1544
+ // NOTE: this part is supposedly only needed if you want to work with local files
1545
+ // so it might be okay to remove the whole try/catch block and just use
1546
+ // imageData = context.getImageData( top_x, top_y, width, height );
1547
+ try {
1548
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
1549
+ imageData = context.getImageData( top_x, top_y, width, height );
1550
+ } catch(e) {
1551
+ alert("Cannot access local image");
1552
+ throw new Error("unable to access local image data: " + e);
1553
+ return;
1554
+ }
1555
+ }
1556
+ } catch(e) {
1557
+ alert("Cannot access image");
1558
+ throw new Error("unable to access image data: " + e);
1559
+ return;
1560
+ }
1561
+
1562
+ var pixels = imageData.data;
1563
+
1564
+ var rsum,gsum,bsum,asum,x,y,i,p,p1,p2,yp,yi,yw,idx,pa;
1565
+ var wm = width - 1;
1566
+ var hm = height - 1;
1567
+ var wh = width * height;
1568
+ var rad1 = radius + 1;
1569
+
1570
+ var mul_sum = mul_table[radius];
1571
+ var shg_sum = shg_table[radius];
1572
+
1573
+ var r = [];
1574
+ var g = [];
1575
+ var b = [];
1576
+ var a = [];
1577
+
1578
+ var vmin = [];
1579
+ var vmax = [];
1580
+
1581
+ while ( iterations-- > 0 ){
1582
+ yw = yi = 0;
1583
+
1584
+ for ( y=0; y < height; y++ ){
1585
+ rsum = pixels[yw] * rad1;
1586
+ gsum = pixels[yw+1] * rad1;
1587
+ bsum = pixels[yw+2] * rad1;
1588
+ asum = pixels[yw+3] * rad1;
1589
+
1590
+
1591
+ for( i = 1; i <= radius; i++ ){
1592
+ p = yw + (((i > wm ? wm : i )) << 2 );
1593
+ rsum += pixels[p++];
1594
+ gsum += pixels[p++];
1595
+ bsum += pixels[p++];
1596
+ asum += pixels[p]
1597
+ }
1598
+
1599
+ for ( x = 0; x < width; x++ ) {
1600
+ r[yi] = rsum;
1601
+ g[yi] = gsum;
1602
+ b[yi] = bsum;
1603
+ a[yi] = asum;
1604
+
1605
+ if( y==0) {
1606
+ vmin[x] = ( ( p = x + rad1) < wm ? p : wm ) << 2;
1607
+ vmax[x] = ( ( p = x - radius) > 0 ? p << 2 : 0 );
1608
+ }
1609
+
1610
+ p1 = yw + vmin[x];
1611
+ p2 = yw + vmax[x];
1612
+
1613
+ rsum += pixels[p1++] - pixels[p2++];
1614
+ gsum += pixels[p1++] - pixels[p2++];
1615
+ bsum += pixels[p1++] - pixels[p2++];
1616
+ asum += pixels[p1] - pixels[p2];
1617
+
1618
+ yi++;
1619
+ }
1620
+ yw += ( width << 2 );
1621
+ }
1622
+
1623
+ for ( x = 0; x < width; x++ ) {
1624
+ yp = x;
1625
+ rsum = r[yp] * rad1;
1626
+ gsum = g[yp] * rad1;
1627
+ bsum = b[yp] * rad1;
1628
+ asum = a[yp] * rad1;
1629
+
1630
+ for( i = 1; i <= radius; i++ ) {
1631
+ yp += ( i > hm ? 0 : width );
1632
+ rsum += r[yp];
1633
+ gsum += g[yp];
1634
+ bsum += b[yp];
1635
+ asum += a[yp];
1636
+ }
1637
+
1638
+ yi = x << 2;
1639
+ for ( y = 0; y < height; y++) {
1640
+
1641
+ pixels[yi+3] = pa = (asum * mul_sum) >>> shg_sum;
1642
+ if ( pa > 0 )
1643
+ {
1644
+ pa = 255 / pa;
1645
+ pixels[yi] = ((rsum * mul_sum) >>> shg_sum) * pa;
1646
+ pixels[yi+1] = ((gsum * mul_sum) >>> shg_sum) * pa;
1647
+ pixels[yi+2] = ((bsum * mul_sum) >>> shg_sum) * pa;
1648
+ } else {
1649
+ pixels[yi] = pixels[yi+1] = pixels[yi+2] = 0;
1650
+ }
1651
+ if( x == 0 ) {
1652
+ vmin[y] = ( ( p = y + rad1) < hm ? p : hm ) * width;
1653
+ vmax[y] = ( ( p = y - radius) > 0 ? p * width : 0 );
1654
+ }
1655
+
1656
+ p1 = x + vmin[y];
1657
+ p2 = x + vmax[y];
1658
+
1659
+ rsum += r[p1] - r[p2];
1660
+ gsum += g[p1] - g[p2];
1661
+ bsum += b[p1] - b[p2];
1662
+ asum += a[p1] - a[p2];
1663
+
1664
+ yi += width << 2;
1665
+ }
1666
+ }
1667
+ }
1668
+
1669
+ context.putImageData( imageData, top_x, top_y );
1670
+
1671
+ }
1672
+
1673
+ function boxBlurCanvasRGB( id, top_x, top_y, width, height, radius, iterations ){
1674
+ if ( isNaN(radius) || radius < 1 ) return;
1675
+
1676
+ radius |= 0;
1677
+
1678
+ if ( isNaN(iterations) ) iterations = 1;
1679
+ iterations |= 0;
1680
+ if ( iterations > 3 ) iterations = 3;
1681
+ if ( iterations < 1 ) iterations = 1;
1682
+
1683
+ var canvas = id;
1684
+ var context = canvas.getContext("2d");
1685
+ var imageData;
1686
+
1687
+ try {
1688
+ try {
1689
+ imageData = context.getImageData( top_x, top_y, width, height );
1690
+ } catch(e) {
1691
+
1692
+ // NOTE: this part is supposedly only needed if you want to work with local files
1693
+ // so it might be okay to remove the whole try/catch block and just use
1694
+ // imageData = context.getImageData( top_x, top_y, width, height );
1695
+ try {
1696
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
1697
+ imageData = context.getImageData( top_x, top_y, width, height );
1698
+ } catch(e) {
1699
+ alert("Cannot access local image");
1700
+ throw new Error("unable to access local image data: " + e);
1701
+ return;
1702
+ }
1703
+ }
1704
+ } catch(e) {
1705
+ alert("Cannot access image");
1706
+ throw new Error("unable to access image data: " + e);
1707
+ return;
1708
+ }
1709
+
1710
+ var pixels = imageData.data;
1711
+
1712
+ var rsum,gsum,bsum,asum,x,y,i,p,p1,p2,yp,yi,yw,idx;
1713
+ var wm = width - 1;
1714
+ var hm = height - 1;
1715
+ var wh = width * height;
1716
+ var rad1 = radius + 1;
1717
+
1718
+ var r = [];
1719
+ var g = [];
1720
+ var b = [];
1721
+
1722
+ var mul_sum = mul_table[radius];
1723
+ var shg_sum = shg_table[radius];
1724
+
1725
+ var vmin = [];
1726
+ var vmax = [];
1727
+
1728
+ while ( iterations-- > 0 ){
1729
+ yw = yi = 0;
1730
+
1731
+ for ( y=0; y < height; y++ ){
1732
+ rsum = pixels[yw] * rad1;
1733
+ gsum = pixels[yw+1] * rad1;
1734
+ bsum = pixels[yw+2] * rad1;
1735
+
1736
+ for( i = 1; i <= radius; i++ ){
1737
+ p = yw + (((i > wm ? wm : i )) << 2 );
1738
+ rsum += pixels[p++];
1739
+ gsum += pixels[p++];
1740
+ bsum += pixels[p++];
1741
+ }
1742
+
1743
+ for ( x = 0; x < width; x++ ){
1744
+ r[yi] = rsum;
1745
+ g[yi] = gsum;
1746
+ b[yi] = bsum;
1747
+
1748
+ if( y==0) {
1749
+ vmin[x] = ( ( p = x + rad1) < wm ? p : wm ) << 2;
1750
+ vmax[x] = ( ( p = x - radius) > 0 ? p << 2 : 0 );
1751
+ }
1752
+
1753
+ p1 = yw + vmin[x];
1754
+ p2 = yw + vmax[x];
1755
+
1756
+ rsum += pixels[p1++] - pixels[p2++];
1757
+ gsum += pixels[p1++] - pixels[p2++];
1758
+ bsum += pixels[p1++] - pixels[p2++];
1759
+
1760
+ yi++;
1761
+ }
1762
+ yw += ( width << 2 );
1763
+ }
1764
+
1765
+ for ( x = 0; x < width; x++ ){
1766
+ yp = x;
1767
+ rsum = r[yp] * rad1;
1768
+ gsum = g[yp] * rad1;
1769
+ bsum = b[yp] * rad1;
1770
+
1771
+ for( i = 1; i <= radius; i++ ){
1772
+ yp += ( i > hm ? 0 : width );
1773
+ rsum += r[yp];
1774
+ gsum += g[yp];
1775
+ bsum += b[yp];
1776
+ }
1777
+
1778
+ yi = x << 2;
1779
+ for ( y = 0; y < height; y++){
1780
+ pixels[yi] = (rsum * mul_sum) >>> shg_sum;
1781
+ pixels[yi+1] = (gsum * mul_sum) >>> shg_sum;
1782
+ pixels[yi+2] = (bsum * mul_sum) >>> shg_sum;
1783
+
1784
+ if( x == 0 ) {
1785
+ vmin[y] = ( ( p = y + rad1) < hm ? p : hm ) * width;
1786
+ vmax[y] = ( ( p = y - radius) > 0 ? p * width : 0 );
1787
+ }
1788
+
1789
+ p1 = x + vmin[y];
1790
+ p2 = x + vmax[y];
1791
+
1792
+ rsum += r[p1] - r[p2];
1793
+ gsum += g[p1] - g[p2];
1794
+ bsum += b[p1] - b[p2];
1795
+
1796
+ yi += width << 2;
1797
+ }
1798
+ }
1799
+ }
1800
+ context.putImageData( imageData, top_x, top_y );
1801
+
1802
+ }
1803
+
1804
+ /*
1805
+ * @fileOverview TouchSwipe - jQuery Plugin
1806
+ * @version 1.6.6
1807
+ *
1808
+ * @author Matt Bryson http://www.github.com/mattbryson
1809
+ * @see https://github.com/mattbryson/TouchSwipe-Jquery-Plugin
1810
+ * @see http://labs.rampinteractive.co.uk/touchSwipe/
1811
+ * @see http://plugins.jquery.com/project/touchSwipe
1812
+ *
1813
+ * Copyright (c) 2010-2015 Matt Bryson
1814
+ * Dual licensed under the MIT or GPL Version 2 licenses.
1815
+ *
1816
+ */
1817
+
1818
+ /*
1819
+ *
1820
+ * Changelog
1821
+ * $Date: 2010-12-12 (Wed, 12 Dec 2010) $
1822
+ * $version: 1.0.0
1823
+ * $version: 1.0.1 - removed multibyte comments
1824
+ *
1825
+ * $Date: 2011-21-02 (Mon, 21 Feb 2011) $
1826
+ * $version: 1.1.0 - added allowPageScroll property to allow swiping and scrolling of page
1827
+ * - changed handler signatures so one handler can be used for multiple events
1828
+ * $Date: 2011-23-02 (Wed, 23 Feb 2011) $
1829
+ * $version: 1.2.0 - added click handler. This is fired if the user simply clicks and does not swipe. The event object and click target are passed to handler.
1830
+ * - If you use the http://code.google.com/p/jquery-ui-for-ipad-and-iphone/ plugin, you can also assign jQuery mouse events to children of a touchSwipe object.
1831
+ * $version: 1.2.1 - removed console log!
1832
+ *
1833
+ * $version: 1.2.2 - Fixed bug where scope was not preserved in callback methods.
1834
+ *
1835
+ * $Date: 2011-28-04 (Thurs, 28 April 2011) $
1836
+ * $version: 1.2.4 - Changed licence terms to be MIT or GPL inline with jQuery. Added check for support of touch events to stop non compatible browsers erroring.
1837
+ *
1838
+ * $Date: 2011-27-09 (Tues, 27 September 2011) $
1839
+ * $version: 1.2.5 - Added support for testing swipes with mouse on desktop browser (thanks to https://github.com/joelhy)
1840
+ *
1841
+ * $Date: 2012-14-05 (Mon, 14 May 2012) $
1842
+ * $version: 1.2.6 - Added timeThreshold between start and end touch, so user can ignore slow swipes (thanks to Mark Chase). Default is null, all swipes are detected
1843
+ *
1844
+ * $Date: 2012-05-06 (Tues, 05 June 2012) $
1845
+ * $version: 1.2.7 - Changed time threshold to have null default for backwards compatibility. Added duration param passed back in events, and refactored how time is handled.
1846
+ *
1847
+ * $Date: 2012-05-06 (Tues, 05 June 2012) $
1848
+ * $version: 1.2.8 - Added the possibility to return a value like null or false in the trigger callback. In that way we can control when the touch start/move should take effect or not (simply by returning in some cases return null; or return false;) This effects the ontouchstart/ontouchmove event.
1849
+ *
1850
+ * $Date: 2012-06-06 (Wed, 06 June 2012) $
1851
+ * $version: 1.3.0 - Refactored whole plugin to allow for methods to be executed, as well as exposed defaults for user override. Added 'enable', 'disable', and 'destroy' methods
1852
+ *
1853
+ * $Date: 2012-05-06 (Fri, 05 June 2012) $
1854
+ * $version: 1.3.1 - Bug fixes - bind() with false as last argument is no longer supported in jQuery 1.6, also, if you just click, the duration is now returned correctly.
1855
+ *
1856
+ * $Date: 2012-29-07 (Sun, 29 July 2012) $
1857
+ * $version: 1.3.2 - Added fallbackToMouseEvents option to NOT capture mouse events on non touch devices.
1858
+ * - Added "all" fingers value to the fingers property, so any combination of fingers triggers the swipe, allowing event handlers to check the finger count
1859
+ *
1860
+ * $Date: 2012-09-08 (Thurs, 9 Aug 2012) $
1861
+ * $version: 1.3.3 - Code tidy prep for minefied version
1862
+ *
1863
+ * $Date: 2012-04-10 (wed, 4 Oct 2012) $
1864
+ * $version: 1.4.0 - Added pinch support, pinchIn and pinchOut
1865
+ *
1866
+ * $Date: 2012-11-10 (Thurs, 11 Oct 2012) $
1867
+ * $version: 1.5.0 - Added excludedElements, a jquery selector that specifies child elements that do NOT trigger swipes. By default, this is one select that removes all form, input select, button and anchor elements.
1868
+ *
1869
+ * $Date: 2012-22-10 (Mon, 22 Oct 2012) $
1870
+ * $version: 1.5.1 - Fixed bug with jQuery 1.8 and trailing comma in excludedElements
1871
+ * - Fixed bug with IE and eventPreventDefault()
1872
+ * $Date: 2013-01-12 (Fri, 12 Jan 2013) $
1873
+ * $version: 1.6.0 - Fixed bugs with pinching, mainly when both pinch and swipe enabled, as well as adding time threshold for multifinger gestures, so releasing one finger beofre the other doesnt trigger as single finger gesture.
1874
+ * - made the demo site all static local HTML pages so they can be run locally by a developer
1875
+ * - added jsDoc comments and added documentation for the plugin
1876
+ * - code tidy
1877
+ * - added triggerOnTouchLeave property that will end the event when the user swipes off the element.
1878
+ * $Date: 2013-03-23 (Sat, 23 Mar 2013) $
1879
+ * $version: 1.6.1 - Added support for ie8 touch events
1880
+ * $version: 1.6.2 - Added support for events binding with on / off / bind in jQ for all callback names.
1881
+ * - Deprecated the 'click' handler in favour of tap.
1882
+ * - added cancelThreshold property
1883
+ * - added option method to update init options at runtime
1884
+ * $version 1.6.3 - added doubletap, longtap events and longTapThreshold, doubleTapThreshold property
1885
+ *
1886
+ * $Date: 2013-04-04 (Thurs, 04 April 2013) $
1887
+ * $version 1.6.4 - Fixed bug with cancelThreshold introduced in 1.6.3, where swipe status no longer fired start event, and stopped once swiping back.
1888
+ *
1889
+ * $Date: 2013-08-24 (Sat, 24 Aug 2013) $
1890
+ * $version 1.6.5 - Merged a few pull requests fixing various bugs, added AMD support.
1891
+ *
1892
+ * $Date: 2014-06-04 (Wed, 04 June 2014) $
1893
+ * $version 1.6.6 - Merge of pull requests.
1894
+ * - IE10 touch support
1895
+ * - Only prevent default event handling on valid swipe
1896
+ * - Separate license/changelog comment
1897
+ * - Detect if the swipe is valid at the end of the touch event.
1898
+ * - Pass fingerdata to event handlers.
1899
+ * - Add 'hold' gesture
1900
+ * - Be more tolerant about the tap distance
1901
+ * - Typos and minor fixes
1902
+ *
1903
+ * $Date: 2015-22-01 (Thurs, 22 Jan 2015) $
1904
+ * $version 1.6.7 - Added patch from https://github.com/mattbryson/TouchSwipe-Jquery-Plugin/issues/206 to fix memory leak
1905
+ */
1906
+
1907
+ /**
1908
+ * See (http://jquery.com/).
1909
+ * @name $
1910
+ * @class
1911
+ * See the jQuery Library (http://jquery.com/) for full details. This just
1912
+ * documents the function and classes that are added to jQuery by this plug-in.
1913
+ */
1914
+
1915
+ /**
1916
+ * See (http://jquery.com/)
1917
+ * @name fn
1918
+ * @class
1919
+ * See the jQuery Library (http://jquery.com/) for full details. This just
1920
+ * documents the function and classes that are added to jQuery by this plug-in.
1921
+ * @memberOf $
1922
+ */
1923
+
1924
+
1925
+
1926
+ (function (factory) {
1927
+ if (typeof define === 'function' && define.amd && define.amd.jQuery) {
1928
+ // AMD. Register as anonymous module.
1929
+ define(['jquery'], factory);
1930
+ } else {
1931
+ // Browser globals.
1932
+ factory(jQuery);
1933
+ }
1934
+ }(function ($) {
1935
+ "use strict";
1936
+
1937
+ //Constants
1938
+ var LEFT = "left",
1939
+ RIGHT = "right",
1940
+ UP = "up",
1941
+ DOWN = "down",
1942
+ IN = "in",
1943
+ OUT = "out",
1944
+
1945
+ NONE = "none",
1946
+ AUTO = "auto",
1947
+
1948
+ SWIPE = "swipe",
1949
+ PINCH = "pinch",
1950
+ TAP = "tap",
1951
+ DOUBLE_TAP = "doubletap",
1952
+ LONG_TAP = "longtap",
1953
+ HOLD = "hold",
1954
+
1955
+ HORIZONTAL = "horizontal",
1956
+ VERTICAL = "vertical",
1957
+
1958
+ ALL_FINGERS = "all",
1959
+
1960
+ DOUBLE_TAP_THRESHOLD = 10,
1961
+
1962
+ PHASE_START = "start",
1963
+ PHASE_MOVE = "move",
1964
+ PHASE_END = "end",
1965
+ PHASE_CANCEL = "cancel",
1966
+
1967
+ SUPPORTS_TOUCH = 'ontouchstart' in window,
1968
+
1969
+ SUPPORTS_POINTER_IE10 = window.navigator.msPointerEnabled && !window.navigator.pointerEnabled,
1970
+
1971
+ SUPPORTS_POINTER = window.navigator.pointerEnabled || window.navigator.msPointerEnabled,
1972
+
1973
+ PLUGIN_NS = 'TouchSwipe';
1974
+
1975
+
1976
+
1977
+ /**
1978
+ * The default configuration, and available options to configure touch swipe with.
1979
+ * You can set the default values by updating any of the properties prior to instantiation.
1980
+ * @name $.fn.swipe.defaults
1981
+ * @namespace
1982
+ * @property {int} [fingers=1] The number of fingers to detect in a swipe. Any swipes that do not meet this requirement will NOT trigger swipe handlers.
1983
+ * @property {int} [threshold=75] The number of pixels that the user must move their finger by before it is considered a swipe.
1984
+ * @property {int} [cancelThreshold=null] The number of pixels that the user must move their finger back from the original swipe direction to cancel the gesture.
1985
+ * @property {int} [pinchThreshold=20] The number of pixels that the user must pinch their finger by before it is considered a pinch.
1986
+ * @property {int} [maxTimeThreshold=null] Time, in milliseconds, between touchStart and touchEnd must NOT exceed in order to be considered a swipe.
1987
+ * @property {int} [fingerReleaseThreshold=250] Time in milliseconds between releasing multiple fingers. If 2 fingers are down, and are released one after the other, if they are within this threshold, it counts as a simultaneous release.
1988
+ * @property {int} [longTapThreshold=500] Time in milliseconds between tap and release for a long tap
1989
+ * @property {int} [doubleTapThreshold=200] Time in milliseconds between 2 taps to count as a double tap
1990
+ * @property {function} [swipe=null] A handler to catch all swipes. See {@link $.fn.swipe#event:swipe}
1991
+ * @property {function} [swipeLeft=null] A handler that is triggered for "left" swipes. See {@link $.fn.swipe#event:swipeLeft}
1992
+ * @property {function} [swipeRight=null] A handler that is triggered for "right" swipes. See {@link $.fn.swipe#event:swipeRight}
1993
+ * @property {function} [swipeUp=null] A handler that is triggered for "up" swipes. See {@link $.fn.swipe#event:swipeUp}
1994
+ * @property {function} [swipeDown=null] A handler that is triggered for "down" swipes. See {@link $.fn.swipe#event:swipeDown}
1995
+ * @property {function} [swipeStatus=null] A handler triggered for every phase of the swipe. See {@link $.fn.swipe#event:swipeStatus}
1996
+ * @property {function} [pinchIn=null] A handler triggered for pinch in events. See {@link $.fn.swipe#event:pinchIn}
1997
+ * @property {function} [pinchOut=null] A handler triggered for pinch out events. See {@link $.fn.swipe#event:pinchOut}
1998
+ * @property {function} [pinchStatus=null] A handler triggered for every phase of a pinch. See {@link $.fn.swipe#event:pinchStatus}
1999
+ * @property {function} [tap=null] A handler triggered when a user just taps on the item, rather than swipes it. If they do not move, tap is triggered, if they do move, it is not.
2000
+ * @property {function} [doubleTap=null] A handler triggered when a user double taps on the item. The delay between taps can be set with the doubleTapThreshold property. See {@link $.fn.swipe.defaults#doubleTapThreshold}
2001
+ * @property {function} [longTap=null] A handler triggered when a user long taps on the item. The delay between start and end can be set with the longTapThreshold property. See {@link $.fn.swipe.defaults#longTapThreshold}
2002
+ * @property (function) [hold=null] A handler triggered when a user reaches longTapThreshold on the item. See {@link $.fn.swipe.defaults#longTapThreshold}
2003
+ * @property {boolean} [triggerOnTouchEnd=true] If true, the swipe events are triggered when the touch end event is received (user releases finger). If false, it will be triggered on reaching the threshold, and then cancel the touch event automatically.
2004
+ * @property {boolean} [triggerOnTouchLeave=false] If true, then when the user leaves the swipe object, the swipe will end and trigger appropriate handlers.
2005
+ * @property {string|undefined} [allowPageScroll='auto'] How the browser handles page scrolls when the user is swiping on a touchSwipe object. See {@link $.fn.swipe.pageScroll}. <br/><br/>
2006
+ <code>"auto"</code> : all undefined swipes will cause the page to scroll in that direction. <br/>
2007
+ <code>"none"</code> : the page will not scroll when user swipes. <br/>
2008
+ <code>"horizontal"</code> : will force page to scroll on horizontal swipes. <br/>
2009
+ <code>"vertical"</code> : will force page to scroll on vertical swipes. <br/>
2010
+ * @property {boolean} [fallbackToMouseEvents=true] If true mouse events are used when run on a non touch device, false will stop swipes being triggered by mouse events on non tocuh devices.
2011
+ * @property {string} [excludedElements="button, input, select, textarea, a, .noSwipe"] A jquery selector that specifies child elements that do NOT trigger swipes. By default this excludes all form, input, select, button, anchor and .noSwipe elements.
2012
+
2013
+ */
2014
+ var defaults = {
2015
+ fingers: 1,
2016
+ threshold: 75,
2017
+ cancelThreshold:null,
2018
+ pinchThreshold:20,
2019
+ maxTimeThreshold: null,
2020
+ fingerReleaseThreshold:250,
2021
+ longTapThreshold:500,
2022
+ doubleTapThreshold:200,
2023
+ swipe: null,
2024
+ swipeLeft: null,
2025
+ swipeRight: null,
2026
+ swipeUp: null,
2027
+ swipeDown: null,
2028
+ swipeStatus: null,
2029
+ pinchIn:null,
2030
+ pinchOut:null,
2031
+ pinchStatus:null,
2032
+ click:null, //Deprecated since 1.6.2
2033
+ tap:null,
2034
+ doubleTap:null,
2035
+ longTap:null,
2036
+ hold:null,
2037
+ triggerOnTouchEnd: true,
2038
+ triggerOnTouchLeave:false,
2039
+ allowPageScroll: "auto",
2040
+ fallbackToMouseEvents: true,
2041
+ excludedElements:"label, button, input, select, textarea, a, .noSwipe"
2042
+ };
2043
+
2044
+
2045
+
2046
+ /**
2047
+ * Applies TouchSwipe behaviour to one or more jQuery objects.
2048
+ * The TouchSwipe plugin can be instantiated via this method, or methods within
2049
+ * TouchSwipe can be executed via this method as per jQuery plugin architecture.
2050
+ * @see TouchSwipe
2051
+ * @class
2052
+ * @param {Mixed} method If the current DOMNode is a TouchSwipe object, and <code>method</code> is a TouchSwipe method, then
2053
+ * the <code>method</code> is executed, and any following arguments are passed to the TouchSwipe method.
2054
+ * If <code>method</code> is an object, then the TouchSwipe class is instantiated on the current DOMNode, passing the
2055
+ * configuration properties defined in the object. See TouchSwipe
2056
+ *
2057
+ */
2058
+ $.fn.swipe = function (method) {
2059
+ var $this = $(this),
2060
+ plugin = $this.data(PLUGIN_NS);
2061
+
2062
+ //Check if we are already instantiated and trying to execute a method
2063
+ if (plugin && typeof method === 'string') {
2064
+ if (plugin[method]) {
2065
+ return plugin[method].apply(this, Array.prototype.slice.call(arguments, 1));
2066
+ } else {
2067
+ $.error('Method ' + method + ' does not exist on jQuery.swipe');
2068
+ }
2069
+ }
2070
+ //Else not instantiated and trying to pass init object (or nothing)
2071
+ else if (!plugin && (typeof method === 'object' || !method)) {
2072
+ return init.apply(this, arguments);
2073
+ }
2074
+
2075
+ return $this;
2076
+ };
2077
+
2078
+ //Expose our defaults so a user could override the plugin defaults
2079
+ $.fn.swipe.defaults = defaults;
2080
+
2081
+ /**
2082
+ * The phases that a touch event goes through. The <code>phase</code> is passed to the event handlers.
2083
+ * These properties are read only, attempting to change them will not alter the values passed to the event handlers.
2084
+ * @namespace
2085
+ * @readonly
2086
+ * @property {string} PHASE_START Constant indicating the start phase of the touch event. Value is <code>"start"</code>.
2087
+ * @property {string} PHASE_MOVE Constant indicating the move phase of the touch event. Value is <code>"move"</code>.
2088
+ * @property {string} PHASE_END Constant indicating the end phase of the touch event. Value is <code>"end"</code>.
2089
+ * @property {string} PHASE_CANCEL Constant indicating the cancel phase of the touch event. Value is <code>"cancel"</code>.
2090
+ */
2091
+ $.fn.swipe.phases = {
2092
+ PHASE_START: PHASE_START,
2093
+ PHASE_MOVE: PHASE_MOVE,
2094
+ PHASE_END: PHASE_END,
2095
+ PHASE_CANCEL: PHASE_CANCEL
2096
+ };
2097
+
2098
+ /**
2099
+ * The direction constants that are passed to the event handlers.
2100
+ * These properties are read only, attempting to change them will not alter the values passed to the event handlers.
2101
+ * @namespace
2102
+ * @readonly
2103
+ * @property {string} LEFT Constant indicating the left direction. Value is <code>"left"</code>.
2104
+ * @property {string} RIGHT Constant indicating the right direction. Value is <code>"right"</code>.
2105
+ * @property {string} UP Constant indicating the up direction. Value is <code>"up"</code>.
2106
+ * @property {string} DOWN Constant indicating the down direction. Value is <code>"cancel"</code>.
2107
+ * @property {string} IN Constant indicating the in direction. Value is <code>"in"</code>.
2108
+ * @property {string} OUT Constant indicating the out direction. Value is <code>"out"</code>.
2109
+ */
2110
+ $.fn.swipe.directions = {
2111
+ LEFT: LEFT,
2112
+ RIGHT: RIGHT,
2113
+ UP: UP,
2114
+ DOWN: DOWN,
2115
+ IN : IN,
2116
+ OUT: OUT
2117
+ };
2118
+
2119
+ /**
2120
+ * The page scroll constants that can be used to set the value of <code>allowPageScroll</code> option
2121
+ * These properties are read only
2122
+ * @namespace
2123
+ * @readonly
2124
+ * @see $.fn.swipe.defaults#allowPageScroll
2125
+ * @property {string} NONE Constant indicating no page scrolling is allowed. Value is <code>"none"</code>.
2126
+ * @property {string} HORIZONTAL Constant indicating horizontal page scrolling is allowed. Value is <code>"horizontal"</code>.
2127
+ * @property {string} VERTICAL Constant indicating vertical page scrolling is allowed. Value is <code>"vertical"</code>.
2128
+ * @property {string} AUTO Constant indicating either horizontal or vertical will be allowed, depending on the swipe handlers registered. Value is <code>"auto"</code>.
2129
+ */
2130
+ $.fn.swipe.pageScroll = {
2131
+ NONE: NONE,
2132
+ HORIZONTAL: HORIZONTAL,
2133
+ VERTICAL: VERTICAL,
2134
+ AUTO: AUTO
2135
+ };
2136
+
2137
+ /**
2138
+ * Constants representing the number of fingers used in a swipe. These are used to set both the value of <code>fingers</code> in the
2139
+ * options object, as well as the value of the <code>fingers</code> event property.
2140
+ * These properties are read only, attempting to change them will not alter the values passed to the event handlers.
2141
+ * @namespace
2142
+ * @readonly
2143
+ * @see $.fn.swipe.defaults#fingers
2144
+ * @property {string} ONE Constant indicating 1 finger is to be detected / was detected. Value is <code>1</code>.
2145
+ * @property {string} TWO Constant indicating 2 fingers are to be detected / were detected. Value is <code>1</code>.
2146
+ * @property {string} THREE Constant indicating 3 finger are to be detected / were detected. Value is <code>1</code>.
2147
+ * @property {string} ALL Constant indicating any combination of finger are to be detected. Value is <code>"all"</code>.
2148
+ */
2149
+ $.fn.swipe.fingers = {
2150
+ ONE: 1,
2151
+ TWO: 2,
2152
+ THREE: 3,
2153
+ ALL: ALL_FINGERS
2154
+ };
2155
+
2156
+ /**
2157
+ * Initialise the plugin for each DOM element matched
2158
+ * This creates a new instance of the main TouchSwipe class for each DOM element, and then
2159
+ * saves a reference to that instance in the elements data property.
2160
+ * @internal
2161
+ */
2162
+ function init(options) {
2163
+ //Prep and extend the options
2164
+ if (options && (options.allowPageScroll === undefined && (options.swipe !== undefined || options.swipeStatus !== undefined))) {
2165
+ options.allowPageScroll = NONE;
2166
+ }
2167
+
2168
+ //Check for deprecated options
2169
+ //Ensure that any old click handlers are assigned to the new tap, unless we have a tap
2170
+ if(options.click!==undefined && options.tap===undefined) {
2171
+ options.tap = options.click;
2172
+ }
2173
+
2174
+ if (!options) {
2175
+ options = {};
2176
+ }
2177
+
2178
+ //pass empty object so we dont modify the defaults
2179
+ options = $.extend({}, $.fn.swipe.defaults, options);
2180
+
2181
+ //For each element instantiate the plugin
2182
+ return this.each(function () {
2183
+ var $this = $(this);
2184
+
2185
+ //Check we havent already initialised the plugin
2186
+ var plugin = $this.data(PLUGIN_NS);
2187
+
2188
+ if (!plugin) {
2189
+ plugin = new TouchSwipe(this, options);
2190
+ $this.data(PLUGIN_NS, plugin);
2191
+ }
2192
+ });
2193
+ }
2194
+
2195
+ /**
2196
+ * Main TouchSwipe Plugin Class.
2197
+ * Do not use this to construct your TouchSwipe object, use the jQuery plugin method $.fn.swipe(); {@link $.fn.swipe}
2198
+ * @private
2199
+ * @name TouchSwipe
2200
+ * @param {DOMNode} element The HTML DOM object to apply to plugin to
2201
+ * @param {Object} options The options to configure the plugin with. @link {$.fn.swipe.defaults}
2202
+ * @see $.fh.swipe.defaults
2203
+ * @see $.fh.swipe
2204
+ * @class
2205
+ */
2206
+ function TouchSwipe(element, options) {
2207
+ var useTouchEvents = (SUPPORTS_TOUCH || SUPPORTS_POINTER || !options.fallbackToMouseEvents),
2208
+ START_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerDown' : 'pointerdown') : 'touchstart') : 'mousedown',
2209
+ MOVE_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerMove' : 'pointermove') : 'touchmove') : 'mousemove',
2210
+ END_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerUp' : 'pointerup') : 'touchend') : 'mouseup',
2211
+ LEAVE_EV = useTouchEvents ? null : 'mouseleave', //we manually detect leave on touch devices, so null event here
2212
+ CANCEL_EV = (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerCancel' : 'pointercancel') : 'touchcancel');
2213
+
2214
+
2215
+
2216
+ //touch properties
2217
+ var distance = 0,
2218
+ direction = null,
2219
+ duration = 0,
2220
+ startTouchesDistance = 0,
2221
+ endTouchesDistance = 0,
2222
+ pinchZoom = 1,
2223
+ pinchDistance = 0,
2224
+ pinchDirection = 0,
2225
+ maximumsMap=null;
2226
+
2227
+
2228
+
2229
+ //jQuery wrapped element for this instance
2230
+ var $element = $(element);
2231
+
2232
+ //Current phase of th touch cycle
2233
+ var phase = "start";
2234
+
2235
+ // the current number of fingers being used.
2236
+ var fingerCount = 0;
2237
+
2238
+ //track mouse points / delta
2239
+ var fingerData=null;
2240
+
2241
+ //track times
2242
+ var startTime = 0,
2243
+ endTime = 0,
2244
+ previousTouchEndTime=0,
2245
+ previousTouchFingerCount=0,
2246
+ doubleTapStartTime=0;
2247
+
2248
+ //Timeouts
2249
+ var singleTapTimeout=null,
2250
+ holdTimeout=null;
2251
+
2252
+ // Add gestures to all swipable areas if supported
2253
+ try {
2254
+ $element.bind(START_EV, touchStart);
2255
+ $element.bind(CANCEL_EV, touchCancel);
2256
+ }
2257
+ catch (e) {
2258
+ $.error('events not supported ' + START_EV + ',' + CANCEL_EV + ' on jQuery.swipe');
2259
+ }
2260
+
2261
+ //
2262
+ //Public methods
2263
+ //
2264
+
2265
+ /**
2266
+ * re-enables the swipe plugin with the previous configuration
2267
+ * @function
2268
+ * @name $.fn.swipe#enable
2269
+ * @return {DOMNode} The Dom element that was registered with TouchSwipe
2270
+ * @example $("#element").swipe("enable");
2271
+ */
2272
+ this.enable = function () {
2273
+ $element.bind(START_EV, touchStart);
2274
+ $element.bind(CANCEL_EV, touchCancel);
2275
+ return $element;
2276
+ };
2277
+
2278
+ /**
2279
+ * disables the swipe plugin
2280
+ * @function
2281
+ * @name $.fn.swipe#disable
2282
+ * @return {DOMNode} The Dom element that is now registered with TouchSwipe
2283
+ * @example $("#element").swipe("disable");
2284
+ */
2285
+ this.disable = function () {
2286
+ removeListeners();
2287
+ return $element;
2288
+ };
2289
+
2290
+ /**
2291
+ * Destroy the swipe plugin completely. To use any swipe methods, you must re initialise the plugin.
2292
+ * @function
2293
+ * @name $.fn.swipe#destroy
2294
+ * @example $("#element").swipe("destroy");
2295
+ */
2296
+ this.destroy = function () {
2297
+ removeListeners();
2298
+ $element.data(PLUGIN_NS, null);
2299
+ $element = null;
2300
+ };
2301
+
2302
+
2303
+ /**
2304
+ * Allows run time updating of the swipe configuration options.
2305
+ * @function
2306
+ * @name $.fn.swipe#option
2307
+ * @param {String} property The option property to get or set
2308
+ * @param {Object} [value] The value to set the property to
2309
+ * @return {Object} If only a property name is passed, then that property value is returned.
2310
+ * @example $("#element").swipe("option", "threshold"); // return the threshold
2311
+ * @example $("#element").swipe("option", "threshold", 100); // set the threshold after init
2312
+ * @see $.fn.swipe.defaults
2313
+ *
2314
+ */
2315
+ this.option = function (property, value) {
2316
+ if(options[property]!==undefined) {
2317
+ if(value===undefined) {
2318
+ return options[property];
2319
+ } else {
2320
+ options[property] = value;
2321
+ }
2322
+ } else {
2323
+ $.error('Option ' + property + ' does not exist on jQuery.swipe.options');
2324
+ }
2325
+
2326
+ return null;
2327
+ }
2328
+
2329
+ //
2330
+ // Private methods
2331
+ //
2332
+
2333
+ //
2334
+ // EVENTS
2335
+ //
2336
+ /**
2337
+ * Event handler for a touch start event.
2338
+ * Stops the default click event from triggering and stores where we touched
2339
+ * @inner
2340
+ * @param {object} jqEvent The normalised jQuery event object.
2341
+ */
2342
+ function touchStart(jqEvent) {
2343
+ //If we already in a touch event (a finger already in use) then ignore subsequent ones..
2344
+ if( getTouchInProgress() )
2345
+ return;
2346
+
2347
+ //Check if this element matches any in the excluded elements selectors, or its parent is excluded, if so, DON'T swipe
2348
+ if( $(jqEvent.target).closest( options.excludedElements, $element ).length>0 )
2349
+ return;
2350
+
2351
+ //As we use Jquery bind for events, we need to target the original event object
2352
+ //If these events are being programmatically triggered, we don't have an original event object, so use the Jq one.
2353
+ var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent;
2354
+
2355
+ var ret,
2356
+ evt = SUPPORTS_TOUCH ? event.touches[0] : event;
2357
+
2358
+ phase = PHASE_START;
2359
+
2360
+ //If we support touches, get the finger count
2361
+ if (SUPPORTS_TOUCH) {
2362
+ // get the total number of fingers touching the screen
2363
+ fingerCount = event.touches.length;
2364
+ }
2365
+ //Else this is the desktop, so stop the browser from dragging the image
2366
+ else {
2367
+ jqEvent.preventDefault(); //call this on jq event so we are cross browser
2368
+ }
2369
+
2370
+ //clear vars..
2371
+ distance = 0;
2372
+ direction = null;
2373
+ pinchDirection=null;
2374
+ duration = 0;
2375
+ startTouchesDistance=0;
2376
+ endTouchesDistance=0;
2377
+ pinchZoom = 1;
2378
+ pinchDistance = 0;
2379
+ fingerData=createAllFingerData();
2380
+ maximumsMap=createMaximumsData();
2381
+ cancelMultiFingerRelease();
2382
+
2383
+
2384
+ // check the number of fingers is what we are looking for, or we are capturing pinches
2385
+ if (!SUPPORTS_TOUCH || (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || hasPinches()) {
2386
+ // get the coordinates of the touch
2387
+ createFingerData( 0, evt );
2388
+ startTime = getTimeStamp();
2389
+
2390
+ if(fingerCount==2) {
2391
+ //Keep track of the initial pinch distance, so we can calculate the diff later
2392
+ //Store second finger data as start
2393
+ createFingerData( 1, event.touches[1] );
2394
+ startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start);
2395
+ }
2396
+
2397
+ if (options.swipeStatus || options.pinchStatus) {
2398
+ ret = triggerHandler(event, phase);
2399
+ }
2400
+ }
2401
+ else {
2402
+ //A touch with more or less than the fingers we are looking for, so cancel
2403
+ ret = false;
2404
+ }
2405
+
2406
+ //If we have a return value from the users handler, then return and cancel
2407
+ if (ret === false) {
2408
+ phase = PHASE_CANCEL;
2409
+ triggerHandler(event, phase);
2410
+ return ret;
2411
+ }
2412
+ else {
2413
+ if (options.hold) {
2414
+ holdTimeout = setTimeout($.proxy(function() {
2415
+ //Trigger the event
2416
+ $element.trigger('hold', [event.target]);
2417
+ //Fire the callback
2418
+ if(options.hold) {
2419
+ ret = options.hold.call($element, event, event.target);
2420
+ }
2421
+ }, this), options.longTapThreshold );
2422
+ }
2423
+
2424
+ setTouchInProgress(true);
2425
+ }
2426
+
2427
+ return null;
2428
+ };
2429
+
2430
+
2431
+
2432
+ /**
2433
+ * Event handler for a touch move event.
2434
+ * If we change fingers during move, then cancel the event
2435
+ * @inner
2436
+ * @param {object} jqEvent The normalised jQuery event object.
2437
+ */
2438
+ function touchMove(jqEvent) {
2439
+
2440
+ //As we use Jquery bind for events, we need to target the original event object
2441
+ //If these events are being programmatically triggered, we don't have an original event object, so use the Jq one.
2442
+ var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent;
2443
+
2444
+ //If we are ending, cancelling, or within the threshold of 2 fingers being released, don't track anything..
2445
+ if (phase === PHASE_END || phase === PHASE_CANCEL || inMultiFingerRelease())
2446
+ return;
2447
+
2448
+ var ret,
2449
+ evt = SUPPORTS_TOUCH ? event.touches[0] : event;
2450
+
2451
+
2452
+ //Update the finger data
2453
+ var currentFinger = updateFingerData(evt);
2454
+ endTime = getTimeStamp();
2455
+
2456
+ if (SUPPORTS_TOUCH) {
2457
+ fingerCount = event.touches.length;
2458
+ }
2459
+
2460
+ if (options.hold)
2461
+ clearTimeout(holdTimeout);
2462
+
2463
+ phase = PHASE_MOVE;
2464
+
2465
+ //If we have 2 fingers get Touches distance as well
2466
+ if(fingerCount==2) {
2467
+
2468
+ //Keep track of the initial pinch distance, so we can calculate the diff later
2469
+ //We do this here as well as the start event, in case they start with 1 finger, and the press 2 fingers
2470
+ if(startTouchesDistance==0) {
2471
+ //Create second finger if this is the first time...
2472
+ createFingerData( 1, event.touches[1] );
2473
+
2474
+ startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start);
2475
+ } else {
2476
+ //Else just update the second finger
2477
+ updateFingerData(event.touches[1]);
2478
+
2479
+ endTouchesDistance = calculateTouchesDistance(fingerData[0].end, fingerData[1].end);
2480
+ pinchDirection = calculatePinchDirection(fingerData[0].end, fingerData[1].end);
2481
+ }
2482
+
2483
+
2484
+ pinchZoom = calculatePinchZoom(startTouchesDistance, endTouchesDistance);
2485
+ pinchDistance = Math.abs(startTouchesDistance - endTouchesDistance);
2486
+ }
2487
+
2488
+
2489
+ if ( (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH || hasPinches() ) {
2490
+
2491
+ direction = calculateDirection(currentFinger.start, currentFinger.end);
2492
+
2493
+ //Check if we need to prevent default event (page scroll / pinch zoom) or not
2494
+ validateDefaultEvent(jqEvent, direction);
2495
+
2496
+ //Distance and duration are all off the main finger
2497
+ distance = calculateDistance(currentFinger.start, currentFinger.end);
2498
+ duration = calculateDuration();
2499
+
2500
+ //Cache the maximum distance we made in this direction
2501
+ setMaxDistance(direction, distance);
2502
+
2503
+
2504
+ if (options.swipeStatus || options.pinchStatus) {
2505
+ ret = triggerHandler(event, phase);
2506
+ }
2507
+
2508
+
2509
+ //If we trigger end events when threshold are met, or trigger events when touch leaves element
2510
+ if(!options.triggerOnTouchEnd || options.triggerOnTouchLeave) {
2511
+
2512
+ var inBounds = true;
2513
+
2514
+ //If checking if we leave the element, run the bounds check (we can use touchleave as its not supported on webkit)
2515
+ if(options.triggerOnTouchLeave) {
2516
+ var bounds = getbounds( this );
2517
+ inBounds = isInBounds( currentFinger.end, bounds );
2518
+ }
2519
+
2520
+ //Trigger end handles as we swipe if thresholds met or if we have left the element if the user has asked to check these..
2521
+ if(!options.triggerOnTouchEnd && inBounds) {
2522
+ phase = getNextPhase( PHASE_MOVE );
2523
+ }
2524
+ //We end if out of bounds here, so set current phase to END, and check if its modified
2525
+ else if(options.triggerOnTouchLeave && !inBounds ) {
2526
+ phase = getNextPhase( PHASE_END );
2527
+ }
2528
+
2529
+ if(phase==PHASE_CANCEL || phase==PHASE_END) {
2530
+ triggerHandler(event, phase);
2531
+ }
2532
+ }
2533
+ }
2534
+ else {
2535
+ phase = PHASE_CANCEL;
2536
+ triggerHandler(event, phase);
2537
+ }
2538
+
2539
+ if (ret === false) {
2540
+ phase = PHASE_CANCEL;
2541
+ triggerHandler(event, phase);
2542
+ }
2543
+ }
2544
+
2545
+
2546
+
2547
+ /**
2548
+ * Event handler for a touch end event.
2549
+ * Calculate the direction and trigger events
2550
+ * @inner
2551
+ * @param {object} jqEvent The normalised jQuery event object.
2552
+ */
2553
+ function touchEnd(jqEvent) {
2554
+ //As we use Jquery bind for events, we need to target the original event object
2555
+ var event = jqEvent.originalEvent;
2556
+
2557
+
2558
+ //If we are still in a touch with another finger return
2559
+ //This allows us to wait a fraction and see if the other finger comes up, if it does within the threshold, then we treat it as a multi release, not a single release.
2560
+ if (SUPPORTS_TOUCH) {
2561
+ if(event.touches.length>0) {
2562
+ startMultiFingerRelease();
2563
+ return true;
2564
+ }
2565
+ }
2566
+
2567
+ //If a previous finger has been released, check how long ago, if within the threshold, then assume it was a multifinger release.
2568
+ //This is used to allow 2 fingers to release fractionally after each other, whilst maintainig the event as containg 2 fingers, not 1
2569
+ if(inMultiFingerRelease()) {
2570
+ fingerCount=previousTouchFingerCount;
2571
+ }
2572
+
2573
+ //Set end of swipe
2574
+ endTime = getTimeStamp();
2575
+
2576
+ //Get duration incase move was never fired
2577
+ duration = calculateDuration();
2578
+
2579
+ //If we trigger handlers at end of swipe OR, we trigger during, but they didnt trigger and we are still in the move phase
2580
+ if(didSwipeBackToCancel() || !validateSwipeDistance()) {
2581
+ phase = PHASE_CANCEL;
2582
+ triggerHandler(event, phase);
2583
+ } else if (options.triggerOnTouchEnd || (options.triggerOnTouchEnd == false && phase === PHASE_MOVE)) {
2584
+ //call this on jq event so we are cross browser
2585
+ jqEvent.preventDefault();
2586
+ phase = PHASE_END;
2587
+ triggerHandler(event, phase);
2588
+ }
2589
+ //Special cases - A tap should always fire on touch end regardless,
2590
+ //So here we manually trigger the tap end handler by itself
2591
+ //We dont run trigger handler as it will re-trigger events that may have fired already
2592
+ else if (!options.triggerOnTouchEnd && hasTap()) {
2593
+ //Trigger the pinch events...
2594
+ phase = PHASE_END;
2595
+ triggerHandlerForGesture(event, phase, TAP);
2596
+ }
2597
+ else if (phase === PHASE_MOVE) {
2598
+ phase = PHASE_CANCEL;
2599
+ triggerHandler(event, phase);
2600
+ }
2601
+
2602
+ setTouchInProgress(false);
2603
+
2604
+ return null;
2605
+ }
2606
+
2607
+
2608
+
2609
+ /**
2610
+ * Event handler for a touch cancel event.
2611
+ * Clears current vars
2612
+ * @inner
2613
+ */
2614
+ function touchCancel() {
2615
+ // reset the variables back to default values
2616
+ fingerCount = 0;
2617
+ endTime = 0;
2618
+ startTime = 0;
2619
+ startTouchesDistance=0;
2620
+ endTouchesDistance=0;
2621
+ pinchZoom=1;
2622
+
2623
+ //If we were in progress of tracking a possible multi touch end, then re set it.
2624
+ cancelMultiFingerRelease();
2625
+
2626
+ setTouchInProgress(false);
2627
+ }
2628
+
2629
+
2630
+ /**
2631
+ * Event handler for a touch leave event.
2632
+ * This is only triggered on desktops, in touch we work this out manually
2633
+ * as the touchleave event is not supported in webkit
2634
+ * @inner
2635
+ */
2636
+ function touchLeave(jqEvent) {
2637
+ var event = jqEvent.originalEvent;
2638
+
2639
+ //If we have the trigger on leave property set....
2640
+ if(options.triggerOnTouchLeave) {
2641
+ phase = getNextPhase( PHASE_END );
2642
+ triggerHandler(event, phase);
2643
+ }
2644
+ }
2645
+
2646
+ /**
2647
+ * Removes all listeners that were associated with the plugin
2648
+ * @inner
2649
+ */
2650
+ function removeListeners() {
2651
+ $element.unbind(START_EV, touchStart);
2652
+ $element.unbind(CANCEL_EV, touchCancel);
2653
+ $element.unbind(MOVE_EV, touchMove);
2654
+ $element.unbind(END_EV, touchEnd);
2655
+
2656
+ //we only have leave events on desktop, we manually calculate leave on touch as its not supported in webkit
2657
+ if(LEAVE_EV) {
2658
+ $element.unbind(LEAVE_EV, touchLeave);
2659
+ }
2660
+
2661
+ setTouchInProgress(false);
2662
+ }
2663
+
2664
+
2665
+ /**
2666
+ * Checks if the time and distance thresholds have been met, and if so then the appropriate handlers are fired.
2667
+ */
2668
+ function getNextPhase(currentPhase) {
2669
+
2670
+ var nextPhase = currentPhase;
2671
+
2672
+ // Ensure we have valid swipe (under time and over distance and check if we are out of bound...)
2673
+ var validTime = validateSwipeTime();
2674
+ var validDistance = validateSwipeDistance();
2675
+ var didCancel = didSwipeBackToCancel();
2676
+
2677
+ //If we have exceeded our time, then cancel
2678
+ if(!validTime || didCancel) {
2679
+ nextPhase = PHASE_CANCEL;
2680
+ }
2681
+ //Else if we are moving, and have reached distance then end
2682
+ else if (validDistance && currentPhase == PHASE_MOVE && (!options.triggerOnTouchEnd || options.triggerOnTouchLeave) ) {
2683
+ nextPhase = PHASE_END;
2684
+ }
2685
+ //Else if we have ended by leaving and didn't reach distance, then cancel
2686
+ else if (!validDistance && currentPhase==PHASE_END && options.triggerOnTouchLeave) {
2687
+ nextPhase = PHASE_CANCEL;
2688
+ }
2689
+
2690
+ return nextPhase;
2691
+ }
2692
+
2693
+
2694
+ /**
2695
+ * Trigger the relevant event handler
2696
+ * The handlers are passed the original event, the element that was swiped, and in the case of the catch all handler, the direction that was swiped, "left", "right", "up", or "down"
2697
+ * @param {object} event the original event object
2698
+ * @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases}
2699
+ * @inner
2700
+ */
2701
+ function triggerHandler(event, phase) {
2702
+
2703
+ var ret = undefined;
2704
+
2705
+ // SWIPE GESTURES
2706
+ if(didSwipe() || hasSwipes()) { //hasSwipes as status needs to fire even if swipe is invalid
2707
+ //Trigger the swipe events...
2708
+ ret = triggerHandlerForGesture(event, phase, SWIPE);
2709
+ }
2710
+
2711
+ // PINCH GESTURES (if the above didn't cancel)
2712
+ else if((didPinch() || hasPinches()) && ret!==false) {
2713
+ //Trigger the pinch events...
2714
+ ret = triggerHandlerForGesture(event, phase, PINCH);
2715
+ }
2716
+
2717
+ // CLICK / TAP (if the above didn't cancel)
2718
+ if(didDoubleTap() && ret!==false) {
2719
+ //Trigger the tap events...
2720
+ ret = triggerHandlerForGesture(event, phase, DOUBLE_TAP);
2721
+ }
2722
+
2723
+ // CLICK / TAP (if the above didn't cancel)
2724
+ else if(didLongTap() && ret!==false) {
2725
+ //Trigger the tap events...
2726
+ ret = triggerHandlerForGesture(event, phase, LONG_TAP);
2727
+ }
2728
+
2729
+ // CLICK / TAP (if the above didn't cancel)
2730
+ else if(didTap() && ret!==false) {
2731
+ //Trigger the tap event..
2732
+ ret = triggerHandlerForGesture(event, phase, TAP);
2733
+ }
2734
+
2735
+
2736
+
2737
+ // If we are cancelling the gesture, then manually trigger the reset handler
2738
+ if (phase === PHASE_CANCEL) {
2739
+ touchCancel(event);
2740
+ }
2741
+
2742
+ // If we are ending the gesture, then manually trigger the reset handler IF all fingers are off
2743
+ if(phase === PHASE_END) {
2744
+ //If we support touch, then check that all fingers are off before we cancel
2745
+ if (SUPPORTS_TOUCH) {
2746
+ if(event.touches.length==0) {
2747
+ touchCancel(event);
2748
+ }
2749
+ }
2750
+ else {
2751
+ touchCancel(event);
2752
+ }
2753
+ }
2754
+
2755
+ return ret;
2756
+ }
2757
+
2758
+
2759
+
2760
+ /**
2761
+ * Trigger the relevant event handler
2762
+ * The handlers are passed the original event, the element that was swiped, and in the case of the catch all handler, the direction that was swiped, "left", "right", "up", or "down"
2763
+ * @param {object} event the original event object
2764
+ * @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases}
2765
+ * @param {string} gesture the gesture to trigger a handler for : PINCH or SWIPE {@link $.fn.swipe.gestures}
2766
+ * @return Boolean False, to indicate that the event should stop propagation, or void.
2767
+ * @inner
2768
+ */
2769
+ function triggerHandlerForGesture(event, phase, gesture) {
2770
+
2771
+ var ret=undefined;
2772
+
2773
+ //SWIPES....
2774
+ if(gesture==SWIPE) {
2775
+ //Trigger status every time..
2776
+
2777
+ //Trigger the event...
2778
+ $element.trigger('swipeStatus', [phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData]);
2779
+
2780
+ //Fire the callback
2781
+ if (options.swipeStatus) {
2782
+ ret = options.swipeStatus.call($element, event, phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData);
2783
+ //If the status cancels, then dont run the subsequent event handlers..
2784
+ if(ret===false) return false;
2785
+ }
2786
+
2787
+
2788
+
2789
+
2790
+ if (phase == PHASE_END && validateSwipe()) {
2791
+ //Fire the catch all event
2792
+ $element.trigger('swipe', [direction, distance, duration, fingerCount, fingerData]);
2793
+
2794
+ //Fire catch all callback
2795
+ if (options.swipe) {
2796
+ ret = options.swipe.call($element, event, direction, distance, duration, fingerCount, fingerData);
2797
+ //If the status cancels, then dont run the subsequent event handlers..
2798
+ if(ret===false) return false;
2799
+ }
2800
+
2801
+ //trigger direction specific event handlers
2802
+ switch (direction) {
2803
+ case LEFT:
2804
+ //Trigger the event
2805
+ $element.trigger('swipeLeft', [direction, distance, duration, fingerCount, fingerData]);
2806
+
2807
+ //Fire the callback
2808
+ if (options.swipeLeft) {
2809
+ ret = options.swipeLeft.call($element, event, direction, distance, duration, fingerCount, fingerData);
2810
+ }
2811
+ break;
2812
+
2813
+ case RIGHT:
2814
+ //Trigger the event
2815
+ $element.trigger('swipeRight', [direction, distance, duration, fingerCount, fingerData]);
2816
+
2817
+ //Fire the callback
2818
+ if (options.swipeRight) {
2819
+ ret = options.swipeRight.call($element, event, direction, distance, duration, fingerCount, fingerData);
2820
+ }
2821
+ break;
2822
+
2823
+ case UP:
2824
+ //Trigger the event
2825
+ $element.trigger('swipeUp', [direction, distance, duration, fingerCount, fingerData]);
2826
+
2827
+ //Fire the callback
2828
+ if (options.swipeUp) {
2829
+ ret = options.swipeUp.call($element, event, direction, distance, duration, fingerCount, fingerData);
2830
+ }
2831
+ break;
2832
+
2833
+ case DOWN:
2834
+ //Trigger the event
2835
+ $element.trigger('swipeDown', [direction, distance, duration, fingerCount, fingerData]);
2836
+
2837
+ //Fire the callback
2838
+ if (options.swipeDown) {
2839
+ ret = options.swipeDown.call($element, event, direction, distance, duration, fingerCount, fingerData);
2840
+ }
2841
+ break;
2842
+ }
2843
+ }
2844
+ }
2845
+
2846
+
2847
+ //PINCHES....
2848
+ if(gesture==PINCH) {
2849
+ //Trigger the event
2850
+ $element.trigger('pinchStatus', [phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]);
2851
+
2852
+ //Fire the callback
2853
+ if (options.pinchStatus) {
2854
+ ret = options.pinchStatus.call($element, event, phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData);
2855
+ //If the status cancels, then dont run the subsequent event handlers..
2856
+ if(ret===false) return false;
2857
+ }
2858
+
2859
+ if(phase==PHASE_END && validatePinch()) {
2860
+
2861
+ switch (pinchDirection) {
2862
+ case IN:
2863
+ //Trigger the event
2864
+ $element.trigger('pinchIn', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]);
2865
+
2866
+ //Fire the callback
2867
+ if (options.pinchIn) {
2868
+ ret = options.pinchIn.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData);
2869
+ }
2870
+ break;
2871
+
2872
+ case OUT:
2873
+ //Trigger the event
2874
+ $element.trigger('pinchOut', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]);
2875
+
2876
+ //Fire the callback
2877
+ if (options.pinchOut) {
2878
+ ret = options.pinchOut.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData);
2879
+ }
2880
+ break;
2881
+ }
2882
+ }
2883
+ }
2884
+
2885
+
2886
+
2887
+
2888
+
2889
+ if(gesture==TAP) {
2890
+ if(phase === PHASE_CANCEL || phase === PHASE_END) {
2891
+
2892
+
2893
+ //Cancel any existing double tap
2894
+ clearTimeout(singleTapTimeout);
2895
+ //Cancel hold timeout
2896
+ clearTimeout(holdTimeout);
2897
+
2898
+ //If we are also looking for doubelTaps, wait incase this is one...
2899
+ if(hasDoubleTap() && !inDoubleTap()) {
2900
+ //Cache the time of this tap
2901
+ doubleTapStartTime = getTimeStamp();
2902
+
2903
+ //Now wait for the double tap timeout, and trigger this single tap
2904
+ //if its not cancelled by a double tap
2905
+ singleTapTimeout = setTimeout($.proxy(function() {
2906
+ doubleTapStartTime=null;
2907
+ //Trigger the event
2908
+ $element.trigger('tap', [event.target]);
2909
+
2910
+
2911
+ //Fire the callback
2912
+ if(options.tap) {
2913
+ ret = options.tap.call($element, event, event.target);
2914
+ }
2915
+ }, this), options.doubleTapThreshold );
2916
+
2917
+ } else {
2918
+ doubleTapStartTime=null;
2919
+
2920
+ //Trigger the event
2921
+ $element.trigger('tap', [event.target]);
2922
+
2923
+
2924
+ //Fire the callback
2925
+ if(options.tap) {
2926
+ ret = options.tap.call($element, event, event.target);
2927
+ }
2928
+ }
2929
+ }
2930
+ }
2931
+
2932
+ else if (gesture==DOUBLE_TAP) {
2933
+ if(phase === PHASE_CANCEL || phase === PHASE_END) {
2934
+ //Cancel any pending singletap
2935
+ clearTimeout(singleTapTimeout);
2936
+ doubleTapStartTime=null;
2937
+
2938
+ //Trigger the event
2939
+ $element.trigger('doubletap', [event.target]);
2940
+
2941
+ //Fire the callback
2942
+ if(options.doubleTap) {
2943
+ ret = options.doubleTap.call($element, event, event.target);
2944
+ }
2945
+ }
2946
+ }
2947
+
2948
+ else if (gesture==LONG_TAP) {
2949
+ if(phase === PHASE_CANCEL || phase === PHASE_END) {
2950
+ //Cancel any pending singletap (shouldnt be one)
2951
+ clearTimeout(singleTapTimeout);
2952
+ doubleTapStartTime=null;
2953
+
2954
+ //Trigger the event
2955
+ $element.trigger('longtap', [event.target]);
2956
+
2957
+ //Fire the callback
2958
+ if(options.longTap) {
2959
+ ret = options.longTap.call($element, event, event.target);
2960
+ }
2961
+ }
2962
+ }
2963
+
2964
+ return ret;
2965
+ }
2966
+
2967
+
2968
+
2969
+
2970
+ //
2971
+ // GESTURE VALIDATION
2972
+ //
2973
+
2974
+ /**
2975
+ * Checks the user has swipe far enough
2976
+ * @return Boolean if <code>threshold</code> has been set, return true if the threshold was met, else false.
2977
+ * If no threshold was set, then we return true.
2978
+ * @inner
2979
+ */
2980
+ function validateSwipeDistance() {
2981
+ var valid = true;
2982
+ //If we made it past the min swipe distance..
2983
+ if (options.threshold !== null) {
2984
+ valid = distance >= options.threshold;
2985
+ }
2986
+
2987
+ return valid;
2988
+ }
2989
+
2990
+ /**
2991
+ * Checks the user has swiped back to cancel.
2992
+ * @return Boolean if <code>cancelThreshold</code> has been set, return true if the cancelThreshold was met, else false.
2993
+ * If no cancelThreshold was set, then we return true.
2994
+ * @inner
2995
+ */
2996
+ function didSwipeBackToCancel() {
2997
+ var cancelled = false;
2998
+ if(options.cancelThreshold !== null && direction !==null) {
2999
+ cancelled = (getMaxDistance( direction ) - distance) >= options.cancelThreshold;
3000
+ }
3001
+
3002
+ return cancelled;
3003
+ }
3004
+
3005
+ /**
3006
+ * Checks the user has pinched far enough
3007
+ * @return Boolean if <code>pinchThreshold</code> has been set, return true if the threshold was met, else false.
3008
+ * If no threshold was set, then we return true.
3009
+ * @inner
3010
+ */
3011
+ function validatePinchDistance() {
3012
+ if (options.pinchThreshold !== null) {
3013
+ return pinchDistance >= options.pinchThreshold;
3014
+ }
3015
+ return true;
3016
+ }
3017
+
3018
+ /**
3019
+ * Checks that the time taken to swipe meets the minimum / maximum requirements
3020
+ * @return Boolean
3021
+ * @inner
3022
+ */
3023
+ function validateSwipeTime() {
3024
+ var result;
3025
+ //If no time set, then return true
3026
+
3027
+ if (options.maxTimeThreshold) {
3028
+ if (duration >= options.maxTimeThreshold) {
3029
+ result = false;
3030
+ } else {
3031
+ result = true;
3032
+ }
3033
+ }
3034
+ else {
3035
+ result = true;
3036
+ }
3037
+
3038
+ return result;
3039
+ }
3040
+
3041
+
3042
+ /**
3043
+ * Checks direction of the swipe and the value allowPageScroll to see if we should allow or prevent the default behaviour from occurring.
3044
+ * This will essentially allow page scrolling or not when the user is swiping on a touchSwipe object.
3045
+ * @param {object} jqEvent The normalised jQuery representation of the event object.
3046
+ * @param {string} direction The direction of the event. See {@link $.fn.swipe.directions}
3047
+ * @see $.fn.swipe.directions
3048
+ * @inner
3049
+ */
3050
+ function validateDefaultEvent(jqEvent, direction) {
3051
+ if (options.allowPageScroll === NONE || hasPinches()) {
3052
+ jqEvent.preventDefault();
3053
+ } else {
3054
+ var auto = options.allowPageScroll === AUTO;
3055
+
3056
+ switch (direction) {
3057
+ case LEFT:
3058
+ if ((options.swipeLeft && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) {
3059
+ jqEvent.preventDefault();
3060
+ }
3061
+ break;
3062
+
3063
+ case RIGHT:
3064
+ if ((options.swipeRight && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) {
3065
+ jqEvent.preventDefault();
3066
+ }
3067
+ break;
3068
+
3069
+ case UP:
3070
+ if ((options.swipeUp && auto) || (!auto && options.allowPageScroll != VERTICAL)) {
3071
+ jqEvent.preventDefault();
3072
+ }
3073
+ break;
3074
+
3075
+ case DOWN:
3076
+ if ((options.swipeDown && auto) || (!auto && options.allowPageScroll != VERTICAL)) {
3077
+ jqEvent.preventDefault();
3078
+ }
3079
+ break;
3080
+ }
3081
+ }
3082
+
3083
+ }
3084
+
3085
+
3086
+ // PINCHES
3087
+ /**
3088
+ * Returns true of the current pinch meets the thresholds
3089
+ * @return Boolean
3090
+ * @inner
3091
+ */
3092
+ function validatePinch() {
3093
+ var hasCorrectFingerCount = validateFingers();
3094
+ var hasEndPoint = validateEndPoint();
3095
+ var hasCorrectDistance = validatePinchDistance();
3096
+ return hasCorrectFingerCount && hasEndPoint && hasCorrectDistance;
3097
+
3098
+ }
3099
+
3100
+ /**
3101
+ * Returns true if any Pinch events have been registered
3102
+ * @return Boolean
3103
+ * @inner
3104
+ */
3105
+ function hasPinches() {
3106
+ //Enure we dont return 0 or null for false values
3107
+ return !!(options.pinchStatus || options.pinchIn || options.pinchOut);
3108
+ }
3109
+
3110
+ /**
3111
+ * Returns true if we are detecting pinches, and have one
3112
+ * @return Boolean
3113
+ * @inner
3114
+ */
3115
+ function didPinch() {
3116
+ //Enure we dont return 0 or null for false values
3117
+ return !!(validatePinch() && hasPinches());
3118
+ }
3119
+
3120
+
3121
+
3122
+
3123
+ // SWIPES
3124
+ /**
3125
+ * Returns true if the current swipe meets the thresholds
3126
+ * @return Boolean
3127
+ * @inner
3128
+ */
3129
+ function validateSwipe() {
3130
+ //Check validity of swipe
3131
+ var hasValidTime = validateSwipeTime();
3132
+ var hasValidDistance = validateSwipeDistance();
3133
+ var hasCorrectFingerCount = validateFingers();
3134
+ var hasEndPoint = validateEndPoint();
3135
+ var didCancel = didSwipeBackToCancel();
3136
+
3137
+ // if the user swiped more than the minimum length, perform the appropriate action
3138
+ // hasValidDistance is null when no distance is set
3139
+ var valid = !didCancel && hasEndPoint && hasCorrectFingerCount && hasValidDistance && hasValidTime;
3140
+
3141
+ return valid;
3142
+ }
3143
+
3144
+ /**
3145
+ * Returns true if any Swipe events have been registered
3146
+ * @return Boolean
3147
+ * @inner
3148
+ */
3149
+ function hasSwipes() {
3150
+ //Enure we dont return 0 or null for false values
3151
+ return !!(options.swipe || options.swipeStatus || options.swipeLeft || options.swipeRight || options.swipeUp || options.swipeDown);
3152
+ }
3153
+
3154
+
3155
+ /**
3156
+ * Returns true if we are detecting swipes and have one
3157
+ * @return Boolean
3158
+ * @inner
3159
+ */
3160
+ function didSwipe() {
3161
+ //Enure we dont return 0 or null for false values
3162
+ return !!(validateSwipe() && hasSwipes());
3163
+ }
3164
+
3165
+ /**
3166
+ * Returns true if we have matched the number of fingers we are looking for
3167
+ * @return Boolean
3168
+ * @inner
3169
+ */
3170
+ function validateFingers() {
3171
+ //The number of fingers we want were matched, or on desktop we ignore
3172
+ return ((fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH);
3173
+ }
3174
+
3175
+ /**
3176
+ * Returns true if we have an end point for the swipe
3177
+ * @return Boolean
3178
+ * @inner
3179
+ */
3180
+ function validateEndPoint() {
3181
+ //We have an end value for the finger
3182
+ return fingerData[0].end.x !== 0;
3183
+ }
3184
+
3185
+ // TAP / CLICK
3186
+ /**
3187
+ * Returns true if a click / tap events have been registered
3188
+ * @return Boolean
3189
+ * @inner
3190
+ */
3191
+ function hasTap() {
3192
+ //Enure we dont return 0 or null for false values
3193
+ return !!(options.tap) ;
3194
+ }
3195
+
3196
+ /**
3197
+ * Returns true if a double tap events have been registered
3198
+ * @return Boolean
3199
+ * @inner
3200
+ */
3201
+ function hasDoubleTap() {
3202
+ //Enure we dont return 0 or null for false values
3203
+ return !!(options.doubleTap) ;
3204
+ }
3205
+
3206
+ /**
3207
+ * Returns true if any long tap events have been registered
3208
+ * @return Boolean
3209
+ * @inner
3210
+ */
3211
+ function hasLongTap() {
3212
+ //Enure we dont return 0 or null for false values
3213
+ return !!(options.longTap) ;
3214
+ }
3215
+
3216
+ /**
3217
+ * Returns true if we could be in the process of a double tap (one tap has occurred, we are listening for double taps, and the threshold hasn't past.
3218
+ * @return Boolean
3219
+ * @inner
3220
+ */
3221
+ function validateDoubleTap() {
3222
+ if(doubleTapStartTime==null){
3223
+ return false;
3224
+ }
3225
+ var now = getTimeStamp();
3226
+ return (hasDoubleTap() && ((now-doubleTapStartTime) <= options.doubleTapThreshold));
3227
+ }
3228
+
3229
+ /**
3230
+ * Returns true if we could be in the process of a double tap (one tap has occurred, we are listening for double taps, and the threshold hasn't past.
3231
+ * @return Boolean
3232
+ * @inner
3233
+ */
3234
+ function inDoubleTap() {
3235
+ return validateDoubleTap();
3236
+ }
3237
+
3238
+
3239
+ /**
3240
+ * Returns true if we have a valid tap
3241
+ * @return Boolean
3242
+ * @inner
3243
+ */
3244
+ function validateTap() {
3245
+ return ((fingerCount === 1 || !SUPPORTS_TOUCH) && (isNaN(distance) || distance < options.threshold));
3246
+ }
3247
+
3248
+ /**
3249
+ * Returns true if we have a valid long tap
3250
+ * @return Boolean
3251
+ * @inner
3252
+ */
3253
+ function validateLongTap() {
3254
+ //slight threshold on moving finger
3255
+ return ((duration > options.longTapThreshold) && (distance < DOUBLE_TAP_THRESHOLD));
3256
+ }
3257
+
3258
+ /**
3259
+ * Returns true if we are detecting taps and have one
3260
+ * @return Boolean
3261
+ * @inner
3262
+ */
3263
+ function didTap() {
3264
+ //Enure we dont return 0 or null for false values
3265
+ return !!(validateTap() && hasTap());
3266
+ }
3267
+
3268
+
3269
+ /**
3270
+ * Returns true if we are detecting double taps and have one
3271
+ * @return Boolean
3272
+ * @inner
3273
+ */
3274
+ function didDoubleTap() {
3275
+ //Enure we dont return 0 or null for false values
3276
+ return !!(validateDoubleTap() && hasDoubleTap());
3277
+ }
3278
+
3279
+ /**
3280
+ * Returns true if we are detecting long taps and have one
3281
+ * @return Boolean
3282
+ * @inner
3283
+ */
3284
+ function didLongTap() {
3285
+ //Enure we dont return 0 or null for false values
3286
+ return !!(validateLongTap() && hasLongTap());
3287
+ }
3288
+
3289
+
3290
+
3291
+
3292
+ // MULTI FINGER TOUCH
3293
+ /**
3294
+ * Starts tracking the time between 2 finger releases, and keeps track of how many fingers we initially had up
3295
+ * @inner
3296
+ */
3297
+ function startMultiFingerRelease() {
3298
+ previousTouchEndTime = getTimeStamp();
3299
+ previousTouchFingerCount = event.touches.length+1;
3300
+ }
3301
+
3302
+ /**
3303
+ * Cancels the tracking of time between 2 finger releases, and resets counters
3304
+ * @inner
3305
+ */
3306
+ function cancelMultiFingerRelease() {
3307
+ previousTouchEndTime = 0;
3308
+ previousTouchFingerCount = 0;
3309
+ }
3310
+
3311
+ /**
3312
+ * Checks if we are in the threshold between 2 fingers being released
3313
+ * @return Boolean
3314
+ * @inner
3315
+ */
3316
+ function inMultiFingerRelease() {
3317
+
3318
+ var withinThreshold = false;
3319
+
3320
+ if(previousTouchEndTime) {
3321
+ var diff = getTimeStamp() - previousTouchEndTime
3322
+ if( diff<=options.fingerReleaseThreshold ) {
3323
+ withinThreshold = true;
3324
+ }
3325
+ }
3326
+
3327
+ return withinThreshold;
3328
+ }
3329
+
3330
+
3331
+ /**
3332
+ * gets a data flag to indicate that a touch is in progress
3333
+ * @return Boolean
3334
+ * @inner
3335
+ */
3336
+ function getTouchInProgress() {
3337
+ //strict equality to ensure only true and false are returned
3338
+ return !!($element.data(PLUGIN_NS+'_intouch') === true);
3339
+ }
3340
+
3341
+ /**
3342
+ * Sets a data flag to indicate that a touch is in progress
3343
+ * @param {boolean} val The value to set the property to
3344
+ * @inner
3345
+ */
3346
+ function setTouchInProgress(val) {
3347
+
3348
+ //Add or remove event listeners depending on touch status
3349
+ if(val===true) {
3350
+ $element.bind(MOVE_EV, touchMove);
3351
+ $element.bind(END_EV, touchEnd);
3352
+
3353
+ //we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit
3354
+ if(LEAVE_EV) {
3355
+ $element.bind(LEAVE_EV, touchLeave);
3356
+ }
3357
+ } else {
3358
+ $element.unbind(MOVE_EV, touchMove, false);
3359
+ $element.unbind(END_EV, touchEnd, false);
3360
+
3361
+ //we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit
3362
+ if(LEAVE_EV) {
3363
+ $element.unbind(LEAVE_EV, touchLeave, false);
3364
+ }
3365
+ }
3366
+
3367
+
3368
+ //strict equality to ensure only true and false can update the value
3369
+ $element.data(PLUGIN_NS+'_intouch', val === true);
3370
+ }
3371
+
3372
+
3373
+ /**
3374
+ * Creates the finger data for the touch/finger in the event object.
3375
+ * @param {int} index The index in the array to store the finger data (usually the order the fingers were pressed)
3376
+ * @param {object} evt The event object containing finger data
3377
+ * @return finger data object
3378
+ * @inner
3379
+ */
3380
+ function createFingerData( index, evt ) {
3381
+ var id = evt.identifier!==undefined ? evt.identifier : 0;
3382
+
3383
+ fingerData[index].identifier = id;
3384
+ fingerData[index].start.x = fingerData[index].end.x = evt.pageX||evt.clientX;
3385
+ fingerData[index].start.y = fingerData[index].end.y = evt.pageY||evt.clientY;
3386
+
3387
+ return fingerData[index];
3388
+ }
3389
+
3390
+ /**
3391
+ * Updates the finger data for a particular event object
3392
+ * @param {object} evt The event object containing the touch/finger data to upadte
3393
+ * @return a finger data object.
3394
+ * @inner
3395
+ */
3396
+ function updateFingerData(evt) {
3397
+
3398
+ var id = evt.identifier!==undefined ? evt.identifier : 0;
3399
+ var f = getFingerData( id );
3400
+
3401
+ f.end.x = evt.pageX||evt.clientX;
3402
+ f.end.y = evt.pageY||evt.clientY;
3403
+
3404
+ return f;
3405
+ }
3406
+
3407
+ /**
3408
+ * Returns a finger data object by its event ID.
3409
+ * Each touch event has an identifier property, which is used
3410
+ * to track repeat touches
3411
+ * @param {int} id The unique id of the finger in the sequence of touch events.
3412
+ * @return a finger data object.
3413
+ * @inner
3414
+ */
3415
+ function getFingerData( id ) {
3416
+ for(var i=0; i<fingerData.length; i++) {
3417
+ if(fingerData[i].identifier == id) {
3418
+ return fingerData[i];
3419
+ }
3420
+ }
3421
+ }
3422
+
3423
+ /**
3424
+ * Creats all the finger onjects and returns an array of finger data
3425
+ * @return Array of finger objects
3426
+ * @inner
3427
+ */
3428
+ function createAllFingerData() {
3429
+ var fingerData=[];
3430
+ for (var i=0; i<=5; i++) {
3431
+ fingerData.push({
3432
+ start:{ x: 0, y: 0 },
3433
+ end:{ x: 0, y: 0 },
3434
+ identifier:0
3435
+ });
3436
+ }
3437
+
3438
+ return fingerData;
3439
+ }
3440
+
3441
+ /**
3442
+ * Sets the maximum distance swiped in the given direction.
3443
+ * If the new value is lower than the current value, the max value is not changed.
3444
+ * @param {string} direction The direction of the swipe
3445
+ * @param {int} distance The distance of the swipe
3446
+ * @inner
3447
+ */
3448
+ function setMaxDistance(direction, distance) {
3449
+ distance = Math.max(distance, getMaxDistance(direction) );
3450
+ maximumsMap[direction].distance = distance;
3451
+ }
3452
+
3453
+ /**
3454
+ * gets the maximum distance swiped in the given direction.
3455
+ * @param {string} direction The direction of the swipe
3456
+ * @return int The distance of the swipe
3457
+ * @inner
3458
+ */
3459
+ function getMaxDistance(direction) {
3460
+ if (maximumsMap[direction]) return maximumsMap[direction].distance;
3461
+ return undefined;
3462
+ }
3463
+
3464
+ /**
3465
+ * Creats a map of directions to maximum swiped values.
3466
+ * @return Object A dictionary of maximum values, indexed by direction.
3467
+ * @inner
3468
+ */
3469
+ function createMaximumsData() {
3470
+ var maxData={};
3471
+ maxData[LEFT]=createMaximumVO(LEFT);
3472
+ maxData[RIGHT]=createMaximumVO(RIGHT);
3473
+ maxData[UP]=createMaximumVO(UP);
3474
+ maxData[DOWN]=createMaximumVO(DOWN);
3475
+
3476
+ return maxData;
3477
+ }
3478
+
3479
+ /**
3480
+ * Creates a map maximum swiped values for a given swipe direction
3481
+ * @param {string} The direction that these values will be associated with
3482
+ * @return Object Maximum values
3483
+ * @inner
3484
+ */
3485
+ function createMaximumVO(dir) {
3486
+ return {
3487
+ direction:dir,
3488
+ distance:0
3489
+ }
3490
+ }
3491
+
3492
+
3493
+ //
3494
+ // MATHS / UTILS
3495
+ //
3496
+
3497
+ /**
3498
+ * Calculate the duration of the swipe
3499
+ * @return int
3500
+ * @inner
3501
+ */
3502
+ function calculateDuration() {
3503
+ return endTime - startTime;
3504
+ }
3505
+
3506
+ /**
3507
+ * Calculate the distance between 2 touches (pinch)
3508
+ * @param {point} startPoint A point object containing x and y co-ordinates
3509
+ * @param {point} endPoint A point object containing x and y co-ordinates
3510
+ * @return int;
3511
+ * @inner
3512
+ */
3513
+ function calculateTouchesDistance(startPoint, endPoint) {
3514
+ var diffX = Math.abs(startPoint.x - endPoint.x);
3515
+ var diffY = Math.abs(startPoint.y - endPoint.y);
3516
+
3517
+ return Math.round(Math.sqrt(diffX*diffX+diffY*diffY));
3518
+ }
3519
+
3520
+ /**
3521
+ * Calculate the zoom factor between the start and end distances
3522
+ * @param {int} startDistance Distance (between 2 fingers) the user started pinching at
3523
+ * @param {int} endDistance Distance (between 2 fingers) the user ended pinching at
3524
+ * @return float The zoom value from 0 to 1.
3525
+ * @inner
3526
+ */
3527
+ function calculatePinchZoom(startDistance, endDistance) {
3528
+ var percent = (endDistance/startDistance) * 1;
3529
+ return percent.toFixed(2);
3530
+ }
3531
+
3532
+
3533
+ /**
3534
+ * Returns the pinch direction, either IN or OUT for the given points
3535
+ * @return string Either {@link $.fn.swipe.directions.IN} or {@link $.fn.swipe.directions.OUT}
3536
+ * @see $.fn.swipe.directions
3537
+ * @inner
3538
+ */
3539
+ function calculatePinchDirection() {
3540
+ if(pinchZoom<1) {
3541
+ return OUT;
3542
+ }
3543
+ else {
3544
+ return IN;
3545
+ }
3546
+ }
3547
+
3548
+
3549
+ /**
3550
+ * Calculate the length / distance of the swipe
3551
+ * @param {point} startPoint A point object containing x and y co-ordinates
3552
+ * @param {point} endPoint A point object containing x and y co-ordinates
3553
+ * @return int
3554
+ * @inner
3555
+ */
3556
+ function calculateDistance(startPoint, endPoint) {
3557
+ return Math.round(Math.sqrt(Math.pow(endPoint.x - startPoint.x, 2) + Math.pow(endPoint.y - startPoint.y, 2)));
3558
+ }
3559
+
3560
+ /**
3561
+ * Calculate the angle of the swipe
3562
+ * @param {point} startPoint A point object containing x and y co-ordinates
3563
+ * @param {point} endPoint A point object containing x and y co-ordinates
3564
+ * @return int
3565
+ * @inner
3566
+ */
3567
+ function calculateAngle(startPoint, endPoint) {
3568
+ var x = startPoint.x - endPoint.x;
3569
+ var y = endPoint.y - startPoint.y;
3570
+ var r = Math.atan2(y, x); //radians
3571
+ var angle = Math.round(r * 180 / Math.PI); //degrees
3572
+
3573
+ //ensure value is positive
3574
+ if (angle < 0) {
3575
+ angle = 360 - Math.abs(angle);
3576
+ }
3577
+
3578
+ return angle;
3579
+ }
3580
+
3581
+ /**
3582
+ * Calculate the direction of the swipe
3583
+ * This will also call calculateAngle to get the latest angle of swipe
3584
+ * @param {point} startPoint A point object containing x and y co-ordinates
3585
+ * @param {point} endPoint A point object containing x and y co-ordinates
3586
+ * @return string Either {@link $.fn.swipe.directions.LEFT} / {@link $.fn.swipe.directions.RIGHT} / {@link $.fn.swipe.directions.DOWN} / {@link $.fn.swipe.directions.UP}
3587
+ * @see $.fn.swipe.directions
3588
+ * @inner
3589
+ */
3590
+ function calculateDirection(startPoint, endPoint ) {
3591
+ var angle = calculateAngle(startPoint, endPoint);
3592
+
3593
+ if ((angle <= 45) && (angle >= 0)) {
3594
+ return LEFT;
3595
+ } else if ((angle <= 360) && (angle >= 315)) {
3596
+ return LEFT;
3597
+ } else if ((angle >= 135) && (angle <= 225)) {
3598
+ return RIGHT;
3599
+ } else if ((angle > 45) && (angle < 135)) {
3600
+ return DOWN;
3601
+ } else {
3602
+ return UP;
3603
+ }
3604
+ }
3605
+
3606
+
3607
+ /**
3608
+ * Returns a MS time stamp of the current time
3609
+ * @return int
3610
+ * @inner
3611
+ */
3612
+ function getTimeStamp() {
3613
+ var now = new Date();
3614
+ return now.getTime();
3615
+ }
3616
+
3617
+
3618
+
3619
+ /**
3620
+ * Returns a bounds object with left, right, top and bottom properties for the element specified.
3621
+ * @param {DomNode} The DOM node to get the bounds for.
3622
+ */
3623
+ function getbounds( el ) {
3624
+ el = $(el);
3625
+ var offset = el.offset();
3626
+
3627
+ var bounds = {
3628
+ left:offset.left,
3629
+ right:offset.left+el.outerWidth(),
3630
+ top:offset.top,
3631
+ bottom:offset.top+el.outerHeight()
3632
+ }
3633
+
3634
+ return bounds;
3635
+ }
3636
+
3637
+
3638
+ /**
3639
+ * Checks if the point object is in the bounds object.
3640
+ * @param {object} point A point object.
3641
+ * @param {int} point.x The x value of the point.
3642
+ * @param {int} point.y The x value of the point.
3643
+ * @param {object} bounds The bounds object to test
3644
+ * @param {int} bounds.left The leftmost value
3645
+ * @param {int} bounds.right The righttmost value
3646
+ * @param {int} bounds.top The topmost value
3647
+ * @param {int} bounds.bottom The bottommost value
3648
+ */
3649
+ function isInBounds(point, bounds) {
3650
+ return (point.x > bounds.left && point.x < bounds.right && point.y > bounds.top && point.y < bounds.bottom);
3651
+ };
3652
+
3653
+
3654
+ }
3655
+
3656
+
3657
+
3658
+
3659
+ /**
3660
+ * A catch all handler that is triggered for all swipe directions.
3661
+ * @name $.fn.swipe#swipe
3662
+ * @event
3663
+ * @default null
3664
+ * @param {EventObject} event The original event object
3665
+ * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
3666
+ * @param {int} distance The distance the user swiped
3667
+ * @param {int} duration The duration of the swipe in milliseconds
3668
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
3669
+ * @param {object} fingerData The coordinates of fingers in event
3670
+ */
3671
+
3672
+
3673
+
3674
+
3675
+ /**
3676
+ * A handler that is triggered for "left" swipes.
3677
+ * @name $.fn.swipe#swipeLeft
3678
+ * @event
3679
+ * @default null
3680
+ * @param {EventObject} event The original event object
3681
+ * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
3682
+ * @param {int} distance The distance the user swiped
3683
+ * @param {int} duration The duration of the swipe in milliseconds
3684
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
3685
+ * @param {object} fingerData The coordinates of fingers in event
3686
+ */
3687
+
3688
+ /**
3689
+ * A handler that is triggered for "right" swipes.
3690
+ * @name $.fn.swipe#swipeRight
3691
+ * @event
3692
+ * @default null
3693
+ * @param {EventObject} event The original event object
3694
+ * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
3695
+ * @param {int} distance The distance the user swiped
3696
+ * @param {int} duration The duration of the swipe in milliseconds
3697
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
3698
+ * @param {object} fingerData The coordinates of fingers in event
3699
+ */
3700
+
3701
+ /**
3702
+ * A handler that is triggered for "up" swipes.
3703
+ * @name $.fn.swipe#swipeUp
3704
+ * @event
3705
+ * @default null
3706
+ * @param {EventObject} event The original event object
3707
+ * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
3708
+ * @param {int} distance The distance the user swiped
3709
+ * @param {int} duration The duration of the swipe in milliseconds
3710
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
3711
+ * @param {object} fingerData The coordinates of fingers in event
3712
+ */
3713
+
3714
+ /**
3715
+ * A handler that is triggered for "down" swipes.
3716
+ * @name $.fn.swipe#swipeDown
3717
+ * @event
3718
+ * @default null
3719
+ * @param {EventObject} event The original event object
3720
+ * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
3721
+ * @param {int} distance The distance the user swiped
3722
+ * @param {int} duration The duration of the swipe in milliseconds
3723
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
3724
+ * @param {object} fingerData The coordinates of fingers in event
3725
+ */
3726
+
3727
+ /**
3728
+ * A handler triggered for every phase of the swipe. This handler is constantly fired for the duration of the pinch.
3729
+ * This is triggered regardless of swipe thresholds.
3730
+ * @name $.fn.swipe#swipeStatus
3731
+ * @event
3732
+ * @default null
3733
+ * @param {EventObject} event The original event object
3734
+ * @param {string} phase The phase of the swipe event. See {@link $.fn.swipe.phases}
3735
+ * @param {string} direction The direction the user swiped in. This is null if the user has yet to move. See {@link $.fn.swipe.directions}
3736
+ * @param {int} distance The distance the user swiped. This is 0 if the user has yet to move.
3737
+ * @param {int} duration The duration of the swipe in milliseconds
3738
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
3739
+ * @param {object} fingerData The coordinates of fingers in event
3740
+ */
3741
+
3742
+ /**
3743
+ * A handler triggered for pinch in events.
3744
+ * @name $.fn.swipe#pinchIn
3745
+ * @event
3746
+ * @default null
3747
+ * @param {EventObject} event The original event object
3748
+ * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
3749
+ * @param {int} distance The distance the user pinched
3750
+ * @param {int} duration The duration of the swipe in milliseconds
3751
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
3752
+ * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
3753
+ * @param {object} fingerData The coordinates of fingers in event
3754
+ */
3755
+
3756
+ /**
3757
+ * A handler triggered for pinch out events.
3758
+ * @name $.fn.swipe#pinchOut
3759
+ * @event
3760
+ * @default null
3761
+ * @param {EventObject} event The original event object
3762
+ * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
3763
+ * @param {int} distance The distance the user pinched
3764
+ * @param {int} duration The duration of the swipe in milliseconds
3765
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
3766
+ * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
3767
+ * @param {object} fingerData The coordinates of fingers in event
3768
+ */
3769
+
3770
+ /**
3771
+ * A handler triggered for all pinch events. This handler is constantly fired for the duration of the pinch. This is triggered regardless of thresholds.
3772
+ * @name $.fn.swipe#pinchStatus
3773
+ * @event
3774
+ * @default null
3775
+ * @param {EventObject} event The original event object
3776
+ * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
3777
+ * @param {int} distance The distance the user pinched
3778
+ * @param {int} duration The duration of the swipe in milliseconds
3779
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
3780
+ * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
3781
+ * @param {object} fingerData The coordinates of fingers in event
3782
+ */
3783
+
3784
+ /**
3785
+ * A click handler triggered when a user simply clicks, rather than swipes on an element.
3786
+ * This is deprecated since version 1.6.2, any assignment to click will be assigned to the tap handler.
3787
+ * You cannot use <code>on</code> to bind to this event as the default jQ <code>click</code> event will be triggered.
3788
+ * Use the <code>tap</code> event instead.
3789
+ * @name $.fn.swipe#click
3790
+ * @event
3791
+ * @deprecated since version 1.6.2, please use {@link $.fn.swipe#tap} instead
3792
+ * @default null
3793
+ * @param {EventObject} event The original event object
3794
+ * @param {DomObject} target The element clicked on.
3795
+ */
3796
+
3797
+ /**
3798
+ * A click / tap handler triggered when a user simply clicks or taps, rather than swipes on an element.
3799
+ * @name $.fn.swipe#tap
3800
+ * @event
3801
+ * @default null
3802
+ * @param {EventObject} event The original event object
3803
+ * @param {DomObject} target The element clicked on.
3804
+ */
3805
+
3806
+ /**
3807
+ * A double tap handler triggered when a user double clicks or taps on an element.
3808
+ * You can set the time delay for a double tap with the {@link $.fn.swipe.defaults#doubleTapThreshold} property.
3809
+ * Note: If you set both <code>doubleTap</code> and <code>tap</code> handlers, the <code>tap</code> event will be delayed by the <code>doubleTapThreshold</code>
3810
+ * as the script needs to check if its a double tap.
3811
+ * @name $.fn.swipe#doubleTap
3812
+ * @see $.fn.swipe.defaults#doubleTapThreshold
3813
+ * @event
3814
+ * @default null
3815
+ * @param {EventObject} event The original event object
3816
+ * @param {DomObject} target The element clicked on.
3817
+ */
3818
+
3819
+ /**
3820
+ * A long tap handler triggered once a tap has been release if the tap was longer than the longTapThreshold.
3821
+ * You can set the time delay for a long tap with the {@link $.fn.swipe.defaults#longTapThreshold} property.
3822
+ * @name $.fn.swipe#longTap
3823
+ * @see $.fn.swipe.defaults#longTapThreshold
3824
+ * @event
3825
+ * @default null
3826
+ * @param {EventObject} event The original event object
3827
+ * @param {DomObject} target The element clicked on.
3828
+ */
3829
+
3830
+ /**
3831
+ * A hold tap handler triggered as soon as the longTapThreshold is reached
3832
+ * You can set the time delay for a long tap with the {@link $.fn.swipe.defaults#longTapThreshold} property.
3833
+ * @name $.fn.swipe#hold
3834
+ * @see $.fn.swipe.defaults#longTapThreshold
3835
+ * @event
3836
+ * @default null
3837
+ * @param {EventObject} event The original event object
3838
+ * @param {DomObject} target The element clicked on.
3839
+ */
3840
+
3841
+ }));
3842
+
3843
+ /*!
3844
+ * jQuery Mousewheel 3.1.12
3845
+ *
3846
+ * Copyright 2014 jQuery Foundation and other contributors
3847
+ * Released under the MIT license.
3848
+ * http://jquery.org/license
3849
+ */
3850
+
3851
+ (function (factory) {
3852
+ if ( typeof define === 'function' && define.amd ) {
3853
+ // AMD. Register as an anonymous module.
3854
+ define(['jquery'], factory);
3855
+ } else if (typeof exports === 'object') {
3856
+ // Node/CommonJS style for Browserify
3857
+ module.exports = factory;
3858
+ } else {
3859
+ // Browser globals
3860
+ factory(jQuery);
3861
+ }
3862
+ }(function ($) {
3863
+
3864
+ var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
3865
+ toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
3866
+ ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
3867
+ slice = Array.prototype.slice,
3868
+ nullLowestDeltaTimeout, lowestDelta;
3869
+
3870
+ if ( $.event.fixHooks ) {
3871
+ for ( var i = toFix.length; i; ) {
3872
+ $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
3873
+ }
3874
+ }
3875
+
3876
+ var special = $.event.special.mousewheel = {
3877
+ version: '3.1.12',
3878
+
3879
+ setup: function() {
3880
+ if ( this.addEventListener ) {
3881
+ for ( var i = toBind.length; i; ) {
3882
+ this.addEventListener( toBind[--i], handler, false );
3883
+ }
3884
+ } else {
3885
+ this.onmousewheel = handler;
3886
+ }
3887
+ // Store the line height and page height for this particular element
3888
+ $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
3889
+ $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
3890
+ },
3891
+
3892
+ teardown: function() {
3893
+ if ( this.removeEventListener ) {
3894
+ for ( var i = toBind.length; i; ) {
3895
+ this.removeEventListener( toBind[--i], handler, false );
3896
+ }
3897
+ } else {
3898
+ this.onmousewheel = null;
3899
+ }
3900
+ // Clean up the data we added to the element
3901
+ $.removeData(this, 'mousewheel-line-height');
3902
+ $.removeData(this, 'mousewheel-page-height');
3903
+ },
3904
+
3905
+ getLineHeight: function(elem) {
3906
+ var $elem = $(elem),
3907
+ $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
3908
+ if (!$parent.length) {
3909
+ $parent = $('body');
3910
+ }
3911
+ return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
3912
+ },
3913
+
3914
+ getPageHeight: function(elem) {
3915
+ return $(elem).height();
3916
+ },
3917
+
3918
+ settings: {
3919
+ adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
3920
+ normalizeOffset: true // calls getBoundingClientRect for each event
3921
+ }
3922
+ };
3923
+
3924
+ $.fn.extend({
3925
+ mousewheel: function(fn) {
3926
+ return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
3927
+ },
3928
+
3929
+ unmousewheel: function(fn) {
3930
+ return this.unbind('mousewheel', fn);
3931
+ }
3932
+ });
3933
+
3934
+
3935
+ function handler(event) {
3936
+ var orgEvent = event || window.event,
3937
+ args = slice.call(arguments, 1),
3938
+ delta = 0,
3939
+ deltaX = 0,
3940
+ deltaY = 0,
3941
+ absDelta = 0,
3942
+ offsetX = 0,
3943
+ offsetY = 0;
3944
+ event = $.event.fix(orgEvent);
3945
+ event.type = 'mousewheel';
3946
+
3947
+ // Old school scrollwheel delta
3948
+ if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
3949
+ if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
3950
+ if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
3951
+ if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
3952
+
3953
+ // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
3954
+ if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
3955
+ deltaX = deltaY * -1;
3956
+ deltaY = 0;
3957
+ }
3958
+
3959
+ // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
3960
+ delta = deltaY === 0 ? deltaX : deltaY;
3961
+
3962
+ // New school wheel delta (wheel event)
3963
+ if ( 'deltaY' in orgEvent ) {
3964
+ deltaY = orgEvent.deltaY * -1;
3965
+ delta = deltaY;
3966
+ }
3967
+ if ( 'deltaX' in orgEvent ) {
3968
+ deltaX = orgEvent.deltaX;
3969
+ if ( deltaY === 0 ) { delta = deltaX * -1; }
3970
+ }
3971
+
3972
+ // No change actually happened, no reason to go any further
3973
+ if ( deltaY === 0 && deltaX === 0 ) { return; }
3974
+
3975
+ // Need to convert lines and pages to pixels if we aren't already in pixels
3976
+ // There are three delta modes:
3977
+ // * deltaMode 0 is by pixels, nothing to do
3978
+ // * deltaMode 1 is by lines
3979
+ // * deltaMode 2 is by pages
3980
+ if ( orgEvent.deltaMode === 1 ) {
3981
+ var lineHeight = $.data(this, 'mousewheel-line-height');
3982
+ delta *= lineHeight;
3983
+ deltaY *= lineHeight;
3984
+ deltaX *= lineHeight;
3985
+ } else if ( orgEvent.deltaMode === 2 ) {
3986
+ var pageHeight = $.data(this, 'mousewheel-page-height');
3987
+ delta *= pageHeight;
3988
+ deltaY *= pageHeight;
3989
+ deltaX *= pageHeight;
3990
+ }
3991
+
3992
+ // Store lowest absolute delta to normalize the delta values
3993
+ absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
3994
+
3995
+ if ( !lowestDelta || absDelta < lowestDelta ) {
3996
+ lowestDelta = absDelta;
3997
+
3998
+ // Adjust older deltas if necessary
3999
+ if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
4000
+ lowestDelta /= 40;
4001
+ }
4002
+ }
4003
+
4004
+ // Adjust older deltas if necessary
4005
+ if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
4006
+ // Divide all the things by 40!
4007
+ delta /= 40;
4008
+ deltaX /= 40;
4009
+ deltaY /= 40;
4010
+ }
4011
+
4012
+ // Get a whole, normalized value for the deltas
4013
+ delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
4014
+ deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
4015
+ deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
4016
+
4017
+ // Normalise offsetX and offsetY properties
4018
+ if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
4019
+ var boundingRect = this.getBoundingClientRect();
4020
+ offsetX = event.clientX - boundingRect.left;
4021
+ offsetY = event.clientY - boundingRect.top;
4022
+ }
4023
+
4024
+ // Add information to the event object
4025
+ event.deltaX = deltaX;
4026
+ event.deltaY = deltaY;
4027
+ event.deltaFactor = lowestDelta;
4028
+ event.offsetX = offsetX;
4029
+ event.offsetY = offsetY;
4030
+ // Go ahead and set deltaMode to 0 since we converted to pixels
4031
+ // Although this is a little odd since we overwrite the deltaX/Y
4032
+ // properties with normalized deltas.
4033
+ event.deltaMode = 0;
4034
+
4035
+ // Add event and delta to the front of the arguments
4036
+ args.unshift(event, delta, deltaX, deltaY);
4037
+
4038
+ // Clearout lowestDelta after sometime to better
4039
+ // handle multiple device types that give different
4040
+ // a different lowestDelta
4041
+ // Ex: trackpad = 3 and mouse wheel = 120
4042
+ if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
4043
+ nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
4044
+
4045
+ return ($.event.dispatch || $.event.handle).apply(this, args);
4046
+ }
4047
+
4048
+ function nullLowestDelta() {
4049
+ lowestDelta = null;
4050
+ }
4051
+
4052
+ function shouldAdjustOldDeltas(orgEvent, absDelta) {
4053
+ // If this is an older event and the delta is divisable by 120,
4054
+ // then we are assuming that the browser is treating this as an
4055
+ // older mouse wheel event and that we should divide the deltas
4056
+ // by 40 to try and get a more usable deltaFactor.
4057
+ // Side note, this actually impacts the reported scroll distance
4058
+ // in older browsers and can cause scrolling to be slower than native.
4059
+ // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
4060
+ return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
4061
+ }
4062
+
4063
+ }));
4064
+
4065
+ /**
4066
+ * enviraImagesLoaded PACKAGED v4.1.0
4067
+ * JavaScript is all like "You images are done yet or what?"
4068
+ * MIT License
4069
+ */
4070
+
4071
+ /**
4072
+ * EvEmitter v1.0.1
4073
+ * Lil' event emitter
4074
+ * MIT License
4075
+ */
4076
+
4077
+ /* jshint unused: true, undef: true, strict: true */
4078
+
4079
+ ( function( global, factory ) {
4080
+ // universal module definition
4081
+ /* jshint strict: false */ /* globals define, module */
4082
+ if ( typeof define == 'function' && define.amd ) {
4083
+ // AMD - RequireJS
4084
+ define( 'ev-emitter/ev-emitter',factory );
4085
+ } else if ( typeof module == 'object' && module.exports ) {
4086
+ // CommonJS - Browserify, Webpack
4087
+ module.exports = factory();
4088
+ } else {
4089
+ // Browser globals
4090
+ global.EvEmitter = factory();
4091
+ }
4092
+
4093
+ }( this, function() {
4094
+
4095
+
4096
+
4097
+ function EvEmitter() {}
4098
+
4099
+ var proto = EvEmitter.prototype;
4100
+
4101
+ proto.on = function( eventName, listener ) {
4102
+ if ( !eventName || !listener ) {
4103
+ return;
4104
+ }
4105
+ // set events hash
4106
+ var events = this._events = this._events || {};
4107
+ // set listeners array
4108
+ var listeners = events[ eventName ] = events[ eventName ] || [];
4109
+ // only add once
4110
+ if ( listeners.indexOf( listener ) == -1 ) {
4111
+ listeners.push( listener );
4112
+ }
4113
+
4114
+ return this;
4115
+ };
4116
+
4117
+ proto.once = function( eventName, listener ) {
4118
+ if ( !eventName || !listener ) {
4119
+ return;
4120
+ }
4121
+ // add event
4122
+ this.on( eventName, listener );
4123
+ // set once flag
4124
+ // set onceEvents hash
4125
+ var onceEvents = this._onceEvents = this._onceEvents || {};
4126
+ // set onceListeners array
4127
+ var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || [];
4128
+ // set flag
4129
+ onceListeners[ listener ] = true;
4130
+
4131
+ return this;
4132
+ };
4133
+
4134
+ proto.off = function( eventName, listener ) {
4135
+ var listeners = this._events && this._events[ eventName ];
4136
+ if ( !listeners || !listeners.length ) {
4137
+ return;
4138
+ }
4139
+ var index = listeners.indexOf( listener );
4140
+ if ( index != -1 ) {
4141
+ listeners.splice( index, 1 );
4142
+ }
4143
+
4144
+ return this;
4145
+ };
4146
+
4147
+ proto.emitEvent = function( eventName, args ) {
4148
+ var listeners = this._events && this._events[ eventName ];
4149
+ if ( !listeners || !listeners.length ) {
4150
+ return;
4151
+ }
4152
+ var i = 0;
4153
+ var listener = listeners[i];
4154
+ args = args || [];
4155
+ // once stuff
4156
+ var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
4157
+
4158
+ while ( listener ) {
4159
+ var isOnce = onceListeners && onceListeners[ listener ];
4160
+ if ( isOnce ) {
4161
+ // remove listener
4162
+ // remove before trigger to prevent recursion
4163
+ this.off( eventName, listener );
4164
+ // unset once flag
4165
+ delete onceListeners[ listener ];
4166
+ }
4167
+ // trigger listener
4168
+ listener.apply( this, args );
4169
+ // get next listener
4170
+ i += isOnce ? 0 : 1;
4171
+ listener = listeners[i];
4172
+ }
4173
+
4174
+ return this;
4175
+ };
4176
+
4177
+ return EvEmitter;
4178
+
4179
+ }));
4180
+
4181
+ /*!
4182
+ * enviraImagesLoaded v4.1.0
4183
+ * JavaScript is all like "You images are done yet or what?"
4184
+ * MIT License
4185
+ */
4186
+
4187
+ ( function( window, factory ) { 'use strict';
4188
+ // universal module definition
4189
+
4190
+ /*global define: false, module: false, require: false */
4191
+
4192
+ if ( typeof define == 'function' && define.amd ) {
4193
+ // AMD
4194
+ define( [
4195
+ 'ev-emitter/ev-emitter'
4196
+ ], function( EvEmitter ) {
4197
+ return factory( window, EvEmitter );
4198
+ });
4199
+ } else if ( typeof module == 'object' && module.exports ) {
4200
+ // CommonJS
4201
+ module.exports = factory(
4202
+ window,
4203
+ require('ev-emitter')
4204
+ );
4205
+ } else {
4206
+ // browser global
4207
+ window.enviraImagesLoaded = factory(
4208
+ window,
4209
+ window.EvEmitter
4210
+ );
4211
+ }
4212
+
4213
+ })( window,
4214
+
4215
+ // -------------------------- factory -------------------------- //
4216
+
4217
+ function factory( window, EvEmitter ) {
4218
+
4219
+
4220
+
4221
+ var $ = window.jQuery;
4222
+ var console = window.console;
4223
+
4224
+ // -------------------------- helpers -------------------------- //
4225
+
4226
+ // extend objects
4227
+ function extend( a, b ) {
4228
+ for ( var prop in b ) {
4229
+ a[ prop ] = b[ prop ];
4230
+ }
4231
+ return a;
4232
+ }
4233
+
4234
+ // turn element or nodeList into an array
4235
+ function makeArray( obj ) {
4236
+ var ary = [];
4237
+ if ( Array.isArray( obj ) ) {
4238
+ // use object if already an array
4239
+ ary = obj;
4240
+ } else if ( typeof obj.length == 'number' ) {
4241
+ // convert nodeList to array
4242
+ for ( var i=0; i < obj.length; i++ ) {
4243
+ ary.push( obj[i] );
4244
+ }
4245
+ } else {
4246
+ // array of single index
4247
+ ary.push( obj );
4248
+ }
4249
+ return ary;
4250
+ }
4251
+
4252
+ // -------------------------- enviraImagesLoaded -------------------------- //
4253
+
4254
+ /**
4255
+ * @param {Array, Element, NodeList, String} elem
4256
+ * @param {Object or Function} options - if function, use as callback
4257
+ * @param {Function} onAlways - callback function
4258
+ */
4259
+ function EnviraImagesLoaded( elem, options, onAlways ) {
4260
+ // coerce EnviraImagesLoaded() without new, to be new EnviraImagesLoaded()
4261
+ if ( !( this instanceof EnviraImagesLoaded ) ) {
4262
+ return new EnviraImagesLoaded( elem, options, onAlways );
4263
+ }
4264
+ // use elem as selector string
4265
+ if ( typeof elem == 'string' ) {
4266
+ elem = document.querySelectorAll( elem );
4267
+ }
4268
+
4269
+ this.elements = makeArray( elem );
4270
+ this.options = extend( {}, this.options );
4271
+
4272
+ if ( typeof options == 'function' ) {
4273
+ onAlways = options;
4274
+ } else {
4275
+ extend( this.options, options );
4276
+ }
4277
+
4278
+ if ( onAlways ) {
4279
+ this.on( 'always', onAlways );
4280
+ }
4281
+
4282
+ this.getImages();
4283
+
4284
+ if ( $ ) {
4285
+ // add jQuery Deferred object
4286
+ this.jqDeferred = new $.Deferred();
4287
+ }
4288
+
4289
+ // HACK check async to allow time to bind listeners
4290
+ setTimeout( function() {
4291
+ this.check();
4292
+ }.bind( this ));
4293
+ }
4294
+
4295
+ EnviraImagesLoaded.prototype = Object.create( EvEmitter.prototype );
4296
+
4297
+ EnviraImagesLoaded.prototype.options = {};
4298
+
4299
+ EnviraImagesLoaded.prototype.getImages = function() {
4300
+ this.images = [];
4301
+
4302
+ // filter & find items if we have an item selector
4303
+ this.elements.forEach( this.addElementImages, this );
4304
+ };
4305
+
4306
+ /**
4307
+ * @param {Node} element
4308
+ */
4309
+ EnviraImagesLoaded.prototype.addElementImages = function( elem ) {
4310
+ // filter siblings
4311
+ if ( elem.nodeName == 'IMG' ) {
4312
+ this.addImage( elem );
4313
+ }
4314
+ // get background image on element
4315
+ if ( this.options.background === true ) {
4316
+ this.addElementBackgroundImages( elem );
4317
+ }
4318
+
4319
+ // find children
4320
+ // no non-element nodes, #143
4321
+ var nodeType = elem.nodeType;
4322
+ if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
4323
+ return;
4324
+ }
4325
+ var childImgs = elem.querySelectorAll('img');
4326
+ // concat childElems to filterFound array
4327
+ for ( var i=0; i < childImgs.length; i++ ) {
4328
+ var img = childImgs[i];
4329
+ this.addImage( img );
4330
+ }
4331
+
4332
+ // get child background images
4333
+ if ( typeof this.options.background == 'string' ) {
4334
+ var children = elem.querySelectorAll( this.options.background );
4335
+ for ( i=0; i < children.length; i++ ) {
4336
+ var child = children[i];
4337
+ this.addElementBackgroundImages( child );
4338
+ }
4339
+ }
4340
+ };
4341
+
4342
+ var elementNodeTypes = {
4343
+ 1: true,
4344
+ 9: true,
4345
+ 11: true
4346
+ };
4347
+
4348
+ EnviraImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
4349
+ var style = getComputedStyle( elem );
4350
+ if ( !style ) {
4351
+ // Firefox returns null if in a hidden iframe https://bugzil.la/548397
4352
+ return;
4353
+ }
4354
+ // get url inside url("...")
4355
+ var reURL = /url\((['"])?(.*?)\1\)/gi;
4356
+ var matches = reURL.exec( style.backgroundImage );
4357
+ while ( matches !== null ) {
4358
+ var url = matches && matches[2];
4359
+ if ( url ) {
4360
+ this.addBackground( url, elem );
4361
+ }
4362
+ matches = reURL.exec( style.backgroundImage );
4363
+ }
4364
+ };
4365
+
4366
+ /**
4367
+ * @param {Image} img
4368
+ */
4369
+ EnviraImagesLoaded.prototype.addImage = function( img ) {
4370
+ var loadingImage = new LoadingImage( img );
4371
+ this.images.push( loadingImage );
4372
+ };
4373
+
4374
+ EnviraImagesLoaded.prototype.addBackground = function( url, elem ) {
4375
+ var background = new Background( url, elem );
4376
+ this.images.push( background );
4377
+ };
4378
+
4379
+ EnviraImagesLoaded.prototype.check = function() {
4380
+ var _this = this;
4381
+ this.progressedCount = 0;
4382
+ this.hasAnyBroken = false;
4383
+ // complete if no images
4384
+ if ( !this.images.length ) {
4385
+ this.complete();
4386
+ return;
4387
+ }
4388
+
4389
+ function onProgress( image, elem, message ) {
4390
+ // HACK - Chrome triggers event before object properties have changed. #83
4391
+ setTimeout( function() {
4392
+ _this.progress( image, elem, message );
4393
+ });
4394
+ }
4395
+
4396
+ this.images.forEach( function( loadingImage ) {
4397
+ loadingImage.once( 'progress', onProgress );
4398
+ loadingImage.check();
4399
+ });
4400
+ };
4401
+
4402
+ EnviraImagesLoaded.prototype.progress = function( image, elem, message ) {
4403
+ this.progressedCount++;
4404
+ this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
4405
+ // progress event
4406
+ this.emitEvent( 'progress', [ this, image, elem ] );
4407
+ if ( this.jqDeferred && this.jqDeferred.notify ) {
4408
+ this.jqDeferred.notify( this, image );
4409
+ }
4410
+ // check if completed
4411
+ if ( this.progressedCount == this.images.length ) {
4412
+ this.complete();
4413
+ }
4414
+
4415
+ if ( this.options.debug && console ) {
4416
+ console.log( 'progress: ' + message, image, elem );
4417
+ }
4418
+ };
4419
+
4420
+ EnviraImagesLoaded.prototype.complete = function() {
4421
+ var eventName = this.hasAnyBroken ? 'fail' : 'done';
4422
+ this.isComplete = true;
4423
+ this.emitEvent( eventName, [ this ] );
4424
+ this.emitEvent( 'always', [ this ] );
4425
+ if ( this.jqDeferred ) {
4426
+ var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
4427
+ this.jqDeferred[ jqMethod ]( this );
4428
+ }
4429
+ };
4430
+
4431
+ // -------------------------- -------------------------- //
4432
+
4433
+ function LoadingImage( img ) {
4434
+ this.img = img;
4435
+ }
4436
+
4437
+ LoadingImage.prototype = Object.create( EvEmitter.prototype );
4438
+
4439
+ LoadingImage.prototype.check = function() {
4440
+ // If complete is true and browser supports natural sizes,
4441
+ // try to check for image status manually.
4442
+ var isComplete = this.getIsImageComplete();
4443
+ if ( isComplete ) {
4444
+ // report based on naturalWidth
4445
+ this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
4446
+ return;
4447
+ }
4448
+
4449
+ // If none of the checks above matched, simulate loading on detached element.
4450
+ this.proxyImage = new Image();
4451
+ this.proxyImage.addEventListener( 'load', this );
4452
+ this.proxyImage.addEventListener( 'error', this );
4453
+ // bind to image as well for Firefox. #191
4454
+ this.img.addEventListener( 'load', this );
4455
+ this.img.addEventListener( 'error', this );
4456
+ this.proxyImage.src = this.img.src;
4457
+ };
4458
+
4459
+ LoadingImage.prototype.getIsImageComplete = function() {
4460
+ return this.img.complete && this.img.naturalWidth !== undefined;
4461
+ };
4462
+
4463
+ LoadingImage.prototype.confirm = function( isLoaded, message ) {
4464
+ this.isLoaded = isLoaded;
4465
+ this.emitEvent( 'progress', [ this, this.img, message ] );
4466
+ };
4467
+
4468
+ // ----- events ----- //
4469
+
4470
+ // trigger specified handler for event type
4471
+ LoadingImage.prototype.handleEvent = function( event ) {
4472
+ var method = 'on' + event.type;
4473
+ if ( this[ method ] ) {
4474
+ this[ method ]( event );
4475
+ }
4476
+ };
4477
+
4478
+ LoadingImage.prototype.onload = function() {
4479
+ this.confirm( true, 'onload' );
4480
+ this.unbindEvents();
4481
+ };
4482
+
4483
+ LoadingImage.prototype.onerror = function() {
4484
+ this.confirm( false, 'onerror' );
4485
+ this.unbindEvents();
4486
+ };
4487
+
4488
+ LoadingImage.prototype.unbindEvents = function() {
4489
+ this.proxyImage.removeEventListener( 'load', this );
4490
+ this.proxyImage.removeEventListener( 'error', this );
4491
+ this.img.removeEventListener( 'load', this );
4492
+ this.img.removeEventListener( 'error', this );
4493
+ };
4494
+
4495
+ // -------------------------- Background -------------------------- //
4496
+
4497
+ function Background( url, element ) {
4498
+ this.url = url;
4499
+ this.element = element;
4500
+ this.img = new Image();
4501
+ }
4502
+
4503
+ // inherit LoadingImage prototype
4504
+ Background.prototype = Object.create( LoadingImage.prototype );
4505
+
4506
+ Background.prototype.check = function() {
4507
+ this.img.addEventListener( 'load', this );
4508
+ this.img.addEventListener( 'error', this );
4509
+ this.img.src = this.url;
4510
+ // check if image is already complete
4511
+ var isComplete = this.getIsImageComplete();
4512
+ if ( isComplete ) {
4513
+ this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
4514
+ this.unbindEvents();
4515
+ }
4516
+ };
4517
+
4518
+ Background.prototype.unbindEvents = function() {
4519
+ this.img.removeEventListener( 'load', this );
4520
+ this.img.removeEventListener( 'error', this );
4521
+ };
4522
+
4523
+ Background.prototype.confirm = function( isLoaded, message ) {
4524
+ this.isLoaded = isLoaded;
4525
+ this.emitEvent( 'progress', [ this, this.element, message ] );
4526
+ };
4527
+
4528
+ // -------------------------- jQuery -------------------------- //
4529
+
4530
+ EnviraImagesLoaded.makeJQueryPlugin = function( jQuery ) {
4531
+ jQuery = jQuery || window.jQuery;
4532
+ if ( !jQuery ) {
4533
+ return;
4534
+ }
4535
+ // set local variable
4536
+ $ = jQuery;
4537
+ // $().enviraImagesLoaded()
4538
+ $.fn.enviraImagesLoaded = function( options, callback ) {
4539
+ var instance = new EnviraImagesLoaded( this, options, callback );
4540
+ return instance.jqDeferred.promise( $(this) );
4541
+ };
4542
+ };
4543
+ // try making plugin
4544
+ EnviraImagesLoaded.makeJQueryPlugin();
4545
+
4546
+ // -------------------------- -------------------------- //
4547
+
4548
+ return EnviraImagesLoaded;
4549
+
4550
+ });
4551
+
4552
+
4553
+ /*!
4554
+ * Enviratope PACKAGED v3.0.0
4555
+ *
4556
+ * Licensed GPLv3 for open source use
4557
+ * or Enviratope Commercial License for commercial use
4558
+ *
4559
+ * http://enviratope.metafizzy.co
4560
+ * Copyright 2016 Metafizzy
4561
+ */
4562
+
4563
+ /**
4564
+ * Bridget makes jQuery widgets
4565
+ * v2.0.0
4566
+ * MIT license
4567
+ */
4568
+
4569
+ /* jshint browser: true, strict: true, undef: true, unused: true */
4570
+
4571
+ ( function( window, factory ) {
4572
+ 'use strict';
4573
+ /* globals define: false, module: false, require: false */
4574
+
4575
+ if ( typeof define == 'function' && define.amd ) {
4576
+ // AMD
4577
+ define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {
4578
+ factory( window, jQuery );
4579
+ });
4580
+ } else if ( typeof module == 'object' && module.exports ) {
4581
+ // CommonJS
4582
+ module.exports = factory(
4583
+ window,
4584
+ require('jquery')
4585
+ );
4586
+ } else {
4587
+ // browser global
4588
+ window.jQueryBridget = factory(
4589
+ window,
4590
+ window.jQuery
4591
+ );
4592
+ }
4593
+
4594
+ }( window, function factory( window, jQuery ) {
4595
+ 'use strict';
4596
+
4597
+ // ----- utils ----- //
4598
+
4599
+ var arraySlice = Array.prototype.slice;
4600
+
4601
+ // helper function for logging errors
4602
+ // $.error breaks jQuery chaining
4603
+ var console = window.console;
4604
+ var logError = typeof console == 'undefined' ? function() {} :
4605
+ function( message ) {
4606
+ console.error( message );
4607
+ };
4608
+
4609
+ // ----- jQueryBridget ----- //
4610
+
4611
+ function jQueryBridget( namespace, PluginClass, $ ) {
4612
+ $ = $ || jQuery || window.jQuery;
4613
+ if ( !$ ) {
4614
+ return;
4615
+ }
4616
+
4617
+ // add option method -> $().plugin('option', {...})
4618
+ if ( !PluginClass.prototype.option ) {
4619
+ // option setter
4620
+ PluginClass.prototype.option = function( opts ) {
4621
+ // bail out if not an object
4622
+ if ( !$.isPlainObject( opts ) ){
4623
+ return;
4624
+ }
4625
+ this.options = $.extend( true, this.options, opts );
4626
+ };
4627
+ }
4628
+
4629
+ // make jQuery plugin
4630
+ $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {
4631
+ if ( typeof arg0 == 'string' ) {
4632
+ // method call $().plugin( 'methodName', { options } )
4633
+ // shift arguments by 1
4634
+ var args = arraySlice.call( arguments, 1 );
4635
+ return methodCall( this, arg0, args );
4636
+ }
4637
+ // just $().plugin({ options })
4638
+ plainCall( this, arg0 );
4639
+ return this;
4640
+ };
4641
+
4642
+ // $().plugin('methodName')
4643
+ function methodCall( $elems, methodName, args ) {
4644
+ var returnValue;
4645
+ var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';
4646
+
4647
+ $elems.each( function( i, elem ) {
4648
+ // get instance
4649
+ var instance = $.data( elem, namespace );
4650
+ if ( !instance ) {
4651
+ logError( namespace + ' not initialized. Cannot call methods, i.e. ' +
4652
+ pluginMethodStr );
4653
+ return;
4654
+ }
4655
+
4656
+ var method = instance[ methodName ];
4657
+ if ( !method || methodName.charAt(0) == '_' ) {
4658
+ logError( pluginMethodStr + ' is not a valid method' );
4659
+ return;
4660
+ }
4661
+
4662
+ // apply method, get return value
4663
+ var value = method.apply( instance, args );
4664
+ // set return value if value is returned, use only first value
4665
+ returnValue = returnValue === undefined ? value : returnValue;
4666
+ });
4667
+
4668
+ return returnValue !== undefined ? returnValue : $elems;
4669
+ }
4670
+
4671
+ function plainCall( $elems, options ) {
4672
+ $elems.each( function( i, elem ) {
4673
+ var instance = $.data( elem, namespace );
4674
+ if ( instance ) {
4675
+ // set options & init
4676
+ instance.option( options );
4677
+ instance._init();
4678
+ } else {
4679
+ // initialize new instance
4680
+ instance = new PluginClass( elem, options );
4681
+ $.data( elem, namespace, instance );
4682
+ }
4683
+ });
4684
+ }
4685
+
4686
+ updateJQuery( $ );
4687
+
4688
+ }
4689
+
4690
+ // ----- updateJQuery ----- //
4691
+
4692
+ // set $.bridget for v1 backwards compatibility
4693
+ function updateJQuery( $ ) {
4694
+ if ( !$ || ( $ && $.bridget ) ) {
4695
+ return;
4696
+ }
4697
+ $.bridget = jQueryBridget;
4698
+ }
4699
+
4700
+ updateJQuery( jQuery || window.jQuery );
4701
+
4702
+ // ----- ----- //
4703
+
4704
+ return jQueryBridget;
4705
+
4706
+ }));
4707
+
4708
+ /**
4709
+ * EvEmitter v1.0.2
4710
+ * Lil' event emitter
4711
+ * MIT License
4712
+ */
4713
+
4714
+ /* jshint unused: true, undef: true, strict: true */
4715
+
4716
+ ( function( global, factory ) {
4717
+ // universal module definition
4718
+ /* jshint strict: false */ /* globals define, module */
4719
+ if ( typeof define == 'function' && define.amd ) {
4720
+ // AMD - RequireJS
4721
+ define( 'ev-emitter/ev-emitter',factory );
4722
+ } else if ( typeof module == 'object' && module.exports ) {
4723
+ // CommonJS - Browserify, Webpack
4724
+ module.exports = factory();
4725
+ } else {
4726
+ // Browser globals
4727
+ global.EvEmitter = factory();
4728
+ }
4729
+
4730
+ }( this, function() {
4731
+
4732
+
4733
+
4734
+ function EvEmitter() {}
4735
+
4736
+ var proto = EvEmitter.prototype;
4737
+
4738
+ proto.on = function( eventName, listener ) {
4739
+ if ( !eventName || !listener ) {
4740
+ return;
4741
+ }
4742
+ // set events hash
4743
+ var events = this._events = this._events || {};
4744
+ // set listeners array
4745
+ var listeners = events[ eventName ] = events[ eventName ] || [];
4746
+ // only add once
4747
+ if ( listeners.indexOf( listener ) == -1 ) {
4748
+ listeners.push( listener );
4749
+ }
4750
+
4751
+ return this;
4752
+ };
4753
+
4754
+ proto.once = function( eventName, listener ) {
4755
+ if ( !eventName || !listener ) {
4756
+ return;
4757
+ }
4758
+ // add event
4759
+ this.on( eventName, listener );
4760
+ // set once flag
4761
+ // set onceEvents hash
4762
+ var onceEvents = this._onceEvents = this._onceEvents || {};
4763
+ // set onceListeners object
4764
+ var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
4765
+ // set flag
4766
+ onceListeners[ listener ] = true;
4767
+
4768
+ return this;
4769
+ };
4770
+
4771
+ proto.off = function( eventName, listener ) {
4772
+ var listeners = this._events && this._events[ eventName ];
4773
+ if ( !listeners || !listeners.length ) {
4774
+ return;
4775
+ }
4776
+ var index = listeners.indexOf( listener );
4777
+ if ( index != -1 ) {
4778
+ listeners.splice( index, 1 );
4779
+ }
4780
+
4781
+ return this;
4782
+ };
4783
+
4784
+ proto.emitEvent = function( eventName, args ) {
4785
+ var listeners = this._events && this._events[ eventName ];
4786
+ if ( !listeners || !listeners.length ) {
4787
+ return;
4788
+ }
4789
+ var i = 0;
4790
+ var listener = listeners[i];
4791
+ args = args || [];
4792
+ // once stuff
4793
+ var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
4794
+
4795
+ while ( listener ) {
4796
+ var isOnce = onceListeners && onceListeners[ listener ];
4797
+ if ( isOnce ) {
4798
+ // remove listener
4799
+ // remove before trigger to prevent recursion
4800
+ this.off( eventName, listener );
4801
+ // unset once flag
4802
+ delete onceListeners[ listener ];
4803
+ }
4804
+ // trigger listener
4805
+ listener.apply( this, args );
4806
+ // get next listener
4807
+ i += isOnce ? 0 : 1;
4808
+ listener = listeners[i];
4809
+ }
4810
+
4811
+ return this;
4812
+ };
4813
+
4814
+ return EvEmitter;
4815
+
4816
+ }));
4817
+
4818
+ /*!
4819
+ * getSize v2.0.2
4820
+ * measure size of elements
4821
+ * MIT license
4822
+ */
4823
+
4824
+ /*jshint browser: true, strict: true, undef: true, unused: true */
4825
+ /*global define: false, module: false, console: false */
4826
+
4827
+ ( function( window, factory ) {
4828
+ 'use strict';
4829
+
4830
+ if ( typeof define == 'function' && define.amd ) {
4831
+ // AMD
4832
+ define( 'get-size/get-size',[],function() {
4833
+ return factory();
4834
+ });
4835
+ } else if ( typeof module == 'object' && module.exports ) {
4836
+ // CommonJS
4837
+ module.exports = factory();
4838
+ } else {
4839
+ // browser global
4840
+ window.getSize = factory();
4841
+ }
4842
+
4843
+ })( window, function factory() {
4844
+ 'use strict';
4845
+
4846
+ // -------------------------- helpers -------------------------- //
4847
+
4848
+ // get a number from a string, not a percentage
4849
+ function getStyleSize( value ) {
4850
+ var num = parseFloat( value );
4851
+ // not a percent like '100%', and a number
4852
+ var isValid = value.indexOf('%') == -1 && !isNaN( num );
4853
+ return isValid && num;
4854
+ }
4855
+
4856
+ function noop() {}
4857
+
4858
+ var logError = typeof console == 'undefined' ? noop :
4859
+ function( message ) {
4860
+ console.error( message );
4861
+ };
4862
+
4863
+ // -------------------------- measurements -------------------------- //
4864
+
4865
+ var measurements = [
4866
+ 'paddingLeft',
4867
+ 'paddingRight',
4868
+ 'paddingTop',
4869
+ 'paddingBottom',
4870
+ 'marginLeft',
4871
+ 'marginRight',
4872
+ 'marginTop',
4873
+ 'marginBottom',
4874
+ 'borderLeftWidth',
4875
+ 'borderRightWidth',
4876
+ 'borderTopWidth',
4877
+ 'borderBottomWidth'
4878
+ ];
4879
+
4880
+ var measurementsLength = measurements.length;
4881
+
4882
+ function getZeroSize() {
4883
+ var size = {
4884
+ width: 0,
4885
+ height: 0,
4886
+ innerWidth: 0,
4887
+ innerHeight: 0,
4888
+ outerWidth: 0,
4889
+ outerHeight: 0
4890
+ };
4891
+ for ( var i=0; i < measurementsLength; i++ ) {
4892
+ var measurement = measurements[i];
4893
+ size[ measurement ] = 0;
4894
+ }
4895
+ return size;
4896
+ }
4897
+
4898
+ // -------------------------- getStyle -------------------------- //
4899
+
4900
+ /**
4901
+ * getStyle, get style of element, check for Firefox bug
4902
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
4903
+ */
4904
+ function getStyle( elem ) {
4905
+ var style = getComputedStyle( elem );
4906
+ if ( !style ) {
4907
+ logError( 'Style returned ' + style +
4908
+ '. Are you running this code in a hidden iframe on Firefox? ' +
4909
+ 'See http://bit.ly/getsizebug1' );
4910
+ }
4911
+ return style;
4912
+ }
4913
+
4914
+ // -------------------------- setup -------------------------- //
4915
+
4916
+ var isSetup = false;
4917
+
4918
+ var isBoxSizeOuter;
4919
+
4920
+ /**
4921
+ * setup
4922
+ * check isBoxSizerOuter
4923
+ * do on first getSize() rather than on page load for Firefox bug
4924
+ */
4925
+ function setup() {
4926
+ // setup once
4927
+ if ( isSetup ) {
4928
+ return;
4929
+ }
4930
+ isSetup = true;
4931
+
4932
+ // -------------------------- box sizing -------------------------- //
4933
+
4934
+ /**
4935
+ * WebKit measures the outer-width on style.width on border-box elems
4936
+ * IE & Firefox<29 measures the inner-width
4937
+ */
4938
+ var div = document.createElement('div');
4939
+ div.style.width = '200px';
4940
+ div.style.padding = '1px 2px 3px 4px';
4941
+ div.style.borderStyle = 'solid';
4942
+ div.style.borderWidth = '1px 2px 3px 4px';
4943
+ div.style.boxSizing = 'border-box';
4944
+
4945
+ var body = document.body || document.documentElement;
4946
+ body.appendChild( div );
4947
+ var style = getStyle( div );
4948
+
4949
+ getSize.isBoxSizeOuter = isBoxSizeOuter = getStyleSize( style.width ) == 200;
4950
+ body.removeChild( div );
4951
+
4952
+ }
4953
+
4954
+ // -------------------------- getSize -------------------------- //
4955
+
4956
+ function getSize( elem ) {
4957
+ setup();
4958
+
4959
+ // use querySeletor if elem is string
4960
+ if ( typeof elem == 'string' ) {
4961
+ elem = document.querySelector( elem );
4962
+ }
4963
+
4964
+ // do not proceed on non-objects
4965
+ if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
4966
+ return;
4967
+ }
4968
+
4969
+ var style = getStyle( elem );
4970
+
4971
+ // if hidden, everything is 0
4972
+ if ( style.display == 'none' ) {
4973
+ return getZeroSize();
4974
+ }
4975
+
4976
+ var size = {};
4977
+ size.width = elem.offsetWidth;
4978
+ size.height = elem.offsetHeight;
4979
+
4980
+ var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';
4981
+
4982
+ // get all measurements
4983
+ for ( var i=0; i < measurementsLength; i++ ) {
4984
+ var measurement = measurements[i];
4985
+ var value = style[ measurement ];
4986
+ var num = parseFloat( value );
4987
+ // any 'auto', 'medium' value will be 0
4988
+ size[ measurement ] = !isNaN( num ) ? num : 0;
4989
+ }
4990
+
4991
+ var paddingWidth = size.paddingLeft + size.paddingRight;
4992
+ var paddingHeight = size.paddingTop + size.paddingBottom;
4993
+ var marginWidth = size.marginLeft + size.marginRight;
4994
+ var marginHeight = size.marginTop + size.marginBottom;
4995
+ var borderWidth = size.borderLeftWidth + size.borderRightWidth;
4996
+ var borderHeight = size.borderTopWidth + size.borderBottomWidth;
4997
+
4998
+ var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
4999
+
5000
+ // overwrite width and height if we can get it from style
5001
+ var styleWidth = getStyleSize( style.width );
5002
+ if ( styleWidth !== false ) {
5003
+ size.width = styleWidth +
5004
+ // add padding and border unless it's already including it
5005
+ ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
5006
+ }
5007
+
5008
+ var styleHeight = getStyleSize( style.height );
5009
+ if ( styleHeight !== false ) {
5010
+ size.height = styleHeight +
5011
+ // add padding and border unless it's already including it
5012
+ ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
5013
+ }
5014
+
5015
+ size.innerWidth = size.width - ( paddingWidth + borderWidth );
5016
+ size.innerHeight = size.height - ( paddingHeight + borderHeight );
5017
+
5018
+ size.outerWidth = size.width + marginWidth;
5019
+ size.outerHeight = size.height + marginHeight;
5020
+
5021
+ return size;
5022
+ }
5023
+
5024
+ return getSize;
5025
+
5026
+ });
5027
+
5028
+ /**
5029
+ * matchesSelector v2.0.1
5030
+ * matchesSelector( element, '.selector' )
5031
+ * MIT license
5032
+ */
5033
+
5034
+ /*jshint browser: true, strict: true, undef: true, unused: true */
5035
+
5036
+ ( function( window, factory ) {
5037
+ /*global define: false, module: false */
5038
+ 'use strict';
5039
+ // universal module definition
5040
+ if ( typeof define == 'function' && define.amd ) {
5041
+ // AMD
5042
+ define( 'desandro-matches-selector/matches-selector',factory );
5043
+ } else if ( typeof module == 'object' && module.exports ) {
5044
+ // CommonJS
5045
+ module.exports = factory();
5046
+ } else {
5047
+ // browser global
5048
+ window.matchesSelector = factory();
5049
+ }
5050
+
5051
+ }( window, function factory() {
5052
+ 'use strict';
5053
+
5054
+ var matchesMethod = ( function() {
5055
+ var ElemProto = Element.prototype;
5056
+ // check for the standard method name first
5057
+ if ( ElemProto.matches ) {
5058
+ return 'matches';
5059
+ }
5060
+ // check un-prefixed
5061
+ if ( ElemProto.matchesSelector ) {
5062
+ return 'matchesSelector';
5063
+ }
5064
+ // check vendor prefixes
5065
+ var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
5066
+
5067
+ for ( var i=0; i < prefixes.length; i++ ) {
5068
+ var prefix = prefixes[i];
5069
+ var method = prefix + 'MatchesSelector';
5070
+ if ( ElemProto[ method ] ) {
5071
+ return method;
5072
+ }
5073
+ }
5074
+ })();
5075
+
5076
+ return function matchesSelector( elem, selector ) {
5077
+ return elem[ matchesMethod ]( selector );
5078
+ };
5079
+
5080
+ }));
5081
+
5082
+ /**
5083
+ * Fizzy UI utils v2.0.1
5084
+ * MIT license
5085
+ */
5086
+
5087
+ /*jshint browser: true, undef: true, unused: true, strict: true */
5088
+
5089
+ ( function( window, factory ) {
5090
+ // universal module definition
5091
+ /*jshint strict: false */ /*globals define, module, require */
5092
+
5093
+ if ( typeof define == 'function' && define.amd ) {
5094
+ // AMD
5095
+ define( 'fizzy-ui-utils/utils',[
5096
+ 'desandro-matches-selector/matches-selector'
5097
+ ], function( matchesSelector ) {
5098
+ return factory( window, matchesSelector );
5099
+ });
5100
+ } else if ( typeof module == 'object' && module.exports ) {
5101
+ // CommonJS
5102
+ module.exports = factory(
5103
+ window,
5104
+ require('desandro-matches-selector')
5105
+ );
5106
+ } else {
5107
+ // browser global
5108
+ window.fizzyUIUtils = factory(
5109
+ window,
5110
+ window.matchesSelector
5111
+ );
5112
+ }
5113
+
5114
+ }( window, function factory( window, matchesSelector ) {
5115
+
5116
+
5117
+
5118
+ var utils = {};
5119
+
5120
+ // ----- extend ----- //
5121
+
5122
+ // extends objects
5123
+ utils.extend = function( a, b ) {
5124
+ for ( var prop in b ) {
5125
+ a[ prop ] = b[ prop ];
5126
+ }
5127
+ return a;
5128
+ };
5129
+
5130
+ // ----- modulo ----- //
5131
+
5132
+ utils.modulo = function( num, div ) {
5133
+ return ( ( num % div ) + div ) % div;
5134
+ };
5135
+
5136
+ // ----- makeArray ----- //
5137
+
5138
+ // turn element or nodeList into an array
5139
+ utils.makeArray = function( obj ) {
5140
+ var ary = [];
5141
+ if ( Array.isArray( obj ) ) {
5142
+ // use object if already an array
5143
+ ary = obj;
5144
+ } else if ( obj && typeof obj.length == 'number' ) {
5145
+ // convert nodeList to array
5146
+ for ( var i=0; i < obj.length; i++ ) {
5147
+ ary.push( obj[i] );
5148
+ }
5149
+ } else {
5150
+ // array of single index
5151
+ ary.push( obj );
5152
+ }
5153
+ return ary;
5154
+ };
5155
+
5156
+ // ----- removeFrom ----- //
5157
+
5158
+ utils.removeFrom = function( ary, obj ) {
5159
+ var index = ary.indexOf( obj );
5160
+ if ( index != -1 ) {
5161
+ ary.splice( index, 1 );
5162
+ }
5163
+ };
5164
+
5165
+ // ----- getParent ----- //
5166
+
5167
+ utils.getParent = function( elem, selector ) {
5168
+ while ( elem != document.body ) {
5169
+ elem = elem.parentNode;
5170
+ if ( matchesSelector( elem, selector ) ) {
5171
+ return elem;
5172
+ }
5173
+ }
5174
+ };
5175
+
5176
+ // ----- getQueryElement ----- //
5177
+
5178
+ // use element as selector string
5179
+ utils.getQueryElement = function( elem ) {
5180
+ if ( typeof elem == 'string' ) {
5181
+ return document.querySelector( elem );
5182
+ }
5183
+ return elem;
5184
+ };
5185
+
5186
+ // ----- handleEvent ----- //
5187
+
5188
+ // enable .ontype to trigger from .addEventListener( elem, 'type' )
5189
+ utils.handleEvent = function( event ) {
5190
+ var method = 'on' + event.type;
5191
+ if ( this[ method ] ) {
5192
+ this[ method ]( event );
5193
+ }
5194
+ };
5195
+
5196
+ // ----- filterFindElements ----- //
5197
+
5198
+ utils.filterFindElements = function( elems, selector ) {
5199
+ // make array of elems
5200
+ elems = utils.makeArray( elems );
5201
+ var ffElems = [];
5202
+
5203
+ elems.forEach( function( elem ) {
5204
+ // check that elem is an actual element
5205
+ if ( !( elem instanceof HTMLElement ) ) {
5206
+ return;
5207
+ }
5208
+ // add elem if no selector
5209
+ if ( !selector ) {
5210
+ ffElems.push( elem );
5211
+ return;
5212
+ }
5213
+ // filter & find items if we have a selector
5214
+ // filter
5215
+ if ( matchesSelector( elem, selector ) ) {
5216
+ ffElems.push( elem );
5217
+ }
5218
+ // find children
5219
+ var childElems = elem.querySelectorAll( selector );
5220
+ // concat childElems to filterFound array
5221
+ for ( var i=0; i < childElems.length; i++ ) {
5222
+ ffElems.push( childElems[i] );
5223
+ }
5224
+ });
5225
+
5226
+ return ffElems;
5227
+ };
5228
+
5229
+ // ----- debounceMethod ----- //
5230
+
5231
+ utils.debounceMethod = function( _class, methodName, threshold ) {
5232
+ // original method
5233
+ var method = _class.prototype[ methodName ];
5234
+ var timeoutName = methodName + 'Timeout';
5235
+
5236
+ _class.prototype[ methodName ] = function() {
5237
+ var timeout = this[ timeoutName ];
5238
+ if ( timeout ) {
5239
+ clearTimeout( timeout );
5240
+ }
5241
+ var args = arguments;
5242
+
5243
+ var _this = this;
5244
+ this[ timeoutName ] = setTimeout( function() {
5245
+ method.apply( _this, args );
5246
+ delete _this[ timeoutName ];
5247
+ }, threshold || 100 );
5248
+ };
5249
+ };
5250
+
5251
+ // ----- docReady ----- //
5252
+
5253
+ utils.docReady = function( callback ) {
5254
+ if ( document.readyState == 'complete' ) {
5255
+ callback();
5256
+ } else {
5257
+ document.addEventListener( 'DOMContentLoaded', callback );
5258
+ }
5259
+ };
5260
+
5261
+ // ----- htmlInit ----- //
5262
+
5263
+ // http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
5264
+ utils.toDashed = function( str ) {
5265
+ return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
5266
+ return $1 + '-' + $2;
5267
+ }).toLowerCase();
5268
+ };
5269
+
5270
+ var console = window.console;
5271
+ /**
5272
+ * allow user to initialize classes via [data-namespace] or .js-namespace class
5273
+ * htmlInit( Widget, 'widgetName' )
5274
+ * options are parsed from data-namespace-options
5275
+ */
5276
+ utils.htmlInit = function( WidgetClass, namespace ) {
5277
+ utils.docReady( function() {
5278
+ var dashedNamespace = utils.toDashed( namespace );
5279
+ var dataAttr = 'data-' + dashedNamespace;
5280
+ var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
5281
+ var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
5282
+ var elems = utils.makeArray( dataAttrElems )
5283
+ .concat( utils.makeArray( jsDashElems ) );
5284
+ var dataOptionsAttr = dataAttr + '-options';
5285
+ var jQuery = window.jQuery;
5286
+
5287
+ elems.forEach( function( elem ) {
5288
+ var attr = elem.getAttribute( dataAttr ) ||
5289
+ elem.getAttribute( dataOptionsAttr );
5290
+ var options;
5291
+ try {
5292
+ options = attr && JSON.parse( attr );
5293
+ } catch ( error ) {
5294
+ // log error, do not initialize
5295
+ if ( console ) {
5296
+ console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
5297
+ ': ' + error );
5298
+ }
5299
+ return;
5300
+ }
5301
+ // initialize
5302
+ var instance = new WidgetClass( elem, options );
5303
+ // make available via $().data('layoutname')
5304
+ if ( jQuery ) {
5305
+ jQuery.data( elem, namespace, instance );
5306
+ }
5307
+ });
5308
+
5309
+ });
5310
+ };
5311
+
5312
+ // ----- ----- //
5313
+
5314
+ return utils;
5315
+
5316
+ }));
5317
+
5318
+ /**
5319
+ * Outlayer Item
5320
+ */
5321
+
5322
+ ( function( window, factory ) {
5323
+ // universal module definition
5324
+ /* jshint strict: false */ /* globals define, module, require */
5325
+ if ( typeof define == 'function' && define.amd ) {
5326
+ // AMD - RequireJS
5327
+ define( 'outlayer/item',[
5328
+ 'ev-emitter/ev-emitter',
5329
+ 'get-size/get-size'
5330
+ ],
5331
+ factory
5332
+ );
5333
+ } else if ( typeof module == 'object' && module.exports ) {
5334
+ // CommonJS - Browserify, Webpack
5335
+ module.exports = factory(
5336
+ require('ev-emitter'),
5337
+ require('get-size')
5338
+ );
5339
+ } else {
5340
+ // browser global
5341
+ window.Outlayer = {};
5342
+ window.Outlayer.Item = factory(
5343
+ window.EvEmitter,
5344
+ window.getSize
5345
+ );
5346
+ }
5347
+
5348
+ }( window, function factory( EvEmitter, getSize ) {
5349
+ 'use strict';
5350
+
5351
+ // ----- helpers ----- //
5352
+
5353
+ function isEmptyObj( obj ) {
5354
+ for ( var prop in obj ) {
5355
+ return false;
5356
+ }
5357
+ prop = null;
5358
+ return true;
5359
+ }
5360
+
5361
+ // -------------------------- CSS3 support -------------------------- //
5362
+
5363
+
5364
+ var docElemStyle = document.documentElement.style;
5365
+
5366
+ var transitionProperty = typeof docElemStyle.transition == 'string' ?
5367
+ 'transition' : 'WebkitTransition';
5368
+ var transformProperty = typeof docElemStyle.transform == 'string' ?
5369
+ 'transform' : 'WebkitTransform';
5370
+
5371
+ var transitionEndEvent = {
5372
+ WebkitTransition: 'webkitTransitionEnd',
5373
+ transition: 'transitionend'
5374
+ }[ transitionProperty ];
5375
+
5376
+ // cache all vendor properties that could have vendor prefix
5377
+ var vendorProperties = {
5378
+ transform: transformProperty,
5379
+ transition: transitionProperty,
5380
+ transitionDuration: transitionProperty + 'Duration',
5381
+ transitionProperty: transitionProperty + 'Property',
5382
+ transitionDelay: transitionProperty + 'Delay'
5383
+ };
5384
+
5385
+ // -------------------------- Item -------------------------- //
5386
+
5387
+ function Item( element, layout ) {
5388
+ if ( !element ) {
5389
+ return;
5390
+ }
5391
+
5392
+ this.element = element;
5393
+ // parent layout class, i.e. Masonry, Enviratope, or Packery
5394
+ this.layout = layout;
5395
+ this.position = {
5396
+ x: 0,
5397
+ y: 0
5398
+ };
5399
+
5400
+ this._create();
5401
+ }
5402
+
5403
+ // inherit EvEmitter
5404
+ var proto = Item.prototype = Object.create( EvEmitter.prototype );
5405
+ proto.constructor = Item;
5406
+
5407
+ proto._create = function() {
5408
+ // transition objects
5409
+ this._transn = {
5410
+ ingProperties: {},
5411
+ clean: {},
5412
+ onEnd: {}
5413
+ };
5414
+
5415
+ this.css({
5416
+ position: 'absolute'
5417
+ });
5418
+ };
5419
+
5420
+ // trigger specified handler for event type
5421
+ proto.handleEvent = function( event ) {
5422
+ var method = 'on' + event.type;
5423
+ if ( this[ method ] ) {
5424
+ this[ method ]( event );
5425
+ }
5426
+ };
5427
+
5428
+ proto.getSize = function() {
5429
+ this.size = getSize( this.element );
5430
+ };
5431
+
5432
+ /**
5433
+ * apply CSS styles to element
5434
+ * @param {Object} style
5435
+ */
5436
+ proto.css = function( style ) {
5437
+ var elemStyle = this.element.style;
5438
+
5439
+ for ( var prop in style ) {
5440
+ // use vendor property if available
5441
+ var supportedProp = vendorProperties[ prop ] || prop;
5442
+ elemStyle[ supportedProp ] = style[ prop ];
5443
+ }
5444
+ };
5445
+
5446
+ // measure position, and sets it
5447
+ proto.getPosition = function() {
5448
+ var style = getComputedStyle( this.element );
5449
+ var isOriginLeft = this.layout._getOption('originLeft');
5450
+ var isOriginTop = this.layout._getOption('originTop');
5451
+ var xValue = style[ isOriginLeft ? 'left' : 'right' ];
5452
+ var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
5453
+ // convert percent to pixels
5454
+ var layoutSize = this.layout.size;
5455
+ var x = xValue.indexOf('%') != -1 ?
5456
+ ( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 );
5457
+ var y = yValue.indexOf('%') != -1 ?
5458
+ ( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 );
5459
+
5460
+ // clean up 'auto' or other non-integer values
5461
+ x = isNaN( x ) ? 0 : x;
5462
+ y = isNaN( y ) ? 0 : y;
5463
+ // remove padding from measurement
5464
+ x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
5465
+ y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
5466
+
5467
+ this.position.x = x;
5468
+ this.position.y = y;
5469
+ };
5470
+
5471
+ // set settled position, apply padding
5472
+ proto.layoutPosition = function() {
5473
+ var layoutSize = this.layout.size;
5474
+ var style = {};
5475
+ var isOriginLeft = this.layout._getOption('originLeft');
5476
+ var isOriginTop = this.layout._getOption('originTop');
5477
+
5478
+ // x
5479
+ var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';
5480
+ var xProperty = isOriginLeft ? 'left' : 'right';
5481
+ var xResetProperty = isOriginLeft ? 'right' : 'left';
5482
+
5483
+ var x = this.position.x + layoutSize[ xPadding ];
5484
+ // set in percentage or pixels
5485
+ style[ xProperty ] = this.getXValue( x );
5486
+ // reset other property
5487
+ style[ xResetProperty ] = '';
5488
+
5489
+ // y
5490
+ var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';
5491
+ var yProperty = isOriginTop ? 'top' : 'bottom';
5492
+ var yResetProperty = isOriginTop ? 'bottom' : 'top';
5493
+
5494
+ var y = this.position.y + layoutSize[ yPadding ];
5495
+ // set in percentage or pixels
5496
+ style[ yProperty ] = this.getYValue( y );
5497
+ // reset other property
5498
+ style[ yResetProperty ] = '';
5499
+
5500
+ this.css( style );
5501
+ this.emitEvent( 'layout', [ this ] );
5502
+ };
5503
+
5504
+ proto.getXValue = function( x ) {
5505
+ var isHorizontal = this.layout._getOption('horizontal');
5506
+ return this.layout.options.percentPosition && !isHorizontal ?
5507
+ ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
5508
+ };
5509
+
5510
+ proto.getYValue = function( y ) {
5511
+ var isHorizontal = this.layout._getOption('horizontal');
5512
+ return this.layout.options.percentPosition && isHorizontal ?
5513
+ ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
5514
+ };
5515
+
5516
+ proto._transitionTo = function( x, y ) {
5517
+ this.getPosition();
5518
+ // get current x & y from top/left
5519
+ var curX = this.position.x;
5520
+ var curY = this.position.y;
5521
+
5522
+ var compareX = parseInt( x, 10 );
5523
+ var compareY = parseInt( y, 10 );
5524
+ var didNotMove = compareX === this.position.x && compareY === this.position.y;
5525
+
5526
+ // save end position
5527
+ this.setPosition( x, y );
5528
+
5529
+ // if did not move and not transitioning, just go to layout
5530
+ if ( didNotMove && !this.isTransitioning ) {
5531
+ this.layoutPosition();
5532
+ return;
5533
+ }
5534
+
5535
+ var transX = x - curX;
5536
+ var transY = y - curY;
5537
+ var transitionStyle = {};
5538
+ transitionStyle.transform = this.getTranslate( transX, transY );
5539
+
5540
+ this.transition({
5541
+ to: transitionStyle,
5542
+ onTransitionEnd: {
5543
+ transform: this.layoutPosition
5544
+ },
5545
+ isCleaning: true
5546
+ });
5547
+ };
5548
+
5549
+ proto.getTranslate = function( x, y ) {
5550
+ // flip cooridinates if origin on right or bottom
5551
+ var isOriginLeft = this.layout._getOption('originLeft');
5552
+ var isOriginTop = this.layout._getOption('originTop');
5553
+ x = isOriginLeft ? x : -x;
5554
+ y = isOriginTop ? y : -y;
5555
+ return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
5556
+ };
5557
+
5558
+ // non transition + transform support
5559
+ proto.goTo = function( x, y ) {
5560
+ this.setPosition( x, y );
5561
+ this.layoutPosition();
5562
+ };
5563
+
5564
+ proto.moveTo = proto._transitionTo;
5565
+
5566
+ proto.setPosition = function( x, y ) {
5567
+ this.position.x = parseInt( x, 10 );
5568
+ this.position.y = parseInt( y, 10 );
5569
+ };
5570
+
5571
+ // ----- transition ----- //
5572
+
5573
+ /**
5574
+ * @param {Object} style - CSS
5575
+ * @param {Function} onTransitionEnd
5576
+ */
5577
+
5578
+ // non transition, just trigger callback
5579
+ proto._nonTransition = function( args ) {
5580
+ this.css( args.to );
5581
+ if ( args.isCleaning ) {
5582
+ this._removeStyles( args.to );
5583
+ }
5584
+ for ( var prop in args.onTransitionEnd ) {
5585
+ args.onTransitionEnd[ prop ].call( this );
5586
+ }
5587
+ };
5588
+
5589
+ /**
5590
+ * proper transition
5591
+ * @param {Object} args - arguments
5592
+ * @param {Object} to - style to transition to
5593
+ * @param {Object} from - style to start transition from
5594
+ * @param {Boolean} isCleaning - removes transition styles after transition
5595
+ * @param {Function} onTransitionEnd - callback
5596
+ */
5597
+ proto.transition = function( args ) {
5598
+ // redirect to nonTransition if no transition duration
5599
+ if ( !parseFloat( this.layout.options.transitionDuration ) ) {
5600
+ this._nonTransition( args );
5601
+ return;
5602
+ }
5603
+
5604
+ var _transition = this._transn;
5605
+ // keep track of onTransitionEnd callback by css property
5606
+ for ( var prop in args.onTransitionEnd ) {
5607
+ _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
5608
+ }
5609
+ // keep track of properties that are transitioning
5610
+ for ( prop in args.to ) {
5611
+ _transition.ingProperties[ prop ] = true;
5612
+ // keep track of properties to clean up when transition is done
5613
+ if ( args.isCleaning ) {
5614
+ _transition.clean[ prop ] = true;
5615
+ }
5616
+ }
5617
+
5618
+ // set from styles
5619
+ if ( args.from ) {
5620
+ this.css( args.from );
5621
+ // force redraw. http://blog.alexmaccaw.com/css-transitions
5622
+ var h = this.element.offsetHeight;
5623
+ // hack for JSHint to hush about unused var
5624
+ h = null;
5625
+ }
5626
+ // enable transition
5627
+ this.enableTransition( args.to );
5628
+ // set styles that are transitioning
5629
+ this.css( args.to );
5630
+
5631
+ this.isTransitioning = true;
5632
+
5633
+ };
5634
+
5635
+ // dash before all cap letters, including first for
5636
+ // WebkitTransform => -webkit-transform
5637
+ function toDashedAll( str ) {
5638
+ return str.replace( /([A-Z])/g, function( $1 ) {
5639
+ return '-' + $1.toLowerCase();
5640
+ });
5641
+ }
5642
+
5643
+ var transitionProps = 'opacity,' + toDashedAll( transformProperty );
5644
+
5645
+ proto.enableTransition = function(/* style */) {
5646
+ // HACK changing transitionProperty during a transition
5647
+ // will cause transition to jump
5648
+ if ( this.isTransitioning ) {
5649
+ return;
5650
+ }
5651
+
5652
+ // make `transition: foo, bar, baz` from style object
5653
+ // HACK un-comment this when enableTransition can work
5654
+ // while a transition is happening
5655
+ // var transitionValues = [];
5656
+ // for ( var prop in style ) {
5657
+ // // dash-ify camelCased properties like WebkitTransition
5658
+ // prop = vendorProperties[ prop ] || prop;
5659
+ // transitionValues.push( toDashedAll( prop ) );
5660
+ // }
5661
+ // munge number to millisecond, to match stagger
5662
+ var duration = this.layout.options.transitionDuration;
5663
+ duration = typeof duration == 'number' ? duration + 'ms' : duration;
5664
+ // enable transition styles
5665
+ this.css({
5666
+ transitionProperty: transitionProps,
5667
+ transitionDuration: duration,
5668
+ transitionDelay: this.staggerDelay || 0
5669
+ });
5670
+ // listen for transition end event
5671
+ this.element.addEventListener( transitionEndEvent, this, false );
5672
+ };
5673
+
5674
+ // ----- events ----- //
5675
+
5676
+ proto.onwebkitTransitionEnd = function( event ) {
5677
+ this.ontransitionend( event );
5678
+ };
5679
+
5680
+ proto.onotransitionend = function( event ) {
5681
+ this.ontransitionend( event );
5682
+ };
5683
+
5684
+ // properties that I munge to make my life easier
5685
+ var dashedVendorProperties = {
5686
+ '-webkit-transform': 'transform'
5687
+ };
5688
+
5689
+ proto.ontransitionend = function( event ) {
5690
+ // disregard bubbled events from children
5691
+ if ( event.target !== this.element ) {
5692
+ return;
5693
+ }
5694
+ var _transition = this._transn;
5695
+ // get property name of transitioned property, convert to prefix-free
5696
+ var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
5697
+
5698
+ // remove property that has completed transitioning
5699
+ delete _transition.ingProperties[ propertyName ];
5700
+ // check if any properties are still transitioning
5701
+ if ( isEmptyObj( _transition.ingProperties ) ) {
5702
+ // all properties have completed transitioning
5703
+ this.disableTransition();
5704
+ }
5705
+ // clean style
5706
+ if ( propertyName in _transition.clean ) {
5707
+ // clean up style
5708
+ this.element.style[ event.propertyName ] = '';
5709
+ delete _transition.clean[ propertyName ];
5710
+ }
5711
+ // trigger onTransitionEnd callback
5712
+ if ( propertyName in _transition.onEnd ) {
5713
+ var onTransitionEnd = _transition.onEnd[ propertyName ];
5714
+ onTransitionEnd.call( this );
5715
+ delete _transition.onEnd[ propertyName ];
5716
+ }
5717
+
5718
+ this.emitEvent( 'transitionEnd', [ this ] );
5719
+ };
5720
+
5721
+ proto.disableTransition = function() {
5722
+ this.removeTransitionStyles();
5723
+ this.element.removeEventListener( transitionEndEvent, this, false );
5724
+ this.isTransitioning = false;
5725
+ };
5726
+
5727
+ /**
5728
+ * removes style property from element
5729
+ * @param {Object} style
5730
+ **/
5731
+ proto._removeStyles = function( style ) {
5732
+ // clean up transition styles
5733
+ var cleanStyle = {};
5734
+ for ( var prop in style ) {
5735
+ cleanStyle[ prop ] = '';
5736
+ }
5737
+ this.css( cleanStyle );
5738
+ };
5739
+
5740
+ var cleanTransitionStyle = {
5741
+ transitionProperty: '',
5742
+ transitionDuration: '',
5743
+ transitionDelay: ''
5744
+ };
5745
+
5746
+ proto.removeTransitionStyles = function() {
5747
+ // remove transition
5748
+ this.css( cleanTransitionStyle );
5749
+ };
5750
+
5751
+ // ----- stagger ----- //
5752
+
5753
+ proto.stagger = function( delay ) {
5754
+ delay = isNaN( delay ) ? 0 : delay;
5755
+ this.staggerDelay = delay + 'ms';
5756
+ };
5757
+
5758
+ // ----- show/hide/remove ----- //
5759
+
5760
+ // remove element from DOM
5761
+ proto.removeElem = function() {
5762
+ this.element.parentNode.removeChild( this.element );
5763
+ // remove display: none
5764
+ this.css({ display: '' });
5765
+ this.emitEvent( 'remove', [ this ] );
5766
+ };
5767
+
5768
+ proto.remove = function() {
5769
+ // just remove element if no transition support or no transition
5770
+ if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
5771
+ this.removeElem();
5772
+ return;
5773
+ }
5774
+
5775
+ // start transition
5776
+ this.once( 'transitionEnd', function() {
5777
+ this.removeElem();
5778
+ });
5779
+ this.hide();
5780
+ };
5781
+
5782
+ proto.reveal = function() {
5783
+ delete this.isHidden;
5784
+ // remove display: none
5785
+ this.css({ display: '' });
5786
+
5787
+ var options = this.layout.options;
5788
+
5789
+ var onTransitionEnd = {};
5790
+ var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');
5791
+ onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;
5792
+
5793
+ this.transition({
5794
+ from: options.hiddenStyle,
5795
+ to: options.visibleStyle,
5796
+ isCleaning: true,
5797
+ onTransitionEnd: onTransitionEnd
5798
+ });
5799
+ };
5800
+
5801
+ proto.onRevealTransitionEnd = function() {
5802
+ // check if still visible
5803
+ // during transition, item may have been hidden
5804
+ if ( !this.isHidden ) {
5805
+ this.emitEvent('reveal');
5806
+ }
5807
+ };
5808
+
5809
+ /**
5810
+ * get style property use for hide/reveal transition end
5811
+ * @param {String} styleProperty - hiddenStyle/visibleStyle
5812
+ * @returns {String}
5813
+ */
5814
+ proto.getHideRevealTransitionEndProperty = function( styleProperty ) {
5815
+ var optionStyle = this.layout.options[ styleProperty ];
5816
+ // use opacity
5817
+ if ( optionStyle.opacity ) {
5818
+ return 'opacity';
5819
+ }
5820
+ // get first property
5821
+ for ( var prop in optionStyle ) {
5822
+ return prop;
5823
+ }
5824
+ };
5825
+
5826
+ proto.hide = function() {
5827
+ // set flag
5828
+ this.isHidden = true;
5829
+ // remove display: none
5830
+ this.css({ display: '' });
5831
+
5832
+ var options = this.layout.options;
5833
+
5834
+ var onTransitionEnd = {};
5835
+ var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');
5836
+ onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;
5837
+
5838
+ this.transition({
5839
+ from: options.visibleStyle,
5840
+ to: options.hiddenStyle,
5841
+ // keep hidden stuff hidden
5842
+ isCleaning: true,
5843
+ onTransitionEnd: onTransitionEnd
5844
+ });
5845
+ };
5846
+
5847
+ proto.onHideTransitionEnd = function() {
5848
+ // check if still hidden
5849
+ // during transition, item may have been un-hidden
5850
+ if ( this.isHidden ) {
5851
+ this.css({ display: 'none' });
5852
+ this.emitEvent('hide');
5853
+ }
5854
+ };
5855
+
5856
+ proto.destroy = function() {
5857
+ this.css({
5858
+ position: '',
5859
+ left: '',
5860
+ right: '',
5861
+ top: '',
5862
+ bottom: '',
5863
+ transition: '',
5864
+ transform: ''
5865
+ });
5866
+ };
5867
+
5868
+ return Item;
5869
+
5870
+ }));
5871
+
5872
+ /*!
5873
+ * Outlayer v2.1.0
5874
+ * the brains and guts of a layout library
5875
+ * MIT license
5876
+ */
5877
+
5878
+ ( function( window, factory ) {
5879
+ 'use strict';
5880
+ // universal module definition
5881
+ /* jshint strict: false */ /* globals define, module, require */
5882
+ if ( typeof define == 'function' && define.amd ) {
5883
+ // AMD - RequireJS
5884
+ define( 'outlayer/outlayer',[
5885
+ 'ev-emitter/ev-emitter',
5886
+ 'get-size/get-size',
5887
+ 'fizzy-ui-utils/utils',
5888
+ './item'
5889
+ ],
5890
+ function( EvEmitter, getSize, utils, Item ) {
5891
+ return factory( window, EvEmitter, getSize, utils, Item);
5892
+ }
5893
+ );
5894
+ } else if ( typeof module == 'object' && module.exports ) {
5895
+ // CommonJS - Browserify, Webpack
5896
+ module.exports = factory(
5897
+ window,
5898
+ require('ev-emitter'),
5899
+ require('get-size'),
5900
+ require('fizzy-ui-utils'),
5901
+ require('./item')
5902
+ );
5903
+ } else {
5904
+ // browser global
5905
+ window.Outlayer = factory(
5906
+ window,
5907
+ window.EvEmitter,
5908
+ window.getSize,
5909
+ window.fizzyUIUtils,
5910
+ window.Outlayer.Item
5911
+ );
5912
+ }
5913
+
5914
+ }( window, function factory( window, EvEmitter, getSize, utils, Item ) {
5915
+ 'use strict';
5916
+
5917
+ // ----- vars ----- //
5918
+
5919
+ var console = window.console;
5920
+ var jQuery = window.jQuery;
5921
+ var noop = function() {};
5922
+
5923
+ // -------------------------- Outlayer -------------------------- //
5924
+
5925
+ // globally unique identifiers
5926
+ var GUID = 0;
5927
+ // internal store of all Outlayer intances
5928
+ var instances = {};
5929
+
5930
+
5931
+ /**
5932
+ * @param {Element, String} element
5933
+ * @param {Object} options
5934
+ * @constructor
5935
+ */
5936
+ function Outlayer( element, options ) {
5937
+ var queryElement = utils.getQueryElement( element );
5938
+ if ( !queryElement ) {
5939
+ if ( console ) {
5940
+ console.error( 'Bad element for ' + this.constructor.namespace +
5941
+ ': ' + ( queryElement || element ) );
5942
+ }
5943
+ return;
5944
+ }
5945
+ this.element = queryElement;
5946
+ // add jQuery
5947
+ if ( jQuery ) {
5948
+ this.$element = jQuery( this.element );
5949
+ }
5950
+
5951
+ // options
5952
+ this.options = utils.extend( {}, this.constructor.defaults );
5953
+ this.option( options );
5954
+
5955
+ // add id for Outlayer.getFromElement
5956
+ var id = ++GUID;
5957
+ this.element.outlayerGUID = id; // expando
5958
+ instances[ id ] = this; // associate via id
5959
+
5960
+ // kick it off
5961
+ this._create();
5962
+
5963
+ var isInitLayout = this._getOption('initLayout');
5964
+ if ( isInitLayout ) {
5965
+ this.layout();
5966
+ }
5967
+ }
5968
+
5969
+ // settings are for internal use only
5970
+ Outlayer.namespace = 'outlayer';
5971
+ Outlayer.Item = Item;
5972
+
5973
+ // default options
5974
+ Outlayer.defaults = {
5975
+ containerStyle: {
5976
+ position: 'relative'
5977
+ },
5978
+ initLayout: true,
5979
+ originLeft: true,
5980
+ originTop: true,
5981
+ resize: true,
5982
+ resizeContainer: true,
5983
+ // item options
5984
+ transitionDuration: '0.4s',
5985
+ hiddenStyle: {
5986
+ opacity: 0,
5987
+ transform: 'scale(0.001)'
5988
+ },
5989
+ visibleStyle: {
5990
+ opacity: 1,
5991
+ transform: 'scale(1)'
5992
+ }
5993
+ };
5994
+
5995
+ var proto = Outlayer.prototype;
5996
+ // inherit EvEmitter
5997
+ utils.extend( proto, EvEmitter.prototype );
5998
+
5999
+ /**
6000
+ * set options
6001
+ * @param {Object} opts
6002
+ */
6003
+ proto.option = function( opts ) {
6004
+ utils.extend( this.options, opts );
6005
+ };
6006
+
6007
+ /**
6008
+ * get backwards compatible option value, check old name
6009
+ */
6010
+ proto._getOption = function( option ) {
6011
+ var oldOption = this.constructor.compatOptions[ option ];
6012
+ return oldOption && this.options[ oldOption ] !== undefined ?
6013
+ this.options[ oldOption ] : this.options[ option ];
6014
+ };
6015
+
6016
+ Outlayer.compatOptions = {
6017
+ // currentName: oldName
6018
+ initLayout: 'isInitLayout',
6019
+ horizontal: 'isHorizontal',
6020
+ layoutInstant: 'isLayoutInstant',
6021
+ originLeft: 'isOriginLeft',
6022
+ originTop: 'isOriginTop',
6023
+ resize: 'isResizeBound',
6024
+ resizeContainer: 'isResizingContainer'
6025
+ };
6026
+
6027
+ proto._create = function() {
6028
+ // get items from children
6029
+ this.reloadItems();
6030
+ // elements that affect layout, but are not laid out
6031
+ this.stamps = [];
6032
+ this.stamp( this.options.stamp );
6033
+ // set container style
6034
+ utils.extend( this.element.style, this.options.containerStyle );
6035
+
6036
+ // bind resize method
6037
+ var canBindResize = this._getOption('resize');
6038
+ if ( canBindResize ) {
6039
+ this.bindResize();
6040
+ }
6041
+ };
6042
+
6043
+ // goes through all children again and gets bricks in proper order
6044
+ proto.reloadItems = function() {
6045
+ // collection of item elements
6046
+ this.items = this._itemize( this.element.children );
6047
+ };
6048
+
6049
+
6050
+ /**
6051
+ * turn elements into Outlayer.Items to be used in layout
6052
+ * @param {Array or NodeList or HTMLElement} elems
6053
+ * @returns {Array} items - collection of new Outlayer Items
6054
+ */
6055
+ proto._itemize = function( elems ) {
6056
+
6057
+ var itemElems = this._filterFindItemElements( elems );
6058
+ var Item = this.constructor.Item;
6059
+
6060
+ // create new Outlayer Items for collection
6061
+ var items = [];
6062
+ for ( var i=0; i < itemElems.length; i++ ) {
6063
+ var elem = itemElems[i];
6064
+ var item = new Item( elem, this );
6065
+ items.push( item );
6066
+ }
6067
+
6068
+ return items;
6069
+ };
6070
+
6071
+ /**
6072
+ * get item elements to be used in layout
6073
+ * @param {Array or NodeList or HTMLElement} elems
6074
+ * @returns {Array} items - item elements
6075
+ */
6076
+ proto._filterFindItemElements = function( elems ) {
6077
+ return utils.filterFindElements( elems, this.options.itemSelector );
6078
+ };
6079
+
6080
+ /**
6081
+ * getter method for getting item elements
6082
+ * @returns {Array} elems - collection of item elements
6083
+ */
6084
+ proto.getItemElements = function() {
6085
+ return this.items.map( function( item ) {
6086
+ return item.element;
6087
+ });
6088
+ };
6089
+
6090
+ // ----- init & layout ----- //
6091
+
6092
+ /**
6093
+ * lays out all items
6094
+ */
6095
+ proto.layout = function() {
6096
+ this._resetLayout();
6097
+ this._manageStamps();
6098
+
6099
+ // don't animate first layout
6100
+ var layoutInstant = this._getOption('layoutInstant');
6101
+ var isInstant = layoutInstant !== undefined ?
6102
+ layoutInstant : !this._isLayoutInited;
6103
+ this.layoutItems( this.items, isInstant );
6104
+
6105
+ // flag for initalized
6106
+ this._isLayoutInited = true;
6107
+ };
6108
+
6109
+ // _init is alias for layout
6110
+ proto._init = proto.layout;
6111
+
6112
+ /**
6113
+ * logic before any new layout
6114
+ */
6115
+ proto._resetLayout = function() {
6116
+ this.getSize();
6117
+ };
6118
+
6119
+
6120
+ proto.getSize = function() {
6121
+ this.size = getSize( this.element );
6122
+ };
6123
+
6124
+ /**
6125
+ * get measurement from option, for columnWidth, rowHeight, gutter
6126
+ * if option is String -> get element from selector string, & get size of element
6127
+ * if option is Element -> get size of element
6128
+ * else use option as a number
6129
+ *
6130
+ * @param {String} measurement
6131
+ * @param {String} size - width or height
6132
+ * @private
6133
+ */
6134
+ proto._getMeasurement = function( measurement, size ) {
6135
+ var option = this.options[ measurement ];
6136
+ var elem;
6137
+ if ( !option ) {
6138
+ // default to 0
6139
+ this[ measurement ] = 0;
6140
+ } else {
6141
+ // use option as an element
6142
+ if ( typeof option == 'string' ) {
6143
+ elem = this.element.querySelector( option );
6144
+ } else if ( option instanceof HTMLElement ) {
6145
+ elem = option;
6146
+ }
6147
+ // use size of element, if element
6148
+ this[ measurement ] = elem ? getSize( elem )[ size ] : option;
6149
+ }
6150
+ };
6151
+
6152
+ /**
6153
+ * layout a collection of item elements
6154
+ * @api public
6155
+ */
6156
+ proto.layoutItems = function( items, isInstant ) {
6157
+ items = this._getItemsForLayout( items );
6158
+
6159
+ this._layoutItems( items, isInstant );
6160
+
6161
+ this._postLayout();
6162
+ };
6163
+
6164
+ /**
6165
+ * get the items to be laid out
6166
+ * you may want to skip over some items
6167
+ * @param {Array} items
6168
+ * @returns {Array} items
6169
+ */
6170
+ proto._getItemsForLayout = function( items ) {
6171
+ return items.filter( function( item ) {
6172
+ return !item.isIgnored;
6173
+ });
6174
+ };
6175
+
6176
+ /**
6177
+ * layout items
6178
+ * @param {Array} items
6179
+ * @param {Boolean} isInstant
6180
+ */
6181
+ proto._layoutItems = function( items, isInstant ) {
6182
+ this._emitCompleteOnItems( 'layout', items );
6183
+
6184
+ if ( !items || !items.length ) {
6185
+ // no items, emit event with empty array
6186
+ return;
6187
+ }
6188
+
6189
+ var queue = [];
6190
+
6191
+ items.forEach( function( item ) {
6192
+ // get x/y object from method
6193
+ var position = this._getItemLayoutPosition( item );
6194
+ // enqueue
6195
+ position.item = item;
6196
+ position.isInstant = isInstant || item.isLayoutInstant;
6197
+ queue.push( position );
6198
+ }, this );
6199
+
6200
+ this._processLayoutQueue( queue );
6201
+ };
6202
+
6203
+ /**
6204
+ * get item layout position
6205
+ * @param {Outlayer.Item} item
6206
+ * @returns {Object} x and y position
6207
+ */
6208
+ proto._getItemLayoutPosition = function( /* item */ ) {
6209
+ return {
6210
+ x: 0,
6211
+ y: 0
6212
+ };
6213
+ };
6214
+
6215
+ /**
6216
+ * iterate over array and position each item
6217
+ * Reason being - separating this logic prevents 'layout invalidation'
6218
+ * thx @paul_irish
6219
+ * @param {Array} queue
6220
+ */
6221
+ proto._processLayoutQueue = function( queue ) {
6222
+ this.updateStagger();
6223
+ queue.forEach( function( obj, i ) {
6224
+ this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );
6225
+ }, this );
6226
+ };
6227
+
6228
+ // set stagger from option in milliseconds number
6229
+ proto.updateStagger = function() {
6230
+ var stagger = this.options.stagger;
6231
+ if ( stagger === null || stagger === undefined ) {
6232
+ this.stagger = 0;
6233
+ return;
6234
+ }
6235
+ this.stagger = getMilliseconds( stagger );
6236
+ return this.stagger;
6237
+ };
6238
+
6239
+ /**
6240
+ * Sets position of item in DOM
6241
+ * @param {Outlayer.Item} item
6242
+ * @param {Number} x - horizontal position
6243
+ * @param {Number} y - vertical position
6244
+ * @param {Boolean} isInstant - disables transitions
6245
+ */
6246
+ proto._positionItem = function( item, x, y, isInstant, i ) {
6247
+ if ( isInstant ) {
6248
+ // if not transition, just set CSS
6249
+ item.goTo( x, y );
6250
+ } else {
6251
+ item.stagger( i * this.stagger );
6252
+ item.moveTo( x, y );
6253
+ }
6254
+ };
6255
+
6256
+ /**
6257
+ * Any logic you want to do after each layout,
6258
+ * i.e. size the container
6259
+ */
6260
+ proto._postLayout = function() {
6261
+ this.resizeContainer();
6262
+ };
6263
+
6264
+ proto.resizeContainer = function() {
6265
+ var isResizingContainer = this._getOption('resizeContainer');
6266
+ if ( !isResizingContainer ) {
6267
+ return;
6268
+ }
6269
+ var size = this._getContainerSize();
6270
+ if ( size ) {
6271
+ this._setContainerMeasure( size.width, true );
6272
+ this._setContainerMeasure( size.height, false );
6273
+ }
6274
+ };
6275
+
6276
+ /**
6277
+ * Sets width or height of container if returned
6278
+ * @returns {Object} size
6279
+ * @param {Number} width
6280
+ * @param {Number} height
6281
+ */
6282
+ proto._getContainerSize = noop;
6283
+
6284
+ /**
6285
+ * @param {Number} measure - size of width or height
6286
+ * @param {Boolean} isWidth
6287
+ */
6288
+ proto._setContainerMeasure = function( measure, isWidth ) {
6289
+ if ( measure === undefined ) {
6290
+ return;
6291
+ }
6292
+
6293
+ var elemSize = this.size;
6294
+ // add padding and border width if border box
6295
+ if ( elemSize.isBorderBox ) {
6296
+ measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
6297
+ elemSize.borderLeftWidth + elemSize.borderRightWidth :
6298
+ elemSize.paddingBottom + elemSize.paddingTop +
6299
+ elemSize.borderTopWidth + elemSize.borderBottomWidth;
6300
+ }
6301
+
6302
+ measure = Math.max( measure, 0 );
6303
+ this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
6304
+ };
6305
+
6306
+ /**
6307
+ * emit eventComplete on a collection of items events
6308
+ * @param {String} eventName
6309
+ * @param {Array} items - Outlayer.Items
6310
+ */
6311
+ proto._emitCompleteOnItems = function( eventName, items ) {
6312
+ var _this = this;
6313
+ function onComplete() {
6314
+ _this.dispatchEvent( eventName + 'Complete', null, [ items ] );
6315
+ }
6316
+
6317
+ var count = items.length;
6318
+ if ( !items || !count ) {
6319
+ onComplete();
6320
+ return;
6321
+ }
6322
+
6323
+ var doneCount = 0;
6324
+ function tick() {
6325
+ doneCount++;
6326
+ if ( doneCount == count ) {
6327
+ onComplete();
6328
+ }
6329
+ }
6330
+
6331
+ // bind callback
6332
+ items.forEach( function( item ) {
6333
+ item.once( eventName, tick );
6334
+ });
6335
+ };
6336
+
6337
+ /**
6338
+ * emits events via EvEmitter and jQuery events
6339
+ * @param {String} type - name of event
6340
+ * @param {Event} event - original event
6341
+ * @param {Array} args - extra arguments
6342
+ */
6343
+ proto.dispatchEvent = function( type, event, args ) {
6344
+ // add original event to arguments
6345
+ var emitArgs = event ? [ event ].concat( args ) : args;
6346
+ this.emitEvent( type, emitArgs );
6347
+
6348
+ if ( jQuery ) {
6349
+ // set this.$element
6350
+ this.$element = this.$element || jQuery( this.element );
6351
+ if ( event ) {
6352
+ // create jQuery event
6353
+ var $event = jQuery.Event( event );
6354
+ $event.type = type;
6355
+ this.$element.trigger( $event, args );
6356
+ } else {
6357
+ // just trigger with type if no event available
6358
+ this.$element.trigger( type, args );
6359
+ }
6360
+ }
6361
+ };
6362
+
6363
+ // -------------------------- ignore & stamps -------------------------- //
6364
+
6365
+
6366
+ /**
6367
+ * keep item in collection, but do not lay it out
6368
+ * ignored items do not get skipped in layout
6369
+ * @param {Element} elem
6370
+ */
6371
+ proto.ignore = function( elem ) {
6372
+ var item = this.getItem( elem );
6373
+ if ( item ) {
6374
+ item.isIgnored = true;
6375
+ }
6376
+ };
6377
+
6378
+ /**
6379
+ * return item to layout collection
6380
+ * @param {Element} elem
6381
+ */
6382
+ proto.unignore = function( elem ) {
6383
+ var item = this.getItem( elem );
6384
+ if ( item ) {
6385
+ delete item.isIgnored;
6386
+ }
6387
+ };
6388
+
6389
+ /**
6390
+ * adds elements to stamps
6391
+ * @param {NodeList, Array, Element, or String} elems
6392
+ */
6393
+ proto.stamp = function( elems ) {
6394
+ elems = this._find( elems );
6395
+ if ( !elems ) {
6396
+ return;
6397
+ }
6398
+
6399
+ this.stamps = this.stamps.concat( elems );
6400
+ // ignore
6401
+ elems.forEach( this.ignore, this );
6402
+ };
6403
+
6404
+ /**
6405
+ * removes elements to stamps
6406
+ * @param {NodeList, Array, or Element} elems
6407
+ */
6408
+ proto.unstamp = function( elems ) {
6409
+ elems = this._find( elems );
6410
+ if ( !elems ){
6411
+ return;
6412
+ }
6413
+
6414
+ elems.forEach( function( elem ) {
6415
+ // filter out removed stamp elements
6416
+ utils.removeFrom( this.stamps, elem );
6417
+ this.unignore( elem );
6418
+ }, this );
6419
+ };
6420
+
6421
+ /**
6422
+ * finds child elements
6423
+ * @param {NodeList, Array, Element, or String} elems
6424
+ * @returns {Array} elems
6425
+ */
6426
+ proto._find = function( elems ) {
6427
+ if ( !elems ) {
6428
+ return;
6429
+ }
6430
+ // if string, use argument as selector string
6431
+ if ( typeof elems == 'string' ) {
6432
+ elems = this.element.querySelectorAll( elems );
6433
+ }
6434
+ elems = utils.makeArray( elems );
6435
+ return elems;
6436
+ };
6437
+
6438
+ proto._manageStamps = function() {
6439
+ if ( !this.stamps || !this.stamps.length ) {
6440
+ return;
6441
+ }
6442
+
6443
+ this._getBoundingRect();
6444
+
6445
+ this.stamps.forEach( this._manageStamp, this );
6446
+ };
6447
+
6448
+ // update boundingLeft / Top
6449
+ proto._getBoundingRect = function() {
6450
+ // get bounding rect for container element
6451
+ var boundingRect = this.element.getBoundingClientRect();
6452
+ var size = this.size;
6453
+ this._boundingRect = {
6454
+ left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
6455
+ top: boundingRect.top + size.paddingTop + size.borderTopWidth,
6456
+ right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
6457
+ bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
6458
+ };
6459
+ };
6460
+
6461
+ /**
6462
+ * @param {Element} stamp
6463
+ **/
6464
+ proto._manageStamp = noop;
6465
+
6466
+ /**
6467
+ * get x/y position of element relative to container element
6468
+ * @param {Element} elem
6469
+ * @returns {Object} offset - has left, top, right, bottom
6470
+ */
6471
+ proto._getElementOffset = function( elem ) {
6472
+ var boundingRect = elem.getBoundingClientRect();
6473
+ var thisRect = this._boundingRect;
6474
+ var size = getSize( elem );
6475
+ var offset = {
6476
+ left: boundingRect.left - thisRect.left - size.marginLeft,
6477
+ top: boundingRect.top - thisRect.top - size.marginTop,
6478
+ right: thisRect.right - boundingRect.right - size.marginRight,
6479
+ bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
6480
+ };
6481
+ return offset;
6482
+ };
6483
+
6484
+ // -------------------------- resize -------------------------- //
6485
+
6486
+ // enable event handlers for listeners
6487
+ // i.e. resize -> onresize
6488
+ proto.handleEvent = utils.handleEvent;
6489
+
6490
+ /**
6491
+ * Bind layout to window resizing
6492
+ */
6493
+ proto.bindResize = function() {
6494
+ window.addEventListener( 'resize', this );
6495
+ this.isResizeBound = true;
6496
+ };
6497
+
6498
+ /**
6499
+ * Unbind layout to window resizing
6500
+ */
6501
+ proto.unbindResize = function() {
6502
+ window.removeEventListener( 'resize', this );
6503
+ this.isResizeBound = false;
6504
+ };
6505
+
6506
+ proto.onresize = function() {
6507
+ this.resize();
6508
+ };
6509
+
6510
+ utils.debounceMethod( Outlayer, 'onresize', 100 );
6511
+
6512
+ proto.resize = function() {
6513
+ // don't trigger if size did not change
6514
+ // or if resize was unbound. See #9
6515
+ if ( !this.isResizeBound || !this.needsResizeLayout() ) {
6516
+ return;
6517
+ }
6518
+
6519
+ this.layout();
6520
+ };
6521
+
6522
+ /**
6523
+ * check if layout is needed post layout
6524
+ * @returns Boolean
6525
+ */
6526
+ proto.needsResizeLayout = function() {
6527
+ var size = getSize( this.element );
6528
+ // check that this.size and size are there
6529
+ // IE8 triggers resize on body size change, so they might not be
6530
+ var hasSizes = this.size && size;
6531
+ return hasSizes && size.innerWidth !== this.size.innerWidth;
6532
+ };
6533
+
6534
+ // -------------------------- methods -------------------------- //
6535
+
6536
+ /**
6537
+ * add items to Outlayer instance
6538
+ * @param {Array or NodeList or Element} elems
6539
+ * @returns {Array} items - Outlayer.Items
6540
+ **/
6541
+ proto.addItems = function( elems ) {
6542
+ var items = this._itemize( elems );
6543
+ // add items to collection
6544
+ if ( items.length ) {
6545
+ this.items = this.items.concat( items );
6546
+ }
6547
+ return items;
6548
+ };
6549
+
6550
+ /**
6551
+ * Layout newly-appended item elements
6552
+ * @param {Array or NodeList or Element} elems
6553
+ */
6554
+ proto.appended = function( elems ) {
6555
+ var items = this.addItems( elems );
6556
+ if ( !items.length ) {
6557
+ return;
6558
+ }
6559
+ // layout and reveal just the new items
6560
+ this.layoutItems( items, true );
6561
+ this.reveal( items );
6562
+ };
6563
+
6564
+ /**
6565
+ * Layout prepended elements
6566
+ * @param {Array or NodeList or Element} elems
6567
+ */
6568
+ proto.prepended = function( elems ) {
6569
+ var items = this._itemize( elems );
6570
+ if ( !items.length ) {
6571
+ return;
6572
+ }
6573
+ // add items to beginning of collection
6574
+ var previousItems = this.items.slice(0);
6575
+ this.items = items.concat( previousItems );
6576
+ // start new layout
6577
+ this._resetLayout();
6578
+ this._manageStamps();
6579
+ // layout new stuff without transition
6580
+ this.layoutItems( items, true );
6581
+ this.reveal( items );
6582
+ // layout previous items
6583
+ this.layoutItems( previousItems );
6584
+ };
6585
+
6586
+ /**
6587
+ * reveal a collection of items
6588
+ * @param {Array of Outlayer.Items} items
6589
+ */
6590
+ proto.reveal = function( items ) {
6591
+ this._emitCompleteOnItems( 'reveal', items );
6592
+ if ( !items || !items.length ) {
6593
+ return;
6594
+ }
6595
+ var stagger = this.updateStagger();
6596
+ items.forEach( function( item, i ) {
6597
+ item.stagger( i * stagger );
6598
+ item.reveal();
6599
+ });
6600
+ };
6601
+
6602
+ /**
6603
+ * hide a collection of items
6604
+ * @param {Array of Outlayer.Items} items
6605
+ */
6606
+ proto.hide = function( items ) {
6607
+ this._emitCompleteOnItems( 'hide', items );
6608
+ if ( !items || !items.length ) {
6609
+ return;
6610
+ }
6611
+ var stagger = this.updateStagger();
6612
+ items.forEach( function( item, i ) {
6613
+ item.stagger( i * stagger );
6614
+ item.hide();
6615
+ });
6616
+ };
6617
+
6618
+ /**
6619
+ * reveal item elements
6620
+ * @param {Array}, {Element}, {NodeList} items
6621
+ */
6622
+ proto.revealItemElements = function( elems ) {
6623
+ var items = this.getItems( elems );
6624
+ this.reveal( items );
6625
+ };
6626
+
6627
+ /**
6628
+ * hide item elements
6629
+ * @param {Array}, {Element}, {NodeList} items
6630
+ */
6631
+ proto.hideItemElements = function( elems ) {
6632
+ var items = this.getItems( elems );
6633
+ this.hide( items );
6634
+ };
6635
+
6636
+ /**
6637
+ * get Outlayer.Item, given an Element
6638
+ * @param {Element} elem
6639
+ * @param {Function} callback
6640
+ * @returns {Outlayer.Item} item
6641
+ */
6642
+ proto.getItem = function( elem ) {
6643
+ // loop through items to get the one that matches
6644
+ for ( var i=0; i < this.items.length; i++ ) {
6645
+ var item = this.items[i];
6646
+ if ( item.element == elem ) {
6647
+ // return item
6648
+ return item;
6649
+ }
6650
+ }
6651
+ };
6652
+
6653
+ /**
6654
+ * get collection of Outlayer.Items, given Elements
6655
+ * @param {Array} elems
6656
+ * @returns {Array} items - Outlayer.Items
6657
+ */
6658
+ proto.getItems = function( elems ) {
6659
+ elems = utils.makeArray( elems );
6660
+ var items = [];
6661
+ elems.forEach( function( elem ) {
6662
+ var item = this.getItem( elem );
6663
+ if ( item ) {
6664
+ items.push( item );
6665
+ }
6666
+ }, this );
6667
+
6668
+ return items;
6669
+ };
6670
+
6671
+ /**
6672
+ * remove element(s) from instance and DOM
6673
+ * @param {Array or NodeList or Element} elems
6674
+ */
6675
+ proto.remove = function( elems ) {
6676
+ var removeItems = this.getItems( elems );
6677
+
6678
+ this._emitCompleteOnItems( 'remove', removeItems );
6679
+
6680
+ // bail if no items to remove
6681
+ if ( !removeItems || !removeItems.length ) {
6682
+ return;
6683
+ }
6684
+
6685
+ removeItems.forEach( function( item ) {
6686
+ item.remove();
6687
+ // remove item from collection
6688
+ utils.removeFrom( this.items, item );
6689
+ }, this );
6690
+ };
6691
+
6692
+ // ----- destroy ----- //
6693
+
6694
+ // remove and disable Outlayer instance
6695
+ proto.destroy = function() {
6696
+ // clean up dynamic styles
6697
+ var style = this.element.style;
6698
+ style.height = '';
6699
+ style.position = '';
6700
+ style.width = '';
6701
+ // destroy items
6702
+ this.items.forEach( function( item ) {
6703
+ item.destroy();
6704
+ });
6705
+
6706
+ this.unbindResize();
6707
+
6708
+ var id = this.element.outlayerGUID;
6709
+ delete instances[ id ]; // remove reference to instance by id
6710
+ delete this.element.outlayerGUID;
6711
+ // remove data for jQuery
6712
+ if ( jQuery ) {
6713
+ jQuery.removeData( this.element, this.constructor.namespace );
6714
+ }
6715
+
6716
+ };
6717
+
6718
+ // -------------------------- data -------------------------- //
6719
+
6720
+ /**
6721
+ * get Outlayer instance from element
6722
+ * @param {Element} elem
6723
+ * @returns {Outlayer}
6724
+ */
6725
+ Outlayer.data = function( elem ) {
6726
+ elem = utils.getQueryElement( elem );
6727
+ var id = elem && elem.outlayerGUID;
6728
+ return id && instances[ id ];
6729
+ };
6730
+
6731
+
6732
+ // -------------------------- create Outlayer class -------------------------- //
6733
+
6734
+ /**
6735
+ * create a layout class
6736
+ * @param {String} namespace
6737
+ */
6738
+ Outlayer.create = function( namespace, options ) {
6739
+ // sub-class Outlayer
6740
+ var Layout = subclass( Outlayer );
6741
+ // apply new options and compatOptions
6742
+ Layout.defaults = utils.extend( {}, Outlayer.defaults );
6743
+ utils.extend( Layout.defaults, options );
6744
+ Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions );
6745
+
6746
+ Layout.namespace = namespace;
6747
+
6748
+ Layout.data = Outlayer.data;
6749
+
6750
+ // sub-class Item
6751
+ Layout.Item = subclass( Item );
6752
+
6753
+ // -------------------------- declarative -------------------------- //
6754
+
6755
+ utils.htmlInit( Layout, namespace );
6756
+
6757
+ // -------------------------- jQuery bridge -------------------------- //
6758
+
6759
+ // make into jQuery plugin
6760
+ if ( jQuery && jQuery.bridget ) {
6761
+ jQuery.bridget( namespace, Layout );
6762
+ }
6763
+
6764
+ return Layout;
6765
+ };
6766
+
6767
+ function subclass( Parent ) {
6768
+ function SubClass() {
6769
+ Parent.apply( this, arguments );
6770
+ }
6771
+
6772
+ SubClass.prototype = Object.create( Parent.prototype );
6773
+ SubClass.prototype.constructor = SubClass;
6774
+
6775
+ return SubClass;
6776
+ }
6777
+
6778
+ // ----- helpers ----- //
6779
+
6780
+ // how many milliseconds are in each unit
6781
+ var msUnits = {
6782
+ ms: 1,
6783
+ s: 1000
6784
+ };
6785
+
6786
+ // munge time-like parameter into millisecond number
6787
+ // '0.4s' -> 40
6788
+ function getMilliseconds( time ) {
6789
+ if ( typeof time == 'number' ) {
6790
+ return time;
6791
+ }
6792
+ var matches = time.match( /(^\d*\.?\d*)(\w*)/ );
6793
+ var num = matches && matches[1];
6794
+ var unit = matches && matches[2];
6795
+ if ( !num.length ) {
6796
+ return 0;
6797
+ }
6798
+ num = parseFloat( num );
6799
+ var mult = msUnits[ unit ] || 1;
6800
+ return num * mult;
6801
+ }
6802
+
6803
+ // ----- fin ----- //
6804
+
6805
+ // back in global
6806
+ Outlayer.Item = Item;
6807
+
6808
+ return Outlayer;
6809
+
6810
+ }));
6811
+
6812
+ /**
6813
+ * Enviratope Item
6814
+ **/
6815
+
6816
+ ( function( window, factory ) {
6817
+ // universal module definition
6818
+ /* jshint strict: false */ /*globals define, module, require */
6819
+ if ( typeof define == 'function' && define.amd ) {
6820
+ // AMD
6821
+ define( 'enviratope/item',[
6822
+ 'outlayer/outlayer'
6823
+ ],
6824
+ factory );
6825
+ } else if ( typeof module == 'object' && module.exports ) {
6826
+ // CommonJS
6827
+ module.exports = factory(
6828
+ require('outlayer')
6829
+ );
6830
+ } else {
6831
+ // browser global
6832
+ window.Enviratope = window.Enviratope || {};
6833
+ window.Enviratope.Item = factory(
6834
+ window.Outlayer
6835
+ );
6836
+ }
6837
+
6838
+ }( window, function factory( Outlayer ) {
6839
+ 'use strict';
6840
+
6841
+ // -------------------------- Item -------------------------- //
6842
+
6843
+ // sub-class Outlayer Item
6844
+ function Item() {
6845
+ Outlayer.Item.apply( this, arguments );
6846
+ }
6847
+
6848
+ var proto = Item.prototype = Object.create( Outlayer.Item.prototype );
6849
+
6850
+ var _create = proto._create;
6851
+ proto._create = function() {
6852
+ // assign id, used for original-order sorting
6853
+ this.id = this.layout.itemGUID++;
6854
+ _create.call( this );
6855
+ this.sortData = {};
6856
+ };
6857
+
6858
+ proto.updateSortData = function() {
6859
+ if ( this.isIgnored ) {
6860
+ return;
6861
+ }
6862
+ // default sorters
6863
+ this.sortData.id = this.id;
6864
+ // for backward compatibility
6865
+ this.sortData['original-order'] = this.id;
6866
+ this.sortData.random = Math.random();
6867
+ // go thru getSortData obj and apply the sorters
6868
+ var getSortData = this.layout.options.getSortData;
6869
+ var sorters = this.layout._sorters;
6870
+ for ( var key in getSortData ) {
6871
+ var sorter = sorters[ key ];
6872
+ this.sortData[ key ] = sorter( this.element, this );
6873
+ }
6874
+ };
6875
+
6876
+ var _destroy = proto.destroy;
6877
+ proto.destroy = function() {
6878
+ // call super
6879
+ _destroy.apply( this, arguments );
6880
+ // reset display, #741
6881
+ this.css({
6882
+ display: ''
6883
+ });
6884
+ };
6885
+
6886
+ return Item;
6887
+
6888
+ }));
6889
+
6890
+ /**
6891
+ * Enviratope LayoutMode
6892
+ */
6893
+
6894
+ ( function( window, factory ) {
6895
+ // universal module definition
6896
+ /* jshint strict: false */ /*globals define, module, require */
6897
+ if ( typeof define == 'function' && define.amd ) {
6898
+ // AMD
6899
+ define( 'enviratope/layout-mode',[
6900
+ 'get-size/get-size',
6901
+ 'outlayer/outlayer'
6902
+ ],
6903
+ factory );
6904
+ } else if ( typeof module == 'object' && module.exports ) {
6905
+ // CommonJS
6906
+ module.exports = factory(
6907
+ require('get-size'),
6908
+ require('outlayer')
6909
+ );
6910
+ } else {
6911
+ // browser global
6912
+ window.Enviratope = window.Enviratope || {};
6913
+ window.Enviratope.LayoutMode = factory(
6914
+ window.getSize,
6915
+ window.Outlayer
6916
+ );
6917
+ }
6918
+
6919
+ }( window, function factory( getSize, Outlayer ) {
6920
+ 'use strict';
6921
+
6922
+ // layout mode class
6923
+ function LayoutMode( enviratope ) {
6924
+ this.enviratope = enviratope;
6925
+ // link properties
6926
+ if ( enviratope ) {
6927
+ this.options = enviratope.options[ this.namespace ];
6928
+ this.element = enviratope.element;
6929
+ this.items = enviratope.filteredItems;
6930
+ this.size = enviratope.size;
6931
+ }
6932
+ }
6933
+
6934
+ var proto = LayoutMode.prototype;
6935
+
6936
+ /**
6937
+ * some methods should just defer to default Outlayer method
6938
+ * and reference the Enviratope instance as `this`
6939
+ **/
6940
+ var facadeMethods = [
6941
+ '_resetLayout',
6942
+ '_getItemLayoutPosition',
6943
+ '_manageStamp',
6944
+ '_getContainerSize',
6945
+ '_getElementOffset',
6946
+ 'needsResizeLayout',
6947
+ '_getOption'
6948
+ ];
6949
+
6950
+ facadeMethods.forEach( function( methodName ) {
6951
+ proto[ methodName ] = function() {
6952
+ return Outlayer.prototype[ methodName ].apply( this.enviratope, arguments );
6953
+ };
6954
+ });
6955
+
6956
+ // ----- ----- //
6957
+
6958
+ // for horizontal layout modes, check vertical size
6959
+ proto.needsVerticalResizeLayout = function() {
6960
+ // don't trigger if size did not change
6961
+ var size = getSize( this.enviratope.element );
6962
+ // check that this.size and size are there
6963
+ // IE8 triggers resize on body size change, so they might not be
6964
+ var hasSizes = this.enviratope.size && size;
6965
+ return hasSizes && size.innerHeight != this.enviratope.size.innerHeight;
6966
+ };
6967
+
6968
+ // ----- measurements ----- //
6969
+
6970
+ proto._getMeasurement = function() {
6971
+ this.enviratope._getMeasurement.apply( this, arguments );
6972
+ };
6973
+
6974
+ proto.getColumnWidth = function() {
6975
+ this.getSegmentSize( 'column', 'Width' );
6976
+ };
6977
+
6978
+ proto.getRowHeight = function() {
6979
+ this.getSegmentSize( 'row', 'Height' );
6980
+ };
6981
+
6982
+ /**
6983
+ * get columnWidth or rowHeight
6984
+ * segment: 'column' or 'row'
6985
+ * size 'Width' or 'Height'
6986
+ **/
6987
+ proto.getSegmentSize = function( segment, size ) {
6988
+ var segmentName = segment + size;
6989
+ var outerSize = 'outer' + size;
6990
+ // columnWidth / outerWidth // rowHeight / outerHeight
6991
+ this._getMeasurement( segmentName, outerSize );
6992
+ // got rowHeight or columnWidth, we can chill
6993
+ if ( this[ segmentName ] ) {
6994
+ return;
6995
+ }
6996
+ // fall back to item of first element
6997
+ var firstItemSize = this.getFirstItemSize();
6998
+ this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||
6999
+ // or size of container
7000
+ this.enviratope.size[ 'inner' + size ];
7001
+ };
7002
+
7003
+ proto.getFirstItemSize = function() {
7004
+ var firstItem = this.enviratope.filteredItems[0];
7005
+ return firstItem && firstItem.element && getSize( firstItem.element );
7006
+ };
7007
+
7008
+ // ----- methods that should reference enviratope ----- //
7009
+
7010
+ proto.layout = function() {
7011
+ this.enviratope.layout.apply( this.enviratope, arguments );
7012
+ };
7013
+
7014
+ proto.getSize = function() {
7015
+ this.enviratope.getSize();
7016
+ this.size = this.enviratope.size;
7017
+ };
7018
+
7019
+ // -------------------------- create -------------------------- //
7020
+
7021
+ LayoutMode.modes = {};
7022
+
7023
+ LayoutMode.create = function( namespace, options ) {
7024
+
7025
+ function Mode() {
7026
+ LayoutMode.apply( this, arguments );
7027
+ }
7028
+
7029
+ Mode.prototype = Object.create( proto );
7030
+ Mode.prototype.constructor = Mode;
7031
+
7032
+ // default options
7033
+ if ( options ) {
7034
+ Mode.options = options;
7035
+ }
7036
+
7037
+ Mode.prototype.namespace = namespace;
7038
+ // register in Enviratope
7039
+ LayoutMode.modes[ namespace ] = Mode;
7040
+
7041
+ return Mode;
7042
+ };
7043
+
7044
+ return LayoutMode;
7045
+
7046
+ }));
7047
+
7048
+ /*!
7049
+ * Masonry v4.1.0
7050
+ * Cascading grid layout library
7051
+ * http://masonry.desandro.com
7052
+ * MIT License
7053
+ * by David DeSandro
7054
+ */
7055
+
7056
+ ( function( window, factory ) {
7057
+ // universal module definition
7058
+ /* jshint strict: false */ /*globals define, module, require */
7059
+ if ( typeof define == 'function' && define.amd ) {
7060
+ // AMD
7061
+ define( 'masonry/masonry',[
7062
+ 'outlayer/outlayer',
7063
+ 'get-size/get-size'
7064
+ ],
7065
+ factory );
7066
+ } else if ( typeof module == 'object' && module.exports ) {
7067
+ // CommonJS
7068
+ module.exports = factory(
7069
+ require('outlayer'),
7070
+ require('get-size')
7071
+ );
7072
+ } else {
7073
+ // browser global
7074
+ window.Masonry = factory(
7075
+ window.Outlayer,
7076
+ window.getSize
7077
+ );
7078
+ }
7079
+
7080
+ }( window, function factory( Outlayer, getSize ) {
7081
+
7082
+
7083
+
7084
+ // -------------------------- masonryDefinition -------------------------- //
7085
+
7086
+ // create an Outlayer layout class
7087
+ var Masonry = Outlayer.create('masonry');
7088
+ // isFitWidth -> fitWidth
7089
+ Masonry.compatOptions.fitWidth = 'isFitWidth';
7090
+
7091
+ Masonry.prototype._resetLayout = function() {
7092
+ this.getSize();
7093
+ this._getMeasurement( 'columnWidth', 'outerWidth' );
7094
+ this._getMeasurement( 'gutter', 'outerWidth' );
7095
+ this.measureColumns();
7096
+
7097
+ // reset column Y
7098
+ this.colYs = [];
7099
+ for ( var i=0; i < this.cols; i++ ) {
7100
+ this.colYs.push( 0 );
7101
+ }
7102
+
7103
+ this.maxY = 0;
7104
+ };
7105
+
7106
+ Masonry.prototype.measureColumns = function() {
7107
+ this.getContainerWidth();
7108
+ // if columnWidth is 0, default to outerWidth of first item
7109
+ if ( !this.columnWidth ) {
7110
+ var firstItem = this.items[0];
7111
+ var firstItemElem = firstItem && firstItem.element;
7112
+ // columnWidth fall back to item of first element
7113
+ this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
7114
+ // if first elem has no width, default to size of container
7115
+ this.containerWidth;
7116
+ }
7117
+
7118
+ var columnWidth = this.columnWidth += this.gutter;
7119
+
7120
+ // calculate columns
7121
+ var containerWidth = this.containerWidth + this.gutter;
7122
+ var cols = containerWidth / columnWidth;
7123
+ // fix rounding errors, typically with gutters
7124
+ var excess = columnWidth - containerWidth % columnWidth;
7125
+ // if overshoot is less than a pixel, round up, otherwise floor it
7126
+ var mathMethod = excess && excess < 1 ? 'round' : 'floor';
7127
+ cols = Math[ mathMethod ]( cols );
7128
+ this.cols = Math.max( cols, 1 );
7129
+ };
7130
+
7131
+ Masonry.prototype.getContainerWidth = function() {
7132
+ // container is parent if fit width
7133
+ var isFitWidth = this._getOption('fitWidth');
7134
+ var container = isFitWidth ? this.element.parentNode : this.element;
7135
+ // check that this.size and size are there
7136
+ // IE8 triggers resize on body size change, so they might not be
7137
+ var size = getSize( container );
7138
+ this.containerWidth = size && size.innerWidth;
7139
+ };
7140
+
7141
+ Masonry.prototype._getItemLayoutPosition = function( item ) {
7142
+ item.getSize();
7143
+ // how many columns does this brick span
7144
+ var remainder = item.size.outerWidth % this.columnWidth;
7145
+ var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
7146
+ // round if off by 1 pixel, otherwise use ceil
7147
+ var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
7148
+ colSpan = Math.min( colSpan, this.cols );
7149
+
7150
+ var colGroup = this._getColGroup( colSpan );
7151
+ // get the minimum Y value from the columns
7152
+ var minimumY = Math.min.apply( Math, colGroup );
7153
+ var shortColIndex = colGroup.indexOf( minimumY );
7154
+
7155
+ // position the brick
7156
+ var position = {
7157
+ x: this.columnWidth * shortColIndex,
7158
+ y: minimumY
7159
+ };
7160
+
7161
+ // apply setHeight to necessary columns
7162
+ var setHeight = minimumY + item.size.outerHeight;
7163
+ var setSpan = this.cols + 1 - colGroup.length;
7164
+ for ( var i = 0; i < setSpan; i++ ) {
7165
+ this.colYs[ shortColIndex + i ] = setHeight;
7166
+ }
7167
+
7168
+ return position;
7169
+ };
7170
+
7171
+ /**
7172
+ * @param {Number} colSpan - number of columns the element spans
7173
+ * @returns {Array} colGroup
7174
+ */
7175
+ Masonry.prototype._getColGroup = function( colSpan ) {
7176
+ if ( colSpan < 2 ) {
7177
+ // if brick spans only one column, use all the column Ys
7178
+ return this.colYs;
7179
+ }
7180
+
7181
+ var colGroup = [];
7182
+ // how many different places could this brick fit horizontally
7183
+ var groupCount = this.cols + 1 - colSpan;
7184
+ // for each group potential horizontal position
7185
+ for ( var i = 0; i < groupCount; i++ ) {
7186
+ // make an array of colY values for that one group
7187
+ var groupColYs = this.colYs.slice( i, i + colSpan );
7188
+ // and get the max value of the array
7189
+ colGroup[i] = Math.max.apply( Math, groupColYs );
7190
+ }
7191
+ return colGroup;
7192
+ };
7193
+
7194
+ Masonry.prototype._manageStamp = function( stamp ) {
7195
+ var stampSize = getSize( stamp );
7196
+ var offset = this._getElementOffset( stamp );
7197
+ // get the columns that this stamp affects
7198
+ var isOriginLeft = this._getOption('originLeft');
7199
+ var firstX = isOriginLeft ? offset.left : offset.right;
7200
+ var lastX = firstX + stampSize.outerWidth;
7201
+ var firstCol = Math.floor( firstX / this.columnWidth );
7202
+ firstCol = Math.max( 0, firstCol );
7203
+ var lastCol = Math.floor( lastX / this.columnWidth );
7204
+ // lastCol should not go over if multiple of columnWidth #425
7205
+ lastCol -= lastX % this.columnWidth ? 0 : 1;
7206
+ lastCol = Math.min( this.cols - 1, lastCol );
7207
+ // set colYs to bottom of the stamp
7208
+
7209
+ var isOriginTop = this._getOption('originTop');
7210
+ var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) +
7211
+ stampSize.outerHeight;
7212
+ for ( var i = firstCol; i <= lastCol; i++ ) {
7213
+ this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
7214
+ }
7215
+ };
7216
+
7217
+ Masonry.prototype._getContainerSize = function() {
7218
+ this.maxY = Math.max.apply( Math, this.colYs );
7219
+ var size = {
7220
+ height: this.maxY
7221
+ };
7222
+
7223
+ if ( this._getOption('fitWidth') ) {
7224
+ size.width = this._getContainerFitWidth();
7225
+ }
7226
+
7227
+ return size;
7228
+ };
7229
+
7230
+ Masonry.prototype._getContainerFitWidth = function() {
7231
+ var unusedCols = 0;
7232
+ // count unused columns
7233
+ var i = this.cols;
7234
+ while ( --i ) {
7235
+ if ( this.colYs[i] !== 0 ) {
7236
+ break;
7237
+ }
7238
+ unusedCols++;
7239
+ }
7240
+ // fit container to columns that have been used
7241
+ return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
7242
+ };
7243
+
7244
+ Masonry.prototype.needsResizeLayout = function() {
7245
+ var previousWidth = this.containerWidth;
7246
+ this.getContainerWidth();
7247
+ return previousWidth != this.containerWidth;
7248
+ };
7249
+
7250
+ return Masonry;
7251
+
7252
+ }));
7253
+
7254
+ /*!
7255
+ * Masonry layout mode
7256
+ * sub-classes Masonry
7257
+ * http://masonry.desandro.com
7258
+ */
7259
+
7260
+ ( function( window, factory ) {
7261
+ // universal module definition
7262
+ /* jshint strict: false */ /*globals define, module, require */
7263
+ if ( typeof define == 'function' && define.amd ) {
7264
+ // AMD
7265
+ define( 'enviratope/layout-modes/masonry',[
7266
+ '../layout-mode',
7267
+ 'masonry/masonry'
7268
+ ],
7269
+ factory );
7270
+ } else if ( typeof module == 'object' && module.exports ) {
7271
+ // CommonJS
7272
+ module.exports = factory(
7273
+ require('../layout-mode'),
7274
+ require('masonry-layout')
7275
+ );
7276
+ } else {
7277
+ // browser global
7278
+ factory(
7279
+ window.Enviratope.LayoutMode,
7280
+ window.Masonry
7281
+ );
7282
+ }
7283
+
7284
+ }( window, function factory( LayoutMode, Masonry ) {
7285
+ 'use strict';
7286
+
7287
+ // -------------------------- masonryDefinition -------------------------- //
7288
+
7289
+ // create an Outlayer layout class
7290
+ var MasonryMode = LayoutMode.create('masonry');
7291
+
7292
+ var proto = MasonryMode.prototype;
7293
+
7294
+ var keepModeMethods = {
7295
+ _getElementOffset: true,
7296
+ layout: true,
7297
+ _getMeasurement: true
7298
+ };
7299
+
7300
+ // inherit Masonry prototype
7301
+ for ( var method in Masonry.prototype ) {
7302
+ // do not inherit mode methods
7303
+ if ( !keepModeMethods[ method ] ) {
7304
+ proto[ method ] = Masonry.prototype[ method ];
7305
+ }
7306
+ }
7307
+
7308
+ var measureColumns = proto.measureColumns;
7309
+ proto.measureColumns = function() {
7310
+ // set items, used if measuring first item
7311
+ this.items = this.enviratope.filteredItems;
7312
+ measureColumns.call( this );
7313
+ };
7314
+
7315
+ // point to mode options for fitWidth
7316
+ var _getOption = proto._getOption;
7317
+ proto._getOption = function( option ) {
7318
+ if ( option == 'fitWidth' ) {
7319
+ return this.options.isFitWidth !== undefined ?
7320
+ this.options.isFitWidth : this.options.fitWidth;
7321
+ }
7322
+ return _getOption.apply( this.enviratope, arguments );
7323
+ };
7324
+
7325
+ return MasonryMode;
7326
+
7327
+ }));
7328
+
7329
+ /**
7330
+ * fitRows layout mode
7331
+ */
7332
+
7333
+ ( function( window, factory ) {
7334
+ // universal module definition
7335
+ /* jshint strict: false */ /*globals define, module, require */
7336
+ if ( typeof define == 'function' && define.amd ) {
7337
+ // AMD
7338
+ define( 'enviratope/layout-modes/fit-rows',[
7339
+ '../layout-mode'
7340
+ ],
7341
+ factory );
7342
+ } else if ( typeof exports == 'object' ) {
7343
+ // CommonJS
7344
+ module.exports = factory(
7345
+ require('../layout-mode')
7346
+ );
7347
+ } else {
7348
+ // browser global
7349
+ factory(
7350
+ window.Enviratope.LayoutMode
7351
+ );
7352
+ }
7353
+
7354
+ }( window, function factory( LayoutMode ) {
7355
+ 'use strict';
7356
+
7357
+ var FitRows = LayoutMode.create('fitRows');
7358
+
7359
+ var proto = FitRows.prototype;
7360
+
7361
+ proto._resetLayout = function() {
7362
+ this.x = 0;
7363
+ this.y = 0;
7364
+ this.maxY = 0;
7365
+ this._getMeasurement( 'gutter', 'outerWidth' );
7366
+ };
7367
+
7368
+ proto._getItemLayoutPosition = function( item ) {
7369
+ item.getSize();
7370
+
7371
+ var itemWidth = item.size.outerWidth + this.gutter;
7372
+ // if this element cannot fit in the current row
7373
+ var containerWidth = this.enviratope.size.innerWidth + this.gutter;
7374
+ if ( this.x !== 0 && itemWidth + this.x > containerWidth ) {
7375
+ this.x = 0;
7376
+ this.y = this.maxY;
7377
+ }
7378
+
7379
+ var position = {
7380
+ x: this.x,
7381
+ y: this.y
7382
+ };
7383
+
7384
+ this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight );
7385
+ this.x += itemWidth;
7386
+
7387
+ return position;
7388
+ };
7389
+
7390
+ proto._getContainerSize = function() {
7391
+ return { height: this.maxY };
7392
+ };
7393
+
7394
+ return FitRows;
7395
+
7396
+ }));
7397
+
7398
+ /**
7399
+ * vertical layout mode
7400
+ */
7401
+
7402
+ ( function( window, factory ) {
7403
+ // universal module definition
7404
+ /* jshint strict: false */ /*globals define, module, require */
7405
+ if ( typeof define == 'function' && define.amd ) {
7406
+ // AMD
7407
+ define( 'enviratope/layout-modes/vertical',[
7408
+ '../layout-mode'
7409
+ ],
7410
+ factory );
7411
+ } else if ( typeof module == 'object' && module.exports ) {
7412
+ // CommonJS
7413
+ module.exports = factory(
7414
+ require('../layout-mode')
7415
+ );
7416
+ } else {
7417
+ // browser global
7418
+ factory(
7419
+ window.Enviratope.LayoutMode
7420
+ );
7421
+ }
7422
+
7423
+ }( window, function factory( LayoutMode ) {
7424
+ 'use strict';
7425
+
7426
+ var Vertical = LayoutMode.create( 'vertical', {
7427
+ horizontalAlignment: 0
7428
+ });
7429
+
7430
+ var proto = Vertical.prototype;
7431
+
7432
+ proto._resetLayout = function() {
7433
+ this.y = 0;
7434
+ };
7435
+
7436
+ proto._getItemLayoutPosition = function( item ) {
7437
+ item.getSize();
7438
+ var x = ( this.enviratope.size.innerWidth - item.size.outerWidth ) *
7439
+ this.options.horizontalAlignment;
7440
+ var y = this.y;
7441
+ this.y += item.size.outerHeight;
7442
+ return { x: x, y: y };
7443
+ };
7444
+
7445
+ proto._getContainerSize = function() {
7446
+ return { height: this.y };
7447
+ };
7448
+
7449
+ return Vertical;
7450
+
7451
+ }));
7452
+
7453
+ /*!
7454
+ * Enviratope v3.0.0
7455
+ *
7456
+ * Licensed GPLv3 for open source use
7457
+ * or Enviratope Commercial License for commercial use
7458
+ *
7459
+ * http://enviratope.metafizzy.co
7460
+ * Copyright 2016 Metafizzy
7461
+ */
7462
+
7463
+ ( function( window, factory ) {
7464
+ // universal module definition
7465
+ /* jshint strict: false */ /*globals define, module, require */
7466
+ if ( typeof define == 'function' && define.amd ) {
7467
+ // AMD
7468
+ define( [
7469
+ 'outlayer/outlayer',
7470
+ 'get-size/get-size',
7471
+ 'desandro-matches-selector/matches-selector',
7472
+ 'fizzy-ui-utils/utils',
7473
+ './item',
7474
+ './layout-mode',
7475
+ // include default layout modes
7476
+ './layout-modes/masonry',
7477
+ './layout-modes/fit-rows',
7478
+ './layout-modes/vertical'
7479
+ ],
7480
+ function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) {
7481
+ return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode );
7482
+ });
7483
+ } else if ( typeof module == 'object' && module.exports ) {
7484
+ // CommonJS
7485
+ module.exports = factory(
7486
+ window,
7487
+ require('outlayer'),
7488
+ require('get-size'),
7489
+ require('desandro-matches-selector'),
7490
+ require('fizzy-ui-utils'),
7491
+ require('./item'),
7492
+ require('./layout-mode'),
7493
+ // include default layout modes
7494
+ require('./layout-modes/masonry'),
7495
+ require('./layout-modes/fit-rows'),
7496
+ require('./layout-modes/vertical')
7497
+ );
7498
+ } else {
7499
+ // browser global
7500
+ window.Enviratope = factory(
7501
+ window,
7502
+ window.Outlayer,
7503
+ window.getSize,
7504
+ window.matchesSelector,
7505
+ window.fizzyUIUtils,
7506
+ window.Enviratope.Item,
7507
+ window.Enviratope.LayoutMode
7508
+ );
7509
+ }
7510
+
7511
+ }( window, function factory( window, Outlayer, getSize, matchesSelector, utils,
7512
+ Item, LayoutMode ) {
7513
+
7514
+
7515
+
7516
+ // -------------------------- vars -------------------------- //
7517
+
7518
+ var jQuery = window.jQuery;
7519
+
7520
+ // -------------------------- helpers -------------------------- //
7521
+
7522
+ var trim = String.prototype.trim ?
7523
+ function( str ) {
7524
+ return str.trim();
7525
+ } :
7526
+ function( str ) {
7527
+ return str.replace( /^\s+|\s+$/g, '' );
7528
+ };
7529
+
7530
+ // -------------------------- enviratopeDefinition -------------------------- //
7531
+
7532
+ // create an Outlayer layout class
7533
+ var Enviratope = Outlayer.create( 'enviratope', {
7534
+ layoutMode: 'masonry',
7535
+ isJQueryFiltering: true,
7536
+ sortAscending: true
7537
+ });
7538
+
7539
+ Enviratope.Item = Item;
7540
+ Enviratope.LayoutMode = LayoutMode;
7541
+
7542
+ var proto = Enviratope.prototype;
7543
+
7544
+ proto._create = function() {
7545
+ this.itemGUID = 0;
7546
+ // functions that sort items
7547
+ this._sorters = {};
7548
+ this._getSorters();
7549
+ // call super
7550
+ Outlayer.prototype._create.call( this );
7551
+
7552
+ // create layout modes
7553
+ this.modes = {};
7554
+ // start filteredItems with all items
7555
+ this.filteredItems = this.items;
7556
+ // keep of track of sortBys
7557
+ this.sortHistory = [ 'original-order' ];
7558
+ // create from registered layout modes
7559
+ for ( var name in LayoutMode.modes ) {
7560
+ this._initLayoutMode( name );
7561
+ }
7562
+ };
7563
+
7564
+ proto.reloadItems = function() {
7565
+ // reset item ID counter
7566
+ this.itemGUID = 0;
7567
+ // call super
7568
+ Outlayer.prototype.reloadItems.call( this );
7569
+ };
7570
+
7571
+ proto._itemize = function() {
7572
+ var items = Outlayer.prototype._itemize.apply( this, arguments );
7573
+ // assign ID for original-order
7574
+ for ( var i=0; i < items.length; i++ ) {
7575
+ var item = items[i];
7576
+ item.id = this.itemGUID++;
7577
+ }
7578
+ this._updateItemsSortData( items );
7579
+ return items;
7580
+ };
7581
+
7582
+
7583
+ // -------------------------- layout -------------------------- //
7584
+
7585
+ proto._initLayoutMode = function( name ) {
7586
+ var Mode = LayoutMode.modes[ name ];
7587
+ // set mode options
7588
+ // HACK extend initial options, back-fill in default options
7589
+ var initialOpts = this.options[ name ] || {};
7590
+ this.options[ name ] = Mode.options ?
7591
+ utils.extend( Mode.options, initialOpts ) : initialOpts;
7592
+ // init layout mode instance
7593
+ this.modes[ name ] = new Mode( this );
7594
+ };
7595
+
7596
+
7597
+ proto.layout = function() {
7598
+ // if first time doing layout, do all magic
7599
+ if ( !this._isLayoutInited && this._getOption('initLayout') ) {
7600
+ this.arrange();
7601
+ return;
7602
+ }
7603
+ this._layout();
7604
+ };
7605
+
7606
+ // private method to be used in layout() & magic()
7607
+ proto._layout = function() {
7608
+ // don't animate first layout
7609
+ var isInstant = this._getIsInstant();
7610
+ // layout flow
7611
+ this._resetLayout();
7612
+ this._manageStamps();
7613
+ this.layoutItems( this.filteredItems, isInstant );
7614
+
7615
+ // flag for initalized
7616
+ this._isLayoutInited = true;
7617
+ };
7618
+
7619
+ // filter + sort + layout
7620
+ proto.arrange = function( opts ) {
7621
+ // set any options pass
7622
+ this.option( opts );
7623
+ this._getIsInstant();
7624
+ // filter, sort, and layout
7625
+
7626
+ // filter
7627
+ var filtered = this._filter( this.items );
7628
+ this.filteredItems = filtered.matches;
7629
+
7630
+ this._bindArrangeComplete();
7631
+
7632
+ if ( this._isInstant ) {
7633
+ this._noTransition( this._hideReveal, [ filtered ] );
7634
+ } else {
7635
+ this._hideReveal( filtered );
7636
+ }
7637
+
7638
+ this._sort();
7639
+ this._layout();
7640
+ };
7641
+ // alias to _init for main plugin method
7642
+ proto._init = proto.arrange;
7643
+
7644
+ proto._hideReveal = function( filtered ) {
7645
+ this.reveal( filtered.needReveal );
7646
+ this.hide( filtered.needHide );
7647
+ };
7648
+
7649
+ // HACK
7650
+ // Don't animate/transition first layout
7651
+ // Or don't animate/transition other layouts
7652
+ proto._getIsInstant = function() {
7653
+ var isLayoutInstant = this._getOption('layoutInstant');
7654
+ var isInstant = isLayoutInstant !== undefined ? isLayoutInstant :
7655
+ !this._isLayoutInited;
7656
+ this._isInstant = isInstant;
7657
+ return isInstant;
7658
+ };
7659
+
7660
+ // listen for layoutComplete, hideComplete and revealComplete
7661
+ // to trigger arrangeComplete
7662
+ proto._bindArrangeComplete = function() {
7663
+ // listen for 3 events to trigger arrangeComplete
7664
+ var isLayoutComplete, isHideComplete, isRevealComplete;
7665
+ var _this = this;
7666
+ function arrangeParallelCallback() {
7667
+ if ( isLayoutComplete && isHideComplete && isRevealComplete ) {
7668
+ _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] );
7669
+ }
7670
+ }
7671
+ this.once( 'layoutComplete', function() {
7672
+ isLayoutComplete = true;
7673
+ arrangeParallelCallback();
7674
+ });
7675
+ this.once( 'hideComplete', function() {
7676
+ isHideComplete = true;
7677
+ arrangeParallelCallback();
7678
+ });
7679
+ this.once( 'revealComplete', function() {
7680
+ isRevealComplete = true;
7681
+ arrangeParallelCallback();
7682
+ });
7683
+ };
7684
+
7685
+ // -------------------------- filter -------------------------- //
7686
+
7687
+ proto._filter = function( items ) {
7688
+ var filter = this.options.filter;
7689
+ filter = filter || '*';
7690
+ var matches = [];
7691
+ var hiddenMatched = [];
7692
+ var visibleUnmatched = [];
7693
+
7694
+ var test = this._getFilterTest( filter );
7695
+
7696
+ // test each item
7697
+ for ( var i=0; i < items.length; i++ ) {
7698
+ var item = items[i];
7699
+ if ( item.isIgnored ) {
7700
+ continue;
7701
+ }
7702
+ // add item to either matched or unmatched group
7703
+ var isMatched = test( item );
7704
+ // item.isFilterMatched = isMatched;
7705
+ // add to matches if its a match
7706
+ if ( isMatched ) {
7707
+ matches.push( item );
7708
+ }
7709
+ // add to additional group if item needs to be hidden or revealed
7710
+ if ( isMatched && item.isHidden ) {
7711
+ hiddenMatched.push( item );
7712
+ } else if ( !isMatched && !item.isHidden ) {
7713
+ visibleUnmatched.push( item );
7714
+ }
7715
+ }
7716
+
7717
+ // return collections of items to be manipulated
7718
+ return {
7719
+ matches: matches,
7720
+ needReveal: hiddenMatched,
7721
+ needHide: visibleUnmatched
7722
+ };
7723
+ };
7724
+
7725
+ // get a jQuery, function, or a matchesSelector test given the filter
7726
+ proto._getFilterTest = function( filter ) {
7727
+ if ( jQuery && this.options.isJQueryFiltering ) {
7728
+ // use jQuery
7729
+ return function( item ) {
7730
+ return jQuery( item.element ).is( filter );
7731
+ };
7732
+ }
7733
+ if ( typeof filter == 'function' ) {
7734
+ // use filter as function
7735
+ return function( item ) {
7736
+ return filter( item.element );
7737
+ };
7738
+ }
7739
+ // default, use filter as selector string
7740
+ return function( item ) {
7741
+ return matchesSelector( item.element, filter );
7742
+ };
7743
+ };
7744
+
7745
+ // -------------------------- sorting -------------------------- //
7746
+
7747
+ /**
7748
+ * @params {Array} elems
7749
+ * @public
7750
+ */
7751
+ proto.updateSortData = function( elems ) {
7752
+ // get items
7753
+ var items;
7754
+ if ( elems ) {
7755
+ elems = utils.makeArray( elems );
7756
+ items = this.getItems( elems );
7757
+ } else {
7758
+ // update all items if no elems provided
7759
+ items = this.items;
7760
+ }
7761
+
7762
+ this._getSorters();
7763
+ this._updateItemsSortData( items );
7764
+ };
7765
+
7766
+ proto._getSorters = function() {
7767
+ var getSortData = this.options.getSortData;
7768
+ for ( var key in getSortData ) {
7769
+ var sorter = getSortData[ key ];
7770
+ this._sorters[ key ] = mungeSorter( sorter );
7771
+ }
7772
+ };
7773
+
7774
+ /**
7775
+ * @params {Array} items - of Enviratope.Items
7776
+ * @private
7777
+ */
7778
+ proto._updateItemsSortData = function( items ) {
7779
+ // do not update if no items
7780
+ var len = items && items.length;
7781
+
7782
+ for ( var i=0; len && i < len; i++ ) {
7783
+ var item = items[i];
7784
+ item.updateSortData();
7785
+ }
7786
+ };
7787
+
7788
+ // ----- munge sorter ----- //
7789
+
7790
+ // encapsulate this, as we just need mungeSorter
7791
+ // other functions in here are just for munging
7792
+ var mungeSorter = ( function() {
7793
+ // add a magic layer to sorters for convienent shorthands
7794
+ // `.foo-bar` will use the text of .foo-bar querySelector
7795
+ // `[foo-bar]` will use attribute
7796
+ // you can also add parser
7797
+ // `.foo-bar parseInt` will parse that as a number
7798
+ function mungeSorter( sorter ) {
7799
+ // if not a string, return function or whatever it is
7800
+ if ( typeof sorter != 'string' ) {
7801
+ return sorter;
7802
+ }
7803
+ // parse the sorter string
7804
+ var args = trim( sorter ).split(' ');
7805
+ var query = args[0];
7806
+ // check if query looks like [an-attribute]
7807
+ var attrMatch = query.match( /^\[(.+)\]$/ );
7808
+ var attr = attrMatch && attrMatch[1];
7809
+ var getValue = getValueGetter( attr, query );
7810
+ // use second argument as a parser
7811
+ var parser = Enviratope.sortDataParsers[ args[1] ];
7812
+ // parse the value, if there was a parser
7813
+ sorter = parser ? function( elem ) {
7814
+ return elem && parser( getValue( elem ) );
7815
+ } :
7816
+ // otherwise just return value
7817
+ function( elem ) {
7818
+ return elem && getValue( elem );
7819
+ };
7820
+
7821
+ return sorter;
7822
+ }
7823
+
7824
+ // get an attribute getter, or get text of the querySelector
7825
+ function getValueGetter( attr, query ) {
7826
+ // if query looks like [foo-bar], get attribute
7827
+ if ( attr ) {
7828
+ return function getAttribute( elem ) {
7829
+ return elem.getAttribute( attr );
7830
+ };
7831
+ }
7832
+
7833
+ // otherwise, assume its a querySelector, and get its text
7834
+ return function getChildText( elem ) {
7835
+ var child = elem.querySelector( query );
7836
+ return child && child.textContent;
7837
+ };
7838
+ }
7839
+
7840
+ return mungeSorter;
7841
+ })();
7842
+
7843
+ // parsers used in getSortData shortcut strings
7844
+ Enviratope.sortDataParsers = {
7845
+ 'parseInt': function( val ) {
7846
+ return parseInt( val, 10 );
7847
+ },
7848
+ 'parseFloat': function( val ) {
7849
+ return parseFloat( val );
7850
+ }
7851
+ };
7852
+
7853
+ // ----- sort method ----- //
7854
+
7855
+ // sort filteredItem order
7856
+ proto._sort = function() {
7857
+ var sortByOpt = this.options.sortBy;
7858
+ if ( !sortByOpt ) {
7859
+ return;
7860
+ }
7861
+ // concat all sortBy and sortHistory
7862
+ var sortBys = [].concat.apply( sortByOpt, this.sortHistory );
7863
+ // sort magic
7864
+ var itemSorter = getItemSorter( sortBys, this.options.sortAscending );
7865
+ this.filteredItems.sort( itemSorter );
7866
+ // keep track of sortBy History
7867
+ if ( sortByOpt != this.sortHistory[0] ) {
7868
+ // add to front, oldest goes in last
7869
+ this.sortHistory.unshift( sortByOpt );
7870
+ }
7871
+ };
7872
+
7873
+ // returns a function used for sorting
7874
+ function getItemSorter( sortBys, sortAsc ) {
7875
+ return function sorter( itemA, itemB ) {
7876
+ // cycle through all sortKeys
7877
+ for ( var i = 0; i < sortBys.length; i++ ) {
7878
+ var sortBy = sortBys[i];
7879
+ var a = itemA.sortData[ sortBy ];
7880
+ var b = itemB.sortData[ sortBy ];
7881
+ if ( a > b || a < b ) {
7882
+ // if sortAsc is an object, use the value given the sortBy key
7883
+ var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;
7884
+ var direction = isAscending ? 1 : -1;
7885
+ return ( a > b ? 1 : -1 ) * direction;
7886
+ }
7887
+ }
7888
+ return 0;
7889
+ };
7890
+ }
7891
+
7892
+ // -------------------------- methods -------------------------- //
7893
+
7894
+ // get layout mode
7895
+ proto._mode = function() {
7896
+ var layoutMode = this.options.layoutMode;
7897
+ var mode = this.modes[ layoutMode ];
7898
+ if ( !mode ) {
7899
+ // TODO console.error
7900
+ throw new Error( 'No layout mode: ' + layoutMode );
7901
+ }
7902
+ // HACK sync mode's options
7903
+ // any options set after init for layout mode need to be synced
7904
+ mode.options = this.options[ layoutMode ];
7905
+ return mode;
7906
+ };
7907
+
7908
+ proto._resetLayout = function() {
7909
+ // trigger original reset layout
7910
+ Outlayer.prototype._resetLayout.call( this );
7911
+ this._mode()._resetLayout();
7912
+ };
7913
+
7914
+ proto._getItemLayoutPosition = function( item ) {
7915
+ return this._mode()._getItemLayoutPosition( item );
7916
+ };
7917
+
7918
+ proto._manageStamp = function( stamp ) {
7919
+ this._mode()._manageStamp( stamp );
7920
+ };
7921
+
7922
+ proto._getContainerSize = function() {
7923
+ return this._mode()._getContainerSize();
7924
+ };
7925
+
7926
+ proto.needsResizeLayout = function() {
7927
+ return this._mode().needsResizeLayout();
7928
+ };
7929
+
7930
+ // -------------------------- adding & removing -------------------------- //
7931
+
7932
+ // HEADS UP overwrites default Outlayer appended
7933
+ proto.appended = function( elems ) {
7934
+ var items = this.addItems( elems );
7935
+ if ( !items.length ) {
7936
+ return;
7937
+ }
7938
+ // filter, layout, reveal new items
7939
+ var filteredItems = this._filterRevealAdded( items );
7940
+ // add to filteredItems
7941
+ this.filteredItems = this.filteredItems.concat( filteredItems );
7942
+ };
7943
+
7944
+ // HEADS UP overwrites default Outlayer prepended
7945
+ proto.prepended = function( elems ) {
7946
+ var items = this._itemize( elems );
7947
+ if ( !items.length ) {
7948
+ return;
7949
+ }
7950
+ // start new layout
7951
+ this._resetLayout();
7952
+ this._manageStamps();
7953
+ // filter, layout, reveal new items
7954
+ var filteredItems = this._filterRevealAdded( items );
7955
+ // layout previous items
7956
+ this.layoutItems( this.filteredItems );
7957
+ // add to items and filteredItems
7958
+ this.filteredItems = filteredItems.concat( this.filteredItems );
7959
+ this.items = items.concat( this.items );
7960
+ };
7961
+
7962
+ proto._filterRevealAdded = function( items ) {
7963
+ var filtered = this._filter( items );
7964
+ this.hide( filtered.needHide );
7965
+ // reveal all new items
7966
+ this.reveal( filtered.matches );
7967
+ // layout new items, no transition
7968
+ this.layoutItems( filtered.matches, true );
7969
+ return filtered.matches;
7970
+ };
7971
+
7972
+ /**
7973
+ * Filter, sort, and layout newly-appended item elements
7974
+ * @param {Array or NodeList or Element} elems
7975
+ */
7976
+ proto.insert = function( elems ) {
7977
+ var items = this.addItems( elems );
7978
+ if ( !items.length ) {
7979
+ return;
7980
+ }
7981
+ // append item elements
7982
+ var i, item;
7983
+ var len = items.length;
7984
+ for ( i=0; i < len; i++ ) {
7985
+ item = items[i];
7986
+ this.element.appendChild( item.element );
7987
+ }
7988
+ // filter new stuff
7989
+ var filteredInsertItems = this._filter( items ).matches;
7990
+ // set flag
7991
+ for ( i=0; i < len; i++ ) {
7992
+ items[i].isLayoutInstant = true;
7993
+ }
7994
+ this.arrange();
7995
+ // reset flag
7996
+ for ( i=0; i < len; i++ ) {
7997
+ delete items[i].isLayoutInstant;
7998
+ }
7999
+ this.reveal( filteredInsertItems );
8000
+ };
8001
+
8002
+ var _remove = proto.remove;
8003
+ proto.remove = function( elems ) {
8004
+ elems = utils.makeArray( elems );
8005
+ var removeItems = this.getItems( elems );
8006
+ // do regular thing
8007
+ _remove.call( this, elems );
8008
+ // bail if no items to remove
8009
+ var len = removeItems && removeItems.length;
8010
+ // remove elems from filteredItems
8011
+ for ( var i=0; len && i < len; i++ ) {
8012
+ var item = removeItems[i];
8013
+ // remove item from collection
8014
+ utils.removeFrom( this.filteredItems, item );
8015
+ }
8016
+ };
8017
+
8018
+ proto.shuffle = function() {
8019
+ // update random sortData
8020
+ for ( var i=0; i < this.items.length; i++ ) {
8021
+ var item = this.items[i];
8022
+ item.sortData.random = Math.random();
8023
+ }
8024
+ this.options.sortBy = 'random';
8025
+ this._sort();
8026
+ this._layout();
8027
+ };
8028
+
8029
+ /**
8030
+ * trigger fn without transition
8031
+ * kind of hacky to have this in the first place
8032
+ * @param {Function} fn
8033
+ * @param {Array} args
8034
+ * @returns ret
8035
+ * @private
8036
+ */
8037
+ proto._noTransition = function( fn, args ) {
8038
+ // save transitionDuration before disabling
8039
+ var transitionDuration = this.options.transitionDuration;
8040
+ // disable transition
8041
+ this.options.transitionDuration = 0;
8042
+ // do it
8043
+ var returnValue = fn.apply( this, args );
8044
+ // re-enable transition for reveal
8045
+ this.options.transitionDuration = transitionDuration;
8046
+ return returnValue;
8047
+ };
8048
+
8049
+ // ----- helper methods ----- //
8050
+
8051
+ /**
8052
+ * getter method for getting filtered item elements
8053
+ * @returns {Array} elems - collection of item elements
8054
+ */
8055
+ proto.getFilteredItemElements = function() {
8056
+ return this.filteredItems.map( function( item ) {
8057
+ return item.element;
8058
+ });
8059
+ };
8060
+
8061
+ // ----- ----- //
8062
+
8063
+ return Enviratope;
8064
+
8065
+ }));
8066
+
8067
+ // Envirabox 2.1.5
8068
+ ;(function (window, document, $, undefined) {
8069
+ "use strict";
8070
+
8071
+ var H = $("html"),
8072
+ W = $(window),
8073
+ D = $(document),
8074
+ F = $.envirabox = function () {
8075
+ F.open.apply( this, arguments );
8076
+ },
8077
+ IE = navigator.userAgent.match(/msie/i),
8078
+ didUpdate = null,
8079
+ isTouch = document.createTouch !== undefined,
8080
+
8081
+ isQuery = function(obj) {
8082
+ return obj && obj.hasOwnProperty && obj instanceof $;
8083
+ },
8084
+ isString = function(str) {
8085
+ return str && $.type(str) === "string";
8086
+ },
8087
+ isPercentage = function(str) {
8088
+ return isString(str) && str.indexOf('%') > 0;
8089
+ },
8090
+ isScrollable = function(el) {
8091
+ return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight)));
8092
+ },
8093
+ getScalar = function(orig, dim) {
8094
+ var value = parseInt(orig, 10) || 0;
8095
+
8096
+ if (dim && isPercentage(orig)) {
8097
+ value = F.getViewport()[ dim ] / 100 * value;
8098
+ }
8099
+
8100
+ return Math.ceil(value);
8101
+ },
8102
+ getValue = function(value, dim) {
8103
+ return getScalar(value, dim) + 'px';
8104
+ };
8105
+
8106
+ $.extend(F, {
8107
+ // The current version of envirabox
8108
+ version: '2.1.5',
8109
+
8110
+ defaults: {
8111
+ padding : 15,
8112
+ margin : 40,
8113
+
8114
+ width : 800,
8115
+ height : 600,
8116
+ minWidth : 100,
8117
+ minHeight : 100,
8118
+ maxWidth : 9999,
8119
+ maxHeight : 9999,
8120
+ pixelRatio: 1, // Set to 2 for retina display support
8121
+
8122
+ autoSize : true,
8123
+ autoHeight : false,
8124
+ autoWidth : false,
8125
+
8126
+ autoResize : true,
8127
+ autoCenter : !isTouch,
8128
+ fitToView : true,
8129
+ aspectRatio : false,
8130
+ topRatio : 0.5,
8131
+ leftRatio : 0.5,
8132
+
8133
+ scrolling : 'auto', // 'auto', 'yes' or 'no'
8134
+ wrapCSS : '',
8135
+
8136
+ arrows : true,
8137
+ closeBtn : true,
8138
+ closeClick : false,
8139
+ nextClick : false,
8140
+ mouseWheel : true,
8141
+ autoPlay : false,
8142
+ playSpeed : 3000,
8143
+ preload : 3,
8144
+ modal : false,
8145
+ loop : true,
8146
+
8147
+ ajax : {
8148
+ dataType : 'html',
8149
+ headers : { 'X-envirabox': true }
8150
+ },
8151
+ iframe : {
8152
+ scrolling : 'auto',
8153
+ preload : true
8154
+ },
8155
+ swf : {
8156
+ wmode: 'transparent',
8157
+ allowfullscreen : 'true',
8158
+ allowscriptaccess : 'always'
8159
+ },
8160
+
8161
+ keys : {
8162
+ next : {
8163
+ 13 : 'left', // enter
8164
+ 34 : 'up', // page down
8165
+ 39 : 'left', // right arrow
8166
+ 40 : 'up' // down arrow
8167
+ },
8168
+ prev : {
8169
+ 8 : 'right', // backspace
8170
+ 33 : 'down', // page up
8171
+ 37 : 'right', // left arrow
8172
+ 38 : 'down' // up arrow
8173
+ },
8174
+ close : [27], // escape key
8175
+ play : [32], // space - start/stop slideshow
8176
+ toggle : [70] // letter "f" - toggle fullscreen
8177
+ },
8178
+
8179
+ direction : {
8180
+ next : 'left',
8181
+ prev : 'right'
8182
+ },
8183
+
8184
+ scrollOutside : true,
8185
+
8186
+ // Override some properties
8187
+ index : 0,
8188
+ type : null,
8189
+ href : null,
8190
+ content : null,
8191
+ title : null,
8192
+
8193
+ // HTML templates
8194
+ tpl: {
8195
+ wrap : '<div class="envirabox-wrap" tabIndex="-1"><div class="envirabox-skin"><div class="envirabox-outer"><div class="envirabox-inner"></div></div></div></div>',
8196
+ image : '<img class="envirabox-image" src="{href}" />',
8197
+ iframe : '<iframe id="envirabox-frame{rnd}" name="envirabox-frame{rnd}" class="envirabox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : '') + '></iframe>',
8198
+ error : '<p class="envirabox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
8199
+ closeBtn : '<a title="Close" class="envirabox-item envirabox-close" href="javascript:;"></a>',
8200
+ next : '<a title="Next" class="envirabox-nav envirabox-next" href="javascript:;"><span></span></a>',
8201
+ prev : '<a title="Previous" class="envirabox-nav envirabox-prev" href="javascript:;"><span></span></a>'
8202
+ },
8203
+
8204
+ // Properties for each animation type
8205
+ // Opening envirabox
8206
+ openEffect : 'fade', // 'elastic', 'fade' or 'none'
8207
+ openSpeed : 250,
8208
+ openEasing : 'swing',
8209
+ openOpacity : true,
8210
+ openMethod : 'zoomIn',
8211
+
8212
+ // Closing envirabox
8213
+ closeEffect : 'fade', // 'elastic', 'fade' or 'none'
8214
+ closeSpeed : 250,
8215
+ closeEasing : 'swing',
8216
+ closeOpacity : true,
8217
+ closeMethod : 'zoomOut',
8218
+
8219
+ // Changing next gallery item
8220
+ nextEffect : 'elastic', // 'elastic', 'fade' or 'none'
8221
+ nextSpeed : 250,
8222
+ nextEasing : 'swing',
8223
+ nextMethod : 'changeIn',
8224
+
8225
+ // Changing previous gallery item
8226
+ prevEffect : 'elastic', // 'elastic', 'fade' or 'none'
8227
+ prevSpeed : 250,
8228
+ prevEasing : 'swing',
8229
+ prevMethod : 'changeOut',
8230
+
8231
+ // Enable default helpers
8232
+ helpers : {
8233
+ overlay : true,
8234
+ title : true
8235
+ },
8236
+
8237
+ // Callbacks
8238
+ onCancel : $.noop, // If canceling
8239
+ beforeLoad : $.noop, // Before loading
8240
+ afterLoad : $.noop, // After loading
8241
+ beforeShow : $.noop, // Before changing in current item
8242
+ afterShow : $.noop, // After opening
8243
+ beforeChange : $.noop, // Before changing gallery item
8244
+ beforeClose : $.noop, // Before closing
8245
+ afterClose : $.noop // After closing
8246
+ },
8247
+
8248
+ //Current state
8249
+ group : {}, // Selected group
8250
+ opts : {}, // Group options
8251
+ previous : null, // Previous element
8252
+ coming : null, // Element being loaded
8253
+ current : null, // Currently loaded element
8254
+ isActive : false, // Is activated
8255
+ isOpen : false, // Is currently open
8256
+ isOpened : false, // Have been fully opened at least once
8257
+
8258
+ wrap : null,
8259
+ skin : null,
8260
+ outer : null,
8261
+ inner : null,
8262
+
8263
+ player : {
8264
+ timer : null,
8265
+ isActive : false
8266
+ },
8267
+
8268
+ // Loaders
8269
+ ajaxLoad : null,
8270
+ imgPreload : null,
8271
+
8272
+ // Some collections
8273
+ transitions : {},
8274
+ helpers : {},
8275
+
8276
+ /*
8277
+ * Static methods
8278
+ */
8279
+
8280
+ open: function (group, opts) {
8281
+ if (!group) {
8282
+ return;
8283
+ }
8284
+
8285
+ if (!$.isPlainObject(opts)) {
8286
+ opts = {};
8287
+ }
8288
+
8289
+ // Close if already active
8290
+ if (false === F.close(true)) {
8291
+ return;
8292
+ }
8293
+
8294
+ // Normalize group
8295
+ if (!$.isArray(group)) {
8296
+ group = isQuery(group) ? $(group).get() : [group];
8297
+ }
8298
+
8299
+ // Recheck if the type of each element is `object` and set content type (image, ajax, etc)
8300
+ $.each(group, function(i, element) {
8301
+ var obj = {},
8302
+ href,
8303
+ title,
8304
+ content,
8305
+ type,
8306
+ rez,
8307
+ hrefParts,
8308
+ selector;
8309
+
8310
+ if ($.type(element) === "object") {
8311
+ // Check if is DOM element
8312
+ if (element.nodeType) {
8313
+ element = $(element);
8314
+ }
8315
+
8316
+ if (isQuery(element)) {
8317
+ obj = {
8318
+ href : element.data('envirabox-href') || element.attr('href'),
8319
+ title : $('<div/>').text( element.data('envirabox-title') || element.attr('title') ).html(),
8320
+ isDom : true,
8321
+ element : element
8322
+ };
8323
+
8324
+ if ($.metadata) {
8325
+ $.extend(true, obj, element.metadata());
8326
+ }
8327
+
8328
+ } else {
8329
+ obj = element;
8330
+ }
8331
+ }
8332
+
8333
+ href = opts.href || obj.href || (isString(element) ? element : null);
8334
+ title = opts.title !== undefined ? opts.title : obj.title || '';
8335
+
8336
+ content = opts.content || obj.content;
8337
+ type = content ? 'html' : (opts.type || obj.type);
8338
+
8339
+ if (!type && obj.isDom) {
8340
+ type = element.data('envirabox-type');
8341
+
8342
+ if (!type) {
8343
+ rez = element.prop('class').match(/envirabox\.(\w+)/);
8344
+ type = rez ? rez[1] : null;
8345
+ }
8346
+ }
8347
+
8348
+ if (isString(href)) {
8349
+ // Try to guess the content type
8350
+ if (!type) {
8351
+ if (F.isImage(href)) {
8352
+ type = 'image';
8353
+
8354
+ } else if (F.isSWF(href)) {
8355
+ type = 'swf';
8356
+
8357
+ } else if (href.charAt(0) === '#') {
8358
+ type = 'inline';
8359
+
8360
+ } else if (isString(element)) {
8361
+ type = 'html';
8362
+ content = element;
8363
+ }
8364
+ }
8365
+
8366
+ // Split url into two pieces with source url and content selector, e.g,
8367
+ // "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id"
8368
+ if (type === 'ajax') {
8369
+ hrefParts = href.split(/\s+/, 2);
8370
+ href = hrefParts.shift();
8371
+ selector = hrefParts.shift();
8372
+ }
8373
+ }
8374
+
8375
+ if (!content) {
8376
+ if (type === 'inline') {
8377
+ if (href) {
8378
+ content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7
8379
+
8380
+ } else if (obj.isDom) {
8381
+ content = element;
8382
+ }
8383
+
8384
+ } else if (type === 'html') {
8385
+ content = href;
8386
+
8387
+ } else if (!type && !href && obj.isDom) {
8388
+ type = 'inline';
8389
+ content = element;
8390
+ }
8391
+ }
8392
+
8393
+ $.extend(obj, {
8394
+ href : href,
8395
+ type : type,
8396
+ content : content,
8397
+ title : title,
8398
+ selector : selector
8399
+ });
8400
+
8401
+ group[ i ] = obj;
8402
+ });
8403
+
8404
+ // Extend the defaults
8405
+ F.opts = $.extend(true, {}, F.defaults, opts);
8406
+
8407
+ // All options are merged recursive except keys
8408
+ if (opts.keys !== undefined) {
8409
+ F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false;
8410
+ }
8411
+
8412
+ F.group = group;
8413
+
8414
+ return F._start(F.opts.index);
8415
+ },
8416
+
8417
+ // Cancel image loading or abort ajax request
8418
+ cancel: function () {
8419
+ var coming = F.coming;
8420
+
8421
+ if (coming && false === F.trigger('onCancel')) {
8422
+ return;
8423
+ }
8424
+
8425
+ F.hideLoading();
8426
+
8427
+ if (!coming) {
8428
+ return;
8429
+ }
8430
+
8431
+ if (F.ajaxLoad) {
8432
+ F.ajaxLoad.abort();
8433
+ }
8434
+
8435
+ F.ajaxLoad = null;
8436
+
8437
+ if (F.imgPreload) {
8438
+ F.imgPreload.onload = F.imgPreload.onerror = null;
8439
+ }
8440
+
8441
+ if (coming.wrap) {
8442
+ coming.wrap.stop(true, true).trigger('onReset').remove();
8443
+ }
8444
+
8445
+ F.coming = null;
8446
+
8447
+ // If the first item has been canceled, then clear everything
8448
+ if (!F.current) {
8449
+ F._afterZoomOut( coming );
8450
+ }
8451
+ },
8452
+
8453
+ // Start closing animation if is open; remove immediately if opening/closing
8454
+ close: function (event) {
8455
+ F.cancel();
8456
+
8457
+ if (false === F.trigger('beforeClose')) {
8458
+ return;
8459
+ }
8460
+
8461
+ F.unbindEvents();
8462
+
8463
+ if (!F.isActive) {
8464
+ return;
8465
+ }
8466
+
8467
+ if (!F.isOpen || event === true) {
8468
+ $('.envirabox-wrap').stop(true).trigger('onReset').remove();
8469
+
8470
+ F._afterZoomOut();
8471
+
8472
+ } else {
8473
+ F.isOpen = F.isOpened = false;
8474
+ F.isClosing = true;
8475
+
8476
+ $('.envirabox-item, .envirabox-nav').remove();
8477
+
8478
+ F.wrap.stop(true, true).removeClass('envirabox-opened');
8479
+
8480
+ F.transitions[ F.current.closeMethod ]();
8481
+ }
8482
+ },
8483
+
8484
+ // Manage slideshow:
8485
+ // $.envirabox.play(); - toggle slideshow
8486
+ // $.envirabox.play( true ); - start
8487
+ // $.envirabox.play( false ); - stop
8488
+ play: function ( action ) {
8489
+ var clear = function () {
8490
+ clearTimeout(F.player.timer);
8491
+ },
8492
+ set = function () {
8493
+ clear();
8494
+
8495
+ if (F.current && F.player.isActive) {
8496
+ F.player.timer = setTimeout(F.next, F.current.playSpeed);
8497
+ }
8498
+ },
8499
+ stop = function () {
8500
+ clear();
8501
+
8502
+ D.unbind('.player');
8503
+
8504
+ F.player.isActive = false;
8505
+
8506
+ F.trigger('onPlayEnd');
8507
+ },
8508
+ start = function () {
8509
+ if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) {
8510
+ F.player.isActive = true;
8511
+
8512
+ D.bind({
8513
+ 'onCancel.player beforeClose.player' : stop,
8514
+ 'onUpdate.player' : set,
8515
+ 'beforeLoad.player' : clear
8516
+ });
8517
+
8518
+ set();
8519
+
8520
+ F.trigger('onPlayStart');
8521
+ }
8522
+ };
8523
+
8524
+ if (action === true || (!F.player.isActive && action !== false)) {
8525
+ start();
8526
+ } else {
8527
+ stop();
8528
+ }
8529
+ },
8530
+
8531
+ // Navigate to next gallery item
8532
+ next: function ( direction ) {
8533
+ var current = F.current;
8534
+
8535
+ if (current) {
8536
+ if (!isString(direction)) {
8537
+ direction = current.direction.next;
8538
+ }
8539
+
8540
+ F.jumpto(current.index + 1, direction, 'next');
8541
+ }
8542
+ },
8543
+
8544
+ // Navigate to previous gallery item
8545
+ prev: function ( direction ) {
8546
+ var current = F.current;
8547
+
8548
+ if (current) {
8549
+ if (!isString(direction)) {
8550
+ direction = current.direction.prev;
8551
+ }
8552
+
8553
+ F.jumpto(current.index - 1, direction, 'prev');
8554
+ }
8555
+ },
8556
+
8557
+ // Navigate to gallery item by index
8558
+ jumpto: function ( index, direction, router ) {
8559
+ var current = F.current;
8560
+
8561
+ if (!current) {
8562
+ return;
8563
+ }
8564
+
8565
+ index = getScalar(index);
8566
+
8567
+ F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ];
8568
+ F.router = router || 'jumpto';
8569
+
8570
+ if (current.loop) {
8571
+ if (index < 0) {
8572
+ index = current.group.length + (index % current.group.length);
8573
+ }
8574
+
8575
+ index = index % current.group.length;
8576
+ }
8577
+
8578
+ if (current.group[ index ] !== undefined) {
8579
+ F.cancel();
8580
+
8581
+ F._start(index);
8582
+ }
8583
+ },
8584
+
8585
+ // Center inside viewport and toggle position type to fixed or absolute if needed
8586
+ reposition: function (e, onlyAbsolute) {
8587
+ var current = F.current,
8588
+ wrap = current ? current.wrap : null,
8589
+ pos;
8590
+
8591
+ if (wrap) {
8592
+ pos = F._getPosition(onlyAbsolute);
8593
+
8594
+ if (e && e.type === 'scroll') {
8595
+ delete pos.position;
8596
+
8597
+ wrap.stop(true, true).animate(pos, 200);
8598
+
8599
+ } else {
8600
+ wrap.css(pos);
8601
+
8602
+ current.pos = $.extend({}, current.dim, pos);
8603
+ }
8604
+ }
8605
+ },
8606
+
8607
+ update: function (e) {
8608
+ var type = (e && e.originalEvent && e.originalEvent.type),
8609
+ anyway = !type || type === 'orientationchange';
8610
+
8611
+ if (anyway) {
8612
+ clearTimeout(didUpdate);
8613
+
8614
+ didUpdate = null;
8615
+ }
8616
+
8617
+ if (!F.isOpen || didUpdate) {
8618
+ return;
8619
+ }
8620
+
8621
+ didUpdate = setTimeout(function() {
8622
+ var current = F.current;
8623
+
8624
+ if (!current || F.isClosing) {
8625
+ return;
8626
+ }
8627
+
8628
+ F.wrap.removeClass('envirabox-tmp');
8629
+
8630
+ if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) {
8631
+ F._setDimension();
8632
+ }
8633
+
8634
+ if (!(type === 'scroll' && current.canShrink)) {
8635
+ F.reposition(e);
8636
+ }
8637
+
8638
+ F.trigger('onUpdate');
8639
+
8640
+ didUpdate = null;
8641
+
8642
+ }, (anyway && !isTouch ? 0 : 300));
8643
+ },
8644
+
8645
+ // Shrink content to fit inside viewport or restore if resized
8646
+ toggle: function ( action ) {
8647
+ if (F.isOpen) {
8648
+ F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView;
8649
+
8650
+ // Help browser to restore document dimensions
8651
+ if (isTouch) {
8652
+ F.wrap.removeAttr('style').addClass('envirabox-tmp');
8653
+
8654
+ F.trigger('onUpdate');
8655
+ }
8656
+
8657
+ F.update();
8658
+ }
8659
+ },
8660
+
8661
+ hideLoading: function () {
8662
+ D.unbind('.loading');
8663
+
8664
+ $('#envirabox-loading').remove();
8665
+ },
8666
+
8667
+ showLoading: function () {
8668
+ var el, viewport;
8669
+
8670
+ F.hideLoading();
8671
+
8672
+ el = $('<div id="envirabox-loading"><div></div></div>').click(F.cancel).appendTo('body');
8673
+
8674
+ // If user will press the escape-button, the request will be canceled
8675
+ D.bind('keydown.loading', function(e) {
8676
+ if ((e.which || e.keyCode) === 27) {
8677
+ e.preventDefault();
8678
+
8679
+ F.cancel();
8680
+ }
8681
+ });
8682
+
8683
+ if (!F.defaults.fixed) {
8684
+ viewport = F.getViewport();
8685
+
8686
+ el.css({
8687
+ position : 'absolute',
8688
+ top : (viewport.h * 0.5) + viewport.y,
8689
+ left : (viewport.w * 0.5) + viewport.x
8690
+ });
8691
+ }
8692
+
8693
+ F.trigger('onLoading');
8694
+ },
8695
+
8696
+ getViewport: function () {
8697
+ var locked = (F.current && F.current.locked) || false,
8698
+ rez = {
8699
+ x: W.scrollLeft(),
8700
+ y: W.scrollTop()
8701
+ };
8702
+
8703
+ if (locked && locked.length) {
8704
+ rez.w = locked[0].clientWidth;
8705
+ rez.h = locked[0].clientHeight;
8706
+
8707
+ } else {
8708
+ // See http://bugs.jquery.com/ticket/6724
8709
+ rez.w = isTouch && window.innerWidth ? window.innerWidth : W.width();
8710
+ rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height();
8711
+ }
8712
+
8713
+ return rez;
8714
+ },
8715
+
8716
+ // Unbind the keyboard / clicking actions
8717
+ unbindEvents: function () {
8718
+ if (F.wrap && isQuery(F.wrap)) {
8719
+ F.wrap.unbind('.fb');
8720
+ }
8721
+
8722
+ D.unbind('.fb');
8723
+ W.unbind('.fb');
8724
+ },
8725
+
8726
+ bindEvents: function () {
8727
+ var current = F.current,
8728
+ keys;
8729
+
8730
+ if (!current) {
8731
+ return;
8732
+ }
8733
+
8734
+ // Changing document height on iOS devices triggers a 'resize' event,
8735
+ // that can change document height... repeating infinitely
8736
+ W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update);
8737
+
8738
+ keys = current.keys;
8739
+
8740
+ if (keys) {
8741
+ D.bind('keydown.fb', function (e) {
8742
+ var code = e.which || e.keyCode,
8743
+ target = e.target || e.srcElement;
8744
+
8745
+ // Skip esc key if loading, because showLoading will cancel preloading
8746
+ if (code === 27 && F.coming) {
8747
+ return false;
8748
+ }
8749
+
8750
+ // Ignore key combinations and key events within form elements
8751
+ if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) {
8752
+ $.each(keys, function(i, val) {
8753
+ if (current.group.length > 1 && val[ code ] !== undefined) {
8754
+ F[ i ]( val[ code ] );
8755
+
8756
+ e.preventDefault();
8757
+ return false;
8758
+ }
8759
+
8760
+ if ($.inArray(code, val) > -1) {
8761
+ F[ i ] ();
8762
+
8763
+ e.preventDefault();
8764
+ return false;
8765
+ }
8766
+ });
8767
+ }
8768
+ });
8769
+ }
8770
+
8771
+ if ($.fn.mousewheel && current.mouseWheel) {
8772
+ F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) {
8773
+ var target = e.target || null,
8774
+ parent = $(target),
8775
+ canScroll = false;
8776
+
8777
+ while (parent.length) {
8778
+ if (canScroll || parent.is('.envirabox-skin') || parent.is('.envirabox-wrap')) {
8779
+ break;
8780
+ }
8781
+
8782
+ canScroll = isScrollable( parent[0] );
8783
+ parent = $(parent).parent();
8784
+ }
8785
+
8786
+ if (delta !== 0 && !canScroll) {
8787
+ if (F.group.length > 1 && !current.canShrink) {
8788
+ if (deltaY > 0 || deltaX > 0) {
8789
+ F.prev( deltaY > 0 ? 'down' : 'left' );
8790
+
8791
+ } else if (deltaY < 0 || deltaX < 0) {
8792
+ F.next( deltaY < 0 ? 'up' : 'right' );
8793
+ }
8794
+
8795
+ e.preventDefault();
8796
+ }
8797
+ }
8798
+ });
8799
+ }
8800
+ },
8801
+
8802
+ trigger: function (event, o) {
8803
+ var ret, obj = o || F.coming || F.current;
8804
+
8805
+ if (obj) {
8806
+ if ($.isFunction( obj[event] )) {
8807
+ ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1));
8808
+ }
8809
+
8810
+ if (ret === false) {
8811
+ return false;
8812
+ }
8813
+
8814
+ if (obj.helpers) {
8815
+ $.each(obj.helpers, function (helper, opts) {
8816
+ if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) {
8817
+ F.helpers[helper][event]($.extend(true, {}, F.helpers[helper].defaults, opts), obj);
8818
+ }
8819
+ });
8820
+ }
8821
+ }
8822
+
8823
+ D.trigger(event);
8824
+ },
8825
+
8826
+ isImage: function (str) {
8827
+ return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);
8828
+ },
8829
+
8830
+ isSWF: function (str) {
8831
+ return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i);
8832
+ },
8833
+
8834
+ _start: function (index) {
8835
+ var coming = {},
8836
+ obj,
8837
+ href,
8838
+ type,
8839
+ margin,
8840
+ padding;
8841
+
8842
+ index = getScalar( index );
8843
+ obj = F.group[ index ] || null;
8844
+
8845
+ if (!obj) {
8846
+ return false;
8847
+ }
8848
+
8849
+ coming = $.extend(true, {}, F.opts, obj);
8850
+
8851
+ // Convert margin and padding properties to array - top, right, bottom, left
8852
+ margin = coming.margin;
8853
+ padding = coming.padding;
8854
+
8855
+ if ($.type(margin) === 'number') {
8856
+ coming.margin = [margin, margin, margin, margin];
8857
+ }
8858
+
8859
+ if ($.type(padding) === 'number') {
8860
+ coming.padding = [padding, padding, padding, padding];
8861
+ }
8862
+
8863
+ // 'modal' propery is just a shortcut
8864
+ if (coming.modal) {
8865
+ $.extend(true, coming, {
8866
+ closeBtn : false,
8867
+ closeClick : false,
8868
+ nextClick : false,
8869
+ arrows : false,
8870
+ mouseWheel : false,
8871
+ keys : null,
8872
+ helpers: {
8873
+ overlay : {
8874
+ closeClick : false
8875
+ }
8876
+ }
8877
+ });
8878
+ }
8879
+
8880
+ // 'autoSize' property is a shortcut, too
8881
+ if (coming.autoSize) {
8882
+ coming.autoWidth = coming.autoHeight = true;
8883
+ }
8884
+
8885
+ if (coming.width === 'auto') {
8886
+ coming.autoWidth = true;
8887
+ }
8888
+
8889
+ if (coming.height === 'auto') {
8890
+ coming.autoHeight = true;
8891
+ }
8892
+
8893
+ /*
8894
+ * Add reference to the group, so it`s possible to access from callbacks, example:
8895
+ * afterLoad : function() {
8896
+ * this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : '');
8897
+ * }
8898
+ */
8899
+
8900
+ coming.group = F.group;
8901
+ coming.index = index;
8902
+
8903
+ // Give a chance for callback or helpers to update coming item (type, title, etc)
8904
+ F.coming = coming;
8905
+
8906
+ if (false === F.trigger('beforeLoad')) {
8907
+ F.coming = null;
8908
+
8909
+ return;
8910
+ }
8911
+
8912
+ type = coming.type;
8913
+ href = coming.href;
8914
+
8915
+ if (!type) {
8916
+ F.coming = null;
8917
+
8918
+ //If we can not determine content type then drop silently or display next/prev item if looping through gallery
8919
+ if (F.current && F.router && F.router !== 'jumpto') {
8920
+ F.current.index = index;
8921
+
8922
+ return F[ F.router ]( F.direction );
8923
+ }
8924
+
8925
+ return false;
8926
+ }
8927
+
8928
+ F.isActive = true;
8929
+
8930
+ if (type === 'image' || type === 'swf') {
8931
+ coming.autoHeight = coming.autoWidth = false;
8932
+ coming.scrolling = 'visible';
8933
+ }
8934
+
8935
+ if (type === 'image') {
8936
+ coming.aspectRatio = true;
8937
+ }
8938
+
8939
+ if (type === 'iframe' && isTouch) {
8940
+ coming.scrolling = 'scroll';
8941
+ }
8942
+
8943
+ // Build the neccessary markup
8944
+ coming.wrap = $(coming.tpl.wrap).addClass('envirabox-' + (isTouch ? 'mobile' : 'desktop') + ' envirabox-type-' + type + ' envirabox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' );
8945
+
8946
+ $.extend(coming, {
8947
+ skin : $('.envirabox-skin', coming.wrap),
8948
+ outer : $('.envirabox-outer', coming.wrap),
8949
+ inner : $('.envirabox-inner', coming.wrap)
8950
+ });
8951
+
8952
+ $.each(["Top", "Right", "Bottom", "Left"], function(i, v) {
8953
+ coming.skin.css('padding' + v, getValue(coming.padding[ i ]));
8954
+ });
8955
+
8956
+ F.trigger('onReady');
8957
+
8958
+ // Check before try to load; 'inline' and 'html' types need content, others - href
8959
+ if (type === 'inline' || type === 'html') {
8960
+ if (!coming.content || !coming.content.length) {
8961
+ return F._error( 'content' );
8962
+ }
8963
+
8964
+ } else if (!href) {
8965
+ return F._error( 'href' );
8966
+ }
8967
+
8968
+ if (type === 'image') {
8969
+ F._loadImage();
8970
+
8971
+ } else if (type === 'ajax') {
8972
+ F._loadAjax();
8973
+
8974
+ } else if (type === 'iframe') {
8975
+ F._loadIframe();
8976
+
8977
+ } else {
8978
+ F._afterLoad();
8979
+ }
8980
+ },
8981
+
8982
+ _error: function ( type ) {
8983
+ $.extend(F.coming, {
8984
+ type : 'html',
8985
+ autoWidth : true,
8986
+ autoHeight : true,
8987
+ minWidth : 0,
8988
+ minHeight : 0,
8989
+ scrolling : 'no',
8990
+ hasError : type,
8991
+ content : F.coming.tpl.error
8992
+ });
8993
+
8994
+ F._afterLoad();
8995
+ },
8996
+
8997
+ _loadImage: function () {
8998
+ // Reset preload image so it is later possible to check "complete" property
8999
+ var img = F.imgPreload = new Image();
9000
+
9001
+ img.onload = function () {
9002
+ this.onload = this.onerror = null;
9003
+
9004
+ F.coming.width = this.width / F.opts.pixelRatio;
9005
+ F.coming.height = this.height / F.opts.pixelRatio;
9006
+
9007
+ F._afterLoad();
9008
+ };
9009
+
9010
+ img.onerror = function () {
9011
+ this.onload = this.onerror = null;
9012
+
9013
+ F._error( 'image' );
9014
+ };
9015
+
9016
+ img.src = F.coming.href;
9017
+
9018
+ if (img.complete !== true) {
9019
+ F.showLoading();
9020
+ }
9021
+ },
9022
+
9023
+ _loadAjax: function () {
9024
+ var coming = F.coming;
9025
+
9026
+ F.showLoading();
9027
+
9028
+ F.ajaxLoad = $.ajax($.extend({}, coming.ajax, {
9029
+ url: coming.href,
9030
+ error: function (jqXHR, textStatus) {
9031
+ if (F.coming && textStatus !== 'abort') {
9032
+ F._error( 'ajax', jqXHR );
9033
+
9034
+ } else {
9035
+ F.hideLoading();
9036
+ }
9037
+ },
9038
+ success: function (data, textStatus) {
9039
+ if (textStatus === 'success') {
9040
+ coming.content = data;
9041
+
9042
+ F._afterLoad();
9043
+ }
9044
+ }
9045
+ }));
9046
+ },
9047
+
9048
+ _loadIframe: function() {
9049
+ var coming = F.coming,
9050
+ iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime()))
9051
+ .attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling)
9052
+ .attr('src', coming.href);
9053
+
9054
+ // This helps IE
9055
+ $(coming.wrap).bind('onReset', function () {
9056
+ try {
9057
+ $(this).find('iframe').hide().attr('src', '//about:blank').end().empty();
9058
+ } catch (e) {}
9059
+ });
9060
+
9061
+ if (coming.iframe.preload) {
9062
+ F.showLoading();
9063
+
9064
+ iframe.one('load', function() {
9065
+ $(this).data('ready', 1);
9066
+
9067
+ // iOS will lose scrolling if we resize
9068
+ if (!isTouch) {
9069
+ $(this).bind('load.fb', F.update);
9070
+ }
9071
+
9072
+ // Without this trick:
9073
+ // - iframe won't scroll on iOS devices
9074
+ // - IE7 sometimes displays empty iframe
9075
+ $(this).parents('.envirabox-wrap').width('100%').removeClass('envirabox-tmp').show();
9076
+
9077
+ F._afterLoad();
9078
+ });
9079
+ }
9080
+
9081
+ coming.content = iframe.appendTo( coming.inner );
9082
+
9083
+ if (!coming.iframe.preload) {
9084
+ F._afterLoad();
9085
+ }
9086
+ },
9087
+
9088
+ _preloadImages: function() {
9089
+ var group = F.group,
9090
+ current = F.current,
9091
+ len = group.length,
9092
+ cnt = current.preload ? Math.min(current.preload, len - 1) : 0,
9093
+ item,
9094
+ i;
9095
+
9096
+ for (i = 1; i <= cnt; i += 1) {
9097
+ item = group[ (current.index + i ) % len ];
9098
+
9099
+ if (item.type === 'image' && item.href) {
9100
+ new Image().src = item.href;
9101
+ }
9102
+ }
9103
+ },
9104
+
9105
+ _afterLoad: function () {
9106
+ var coming = F.coming,
9107
+ previous = F.current,
9108
+ placeholder = 'envirabox-placeholder',
9109
+ current,
9110
+ content,
9111
+ type,
9112
+ scrolling,
9113
+ href,
9114
+ embed;
9115
+
9116
+ F.hideLoading();
9117
+
9118
+ if (!coming || F.isActive === false) {
9119
+ return;
9120
+ }
9121
+
9122
+ if (false === F.trigger('afterLoad', coming, previous)) {
9123
+ coming.wrap.stop(true).trigger('onReset').remove();
9124
+
9125
+ F.coming = null;
9126
+
9127
+ return;
9128
+ }
9129
+
9130
+ if (previous) {
9131
+ F.trigger('beforeChange', previous);
9132
+
9133
+ previous.wrap.stop(true).removeClass('envirabox-opened')
9134
+ .find('.envirabox-item, .envirabox-nav')
9135
+ .remove();
9136
+ }
9137
+
9138
+ F.unbindEvents();
9139
+
9140
+ current = coming;
9141
+ content = coming.content;
9142
+ type = coming.type;
9143
+ scrolling = coming.scrolling;
9144
+
9145
+ $.extend(F, {
9146
+ wrap : current.wrap,
9147
+ skin : current.skin,
9148
+ outer : current.outer,
9149
+ inner : current.inner,
9150
+ current : current,
9151
+ previous : previous
9152
+ });
9153
+
9154
+ href = current.href;
9155
+
9156
+ switch (type) {
9157
+ case 'inline':
9158
+ case 'ajax':
9159
+ case 'html':
9160
+ if (current.selector) {
9161
+ content = $('<div>').html(content).find(current.selector);
9162
+
9163
+ } else if (isQuery(content)) {
9164
+ if (!content.data(placeholder)) {
9165
+ content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter( content ).hide() );
9166
+ }
9167
+
9168
+ content = content.show().detach();
9169
+
9170
+ current.wrap.bind('onReset', function () {
9171
+ if ($(this).find(content).length) {
9172
+ content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false);
9173
+ }
9174
+ });
9175
+ }
9176
+ break;
9177
+
9178
+ case 'image':
9179
+ content = current.tpl.image.replace(/\{href\}/g, href);
9180
+ break;
9181
+
9182
+ case 'swf':
9183
+ content = '<object id="envirabox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>';
9184
+ embed = '';
9185
+
9186
+ $.each(current.swf, function(name, val) {
9187
+ content += '<param name="' + name + '" value="' + val + '"></param>';
9188
+ embed += ' ' + name + '="' + val + '"';
9189
+ });
9190
+
9191
+ content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></embed></object>';
9192
+ break;
9193
+ }
9194
+
9195
+ if (!(isQuery(content) && content.parent().is(current.inner))) {
9196
+ current.inner.append( content );
9197
+ }
9198
+
9199
+ // Give a chance for helpers or callbacks to update elements
9200
+ F.trigger('beforeShow');
9201
+
9202
+ // Set scrolling before calculating dimensions
9203
+ current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling));
9204
+
9205
+ // Set initial dimensions and start position
9206
+ F._setDimension();
9207
+
9208
+ F.reposition();
9209
+
9210
+ F.isOpen = false;
9211
+ F.coming = null;
9212
+
9213
+ F.bindEvents();
9214
+
9215
+ if (!F.isOpened) {
9216
+ $('.envirabox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove();
9217
+
9218
+ } else if (previous.prevMethod) {
9219
+ F.transitions[ previous.prevMethod ]();
9220
+ }
9221
+
9222
+ F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ]();
9223
+
9224
+ F._preloadImages();
9225
+ },
9226
+
9227
+ _setDimension: function () {
9228
+ var viewport = F.getViewport(),
9229
+ steps = 0,
9230
+ canShrink = false,
9231
+ canExpand = false,
9232
+ wrap = F.wrap,
9233
+ skin = F.skin,
9234
+ inner = F.inner,
9235
+ current = F.current,
9236
+ width = current.width,
9237
+ height = current.height,
9238
+ minWidth = current.minWidth,
9239
+ minHeight = current.minHeight,
9240
+ maxWidth = current.maxWidth,
9241
+ maxHeight = current.maxHeight,
9242
+ scrolling = current.scrolling,
9243
+ scrollOut = current.scrollOutside ? current.scrollbarWidth : 0,
9244
+ margin = current.margin,
9245
+ wMargin = getScalar(margin[1] + margin[3]),
9246
+ hMargin = getScalar(margin[0] + margin[2]),
9247
+ wPadding,
9248
+ hPadding,
9249
+ wSpace,
9250
+ hSpace,
9251
+ origWidth,
9252
+ origHeight,
9253
+ origMaxWidth,
9254
+ origMaxHeight,
9255
+ ratio,
9256
+ width_,
9257
+ height_,
9258
+ maxWidth_,
9259
+ maxHeight_,
9260
+ iframe,
9261
+ body;
9262
+
9263
+ // Reset dimensions so we could re-check actual size
9264
+ wrap.add(skin).add(inner).width('auto').height('auto').removeClass('envirabox-tmp');
9265
+
9266
+ wPadding = getScalar(skin.outerWidth(true) - skin.width());
9267
+ hPadding = getScalar(skin.outerHeight(true) - skin.height());
9268
+
9269
+ // Any space between content and viewport (margin, padding, border, title)
9270
+ wSpace = wMargin + wPadding;
9271
+ hSpace = hMargin + hPadding;
9272
+
9273
+ origWidth = isPercentage(width) ? (viewport.w - wSpace) * getScalar(width) / 100 : width;
9274
+ origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height;
9275
+
9276
+ // console.log ( "origWidth = " + origWidth );
9277
+ // console.log ( "origHeight = " + origWidth );
9278
+ // console.log ( "width = " + width );
9279
+ // console.log ( "height = " + height );
9280
+ // console.log ( "isPercentage(width) = " + isPercentage(width) );
9281
+ // console.log ( "isPercentage(height) = " + isPercentage(height) );
9282
+
9283
+ if (current.type === 'iframe') {
9284
+ iframe = current.content;
9285
+
9286
+ if (current.autoHeight && iframe.data('ready') === 1) {
9287
+ try {
9288
+ if (iframe[0].contentWindow.document.location) {
9289
+ inner.width( origWidth ).height(9999);
9290
+
9291
+ body = iframe.contents().find('body');
9292
+
9293
+ if (scrollOut) {
9294
+ body.css('overflow-x', 'hidden');
9295
+ }
9296
+
9297
+ origHeight = body.outerHeight(true);
9298
+ }
9299
+
9300
+ } catch (e) {}
9301
+ }
9302
+
9303
+ } else if (current.autoWidth || current.autoHeight) {
9304
+ inner.addClass( 'envirabox-tmp' );
9305
+
9306
+ // Set width or height in case we need to calculate only one dimension
9307
+ if (!current.autoWidth) {
9308
+ inner.width( origWidth );
9309
+ }
9310
+
9311
+ if (!current.autoHeight) {
9312
+ inner.height( origHeight );
9313
+ }
9314
+
9315
+ if (current.autoWidth) {
9316
+ origWidth = inner.width();
9317
+ }
9318
+
9319
+ if (current.autoHeight) {
9320
+ origHeight = inner.height();
9321
+ }
9322
+
9323
+ inner.removeClass( 'envirabox-tmp' );
9324
+ }
9325
+
9326
+ width = getScalar( origWidth );
9327
+ height = getScalar( origHeight );
9328
+
9329
+ // console.log ( "width = " + width );
9330
+ // console.log ( "height = " + height );
9331
+
9332
+ ratio = origWidth / origHeight;
9333
+
9334
+ // Calculations for the content
9335
+ minWidth = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth);
9336
+ maxWidth = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth);
9337
+
9338
+ minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight);
9339
+ maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight);
9340
+
9341
+ // These will be used to determine if wrap can fit in the viewport
9342
+ origMaxWidth = maxWidth;
9343
+ origMaxHeight = maxHeight;
9344
+
9345
+ if (current.fitToView) {
9346
+ maxWidth = Math.min(viewport.w - wSpace, maxWidth);
9347
+ maxHeight = Math.min(viewport.h - hSpace, maxHeight);
9348
+ }
9349
+
9350
+ maxWidth_ = viewport.w - wMargin;
9351
+ maxHeight_ = viewport.h - hMargin;
9352
+
9353
+ if (current.aspectRatio) {
9354
+ if (width > maxWidth) {
9355
+ width = maxWidth;
9356
+ height = getScalar(width / ratio);
9357
+ }
9358
+
9359
+ if (height > maxHeight) {
9360
+ height = maxHeight;
9361
+ width = getScalar(height * ratio);
9362
+ }
9363
+
9364
+ if (width < minWidth) {
9365
+ width = minWidth;
9366
+ height = getScalar(width / ratio);
9367
+ }
9368
+
9369
+ if (height < minHeight) {
9370
+ height = minHeight;
9371
+ width = getScalar(height * ratio);
9372
+ }
9373
+
9374
+ } else {
9375
+ width = Math.max(minWidth, Math.min(width, maxWidth));
9376
+
9377
+ if (current.autoHeight && current.type !== 'iframe') {
9378
+ inner.width( width );
9379
+
9380
+ height = inner.height();
9381
+ }
9382
+
9383
+ height = Math.max(minHeight, Math.min(height, maxHeight));
9384
+ }
9385
+
9386
+ // Try to fit inside viewport (including the title)
9387
+ if (current.fitToView) {
9388
+ inner.width( width ).height( height );
9389
+
9390
+ wrap.width( width + wPadding );
9391
+
9392
+ // Real wrap dimensions
9393
+ width_ = wrap.width();
9394
+ height_ = wrap.height();
9395
+
9396
+ if (current.aspectRatio) {
9397
+ while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) {
9398
+ if (steps++ > 19) {
9399
+ break;
9400
+ }
9401
+
9402
+ height = Math.max(minHeight, Math.min(maxHeight, height - 10));
9403
+ width = getScalar(height * ratio);
9404
+
9405
+ if (width < minWidth) {
9406
+ width = minWidth;
9407
+ height = getScalar(width / ratio);
9408
+ }
9409
+
9410
+ if (width > maxWidth) {
9411
+ width = maxWidth;
9412
+ height = getScalar(width / ratio);
9413
+ }
9414
+
9415
+ inner.width( width ).height( height );
9416
+
9417
+ wrap.width( width + wPadding );
9418
+
9419
+ width_ = wrap.width();
9420
+ height_ = wrap.height();
9421
+ }
9422
+
9423
+ } else {
9424
+ width = Math.max(minWidth, Math.min(width, width - (width_ - maxWidth_)));
9425
+ height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_)));
9426
+ }
9427
+ }
9428
+
9429
+ if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) {
9430
+ width += scrollOut;
9431
+ }
9432
+
9433
+ // console.log( "before width: " + width);
9434
+ // console.log( "before height: " + height);
9435
+
9436
+ // width = width - (width * 0.01);
9437
+ // height = height - (height * 0.01);
9438
+
9439
+ // console.log( "after width: " + width);
9440
+ // console.log( "after height: " + height);
9441
+
9442
+ inner.width( width ).height( height );
9443
+
9444
+ wrap.width( width + wPadding );
9445
+
9446
+ width_ = wrap.width();
9447
+ height_ = wrap.height();
9448
+
9449
+ canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight;
9450
+ canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight));
9451
+
9452
+ $.extend(current, {
9453
+ dim : {
9454
+ width : getValue( width_ ),
9455
+ height : getValue( height_ )
9456
+ },
9457
+ origWidth : origWidth,
9458
+ origHeight : origHeight,
9459
+ canShrink : canShrink,
9460
+ canExpand : canExpand,
9461
+ wPadding : wPadding,
9462
+ hPadding : hPadding,
9463
+ wrapSpace : height_ - skin.outerHeight(true),
9464
+ skinSpace : skin.height() - height
9465
+ });
9466
+
9467
+ if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) {
9468
+ inner.height('auto');
9469
+ }
9470
+ },
9471
+
9472
+ _getPosition: function (onlyAbsolute) {
9473
+ var current = F.current,
9474
+ viewport = F.getViewport(),
9475
+ margin = current.margin,
9476
+ width = F.wrap.width() + margin[1] + margin[3],
9477
+ height = F.wrap.height() + margin[0] + margin[2],
9478
+ rez = {
9479
+ position: 'absolute',
9480
+ top : margin[0],
9481
+ left : margin[3]
9482
+ };
9483
+
9484
+ // Check for floating title and adjust height.
9485
+ if (current.helpers.title.type && 'float' == current.helpers.title.type) {
9486
+ height = height + $('.envirabox-skin .envirabox-title').height();
9487
+ }
9488
+
9489
+ if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) {
9490
+ rez.position = 'fixed';
9491
+
9492
+ } else if (!current.locked) {
9493
+ rez.top += viewport.y;
9494
+ rez.left += viewport.x;
9495
+ }
9496
+
9497
+ rez.top = getValue(Math.max(rez.top, rez.top + ((viewport.h - height) * current.topRatio)));
9498
+ rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width) * current.leftRatio)));
9499
+
9500
+ return rez;
9501
+ },
9502
+
9503
+ _afterZoomIn: function () {
9504
+ var current = F.current;
9505
+
9506
+ if (!current) {
9507
+ return;
9508
+ }
9509
+
9510
+ F.isOpen = F.isOpened = true;
9511
+
9512
+ F.wrap.css('overflow', 'visible').addClass('envirabox-opened').hide().show(0);
9513
+
9514
+ F.update();
9515
+
9516
+ // Assign a click event
9517
+ if ( current.closeClick || (current.nextClick && F.group.length > 1) ) {
9518
+ F.inner.css('cursor', 'pointer').bind('click.fb', function(e) {
9519
+ if (!$(e.target).is('a') && !$(e.target).parent().is('a')) {
9520
+ e.preventDefault();
9521
+
9522
+ F[ current.closeClick ? 'close' : 'next' ]();
9523
+ }
9524
+ });
9525
+ }
9526
+
9527
+ // Create a close button
9528
+ if (current.closeBtn) {
9529
+ $(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) {
9530
+ e.preventDefault();
9531
+
9532
+ F.close();
9533
+ });
9534
+ }
9535
+
9536
+ // Create navigation arrows
9537
+ if (current.arrows && F.group.length > 1) {
9538
+ if (current.loop || current.index > 0) {
9539
+ $(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev);
9540
+ }
9541
+
9542
+ if (current.loop || current.index < F.group.length - 1) {
9543
+ $(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next);
9544
+ }
9545
+ }
9546
+
9547
+ F.trigger('afterShow');
9548
+
9549
+ // Stop the slideshow if this is the last item
9550
+ if (!current.loop && current.index === current.group.length - 1) {
9551
+
9552
+ F.play( false );
9553
+
9554
+ } else if (F.opts.autoPlay && !F.player.isActive) {
9555
+ F.opts.autoPlay = false;
9556
+
9557
+ F.play(true);
9558
+ }
9559
+ },
9560
+
9561
+ _afterZoomOut: function ( obj ) {
9562
+ obj = obj || F.current;
9563
+
9564
+ $('.envirabox-wrap').trigger('onReset').remove();
9565
+
9566
+ $.extend(F, {
9567
+ group : {},
9568
+ opts : {},
9569
+ router : false,
9570
+ current : null,
9571
+ isActive : false,
9572
+ isOpened : false,
9573
+ isOpen : false,
9574
+ isClosing : false,
9575
+ wrap : null,
9576
+ skin : null,
9577
+ outer : null,
9578
+ inner : null
9579
+ });
9580
+
9581
+ F.trigger('afterClose', obj);
9582
+ }
9583
+ });
9584
+
9585
+ /*
9586
+ * Default transitions
9587
+ */
9588
+
9589
+ F.transitions = {
9590
+ getOrigPosition: function () {
9591
+ var current = F.current,
9592
+ element = current.element,
9593
+ orig = current.orig,
9594
+ pos = {},
9595
+ width = 50,
9596
+ height = 50,
9597
+ hPadding = current.hPadding,
9598
+ wPadding = current.wPadding,
9599
+ viewport = F.getViewport();
9600
+
9601
+ if (!orig && current.isDom && element.is(':visible')) {
9602
+ orig = element.find('img:first');
9603
+
9604
+ if (!orig.length) {
9605
+ orig = element;
9606
+ }
9607
+ }
9608
+
9609
+ if (isQuery(orig)) {
9610
+ pos = orig.offset();
9611
+
9612
+ if (orig.is('img')) {
9613
+ width = orig.outerWidth();
9614
+ height = orig.outerHeight();
9615
+ }
9616
+
9617
+ } else {
9618
+ pos.top = viewport.y + (viewport.h - height) * current.topRatio;
9619
+ pos.left = viewport.x + (viewport.w - width) * current.leftRatio;
9620
+ }
9621
+
9622
+ if (F.wrap.css('position') === 'fixed' || current.locked) {
9623
+ pos.top -= viewport.y;
9624
+ pos.left -= viewport.x;
9625
+ }
9626
+
9627
+ pos = {
9628
+ top : getValue(pos.top - hPadding * current.topRatio),
9629
+ left : getValue(pos.left - wPadding * current.leftRatio),
9630
+ width : getValue(width + wPadding),
9631
+ height : getValue(height + hPadding)
9632
+ };
9633
+
9634
+ return pos;
9635
+ },
9636
+
9637
+ step: function (now, fx) {
9638
+ var ratio,
9639
+ padding,
9640
+ value,
9641
+ prop = fx.prop,
9642
+ current = F.current,
9643
+ wrapSpace = current.wrapSpace,
9644
+ skinSpace = current.skinSpace;
9645
+
9646
+ if (prop === 'width' || prop === 'height') {
9647
+ ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start);
9648
+
9649
+ if (F.isClosing) {
9650
+ ratio = 1 - ratio;
9651
+ }
9652
+
9653
+ padding = prop === 'width' ? current.wPadding : current.hPadding;
9654
+ value = now - padding;
9655
+
9656
+ F.skin[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) ) );
9657
+ F.inner[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) );
9658
+ }
9659
+ },
9660
+
9661
+ zoomIn: function () {
9662
+ var current = F.current,
9663
+ startPos = current.pos,
9664
+ effect = current.openEffect,
9665
+ elastic = effect === 'elastic',
9666
+ endPos = $.extend({opacity : 1}, startPos);
9667
+
9668
+ // Remove "position" property that breaks older IE
9669
+ delete endPos.position;
9670
+
9671
+ if (elastic) {
9672
+ startPos = this.getOrigPosition();
9673
+
9674
+ if (current.openOpacity) {
9675
+ startPos.opacity = 0.1;
9676
+ }
9677
+
9678
+ } else if (effect === 'fade') {
9679
+ startPos.opacity = 0.1;
9680
+ }
9681
+
9682
+ F.wrap.css(startPos).animate(endPos, {
9683
+ duration : effect === 'none' ? 0 : current.openSpeed,
9684
+ easing : current.openEasing,
9685
+ step : elastic ? this.step : null,
9686
+ complete : F._afterZoomIn
9687
+ });
9688
+ },
9689
+
9690
+ zoomOut: function () {
9691
+ var current = F.current,
9692
+ effect = current.closeEffect,
9693
+ elastic = effect === 'elastic',
9694
+ endPos = {opacity : 0.1};
9695
+
9696
+ if (elastic) {
9697
+ endPos = this.getOrigPosition();
9698
+
9699
+ if (current.closeOpacity) {
9700
+ endPos.opacity = 0.1;
9701
+ }
9702
+ }
9703
+
9704
+ F.wrap.animate(endPos, {
9705
+ duration : effect === 'none' ? 0 : current.closeSpeed,
9706
+ easing : current.closeEasing,
9707
+ step : elastic ? this.step : null,
9708
+ complete : F._afterZoomOut
9709
+ });
9710
+ },
9711
+
9712
+ changeIn: function () {
9713
+ var current = F.current,
9714
+ effect = current.nextEffect,
9715
+ startPos = current.pos,
9716
+ endPos = { opacity : 1 },
9717
+ direction = F.direction,
9718
+ distance = 200,
9719
+ field;
9720
+
9721
+ startPos.opacity = 0.1;
9722
+
9723
+ if (effect === 'elastic') {
9724
+ field = direction === 'down' || direction === 'up' ? 'top' : 'left';
9725
+
9726
+ if (direction === 'down' || direction === 'right') {
9727
+ startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance);
9728
+ endPos[ field ] = '+=' + distance + 'px';
9729
+
9730
+ } else {
9731
+ startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance);
9732
+ endPos[ field ] = '-=' + distance + 'px';
9733
+ }
9734
+ }
9735
+
9736
+ // Workaround for http://bugs.jquery.com/ticket/12273
9737
+ if (effect === 'none') {
9738
+ F._afterZoomIn();
9739
+
9740
+ } else {
9741
+ F.wrap.css(startPos).animate(endPos, {
9742
+ duration : current.nextSpeed,
9743
+ easing : current.nextEasing,
9744
+ complete : F._afterZoomIn
9745
+ });
9746
+ }
9747
+ },
9748
+
9749
+ changeOut: function () {
9750
+ var previous = F.previous,
9751
+ effect = previous.prevEffect,
9752
+ endPos = { opacity : 0.1 },
9753
+ direction = F.direction,
9754
+ distance = 200;
9755
+
9756
+ if (effect === 'elastic') {
9757
+ endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px';
9758
+ }
9759
+
9760
+ previous.wrap.animate(endPos, {
9761
+ duration : effect === 'none' ? 0 : previous.prevSpeed,
9762
+ easing : previous.prevEasing,
9763
+ complete : function () {
9764
+ $(this).trigger('onReset').remove();
9765
+ }
9766
+ });
9767
+ }
9768
+ };
9769
+
9770
+ /*
9771
+ * Overlay helper
9772
+ */
9773
+
9774
+ F.helpers.overlay = {
9775
+ defaults : {
9776
+ closeClick : true, // if true, envirabox will be closed when user clicks on the overlay
9777
+ speedOut : 200, // duration of fadeOut animation
9778
+ showEarly : true, // indicates if should be opened immediately or wait until the content is ready
9779
+ css : {}, // custom CSS properties
9780
+ locked : !isTouch, // if true, the content will be locked into overlay
9781
+ fixed : true // if false, the overlay CSS position property will not be set to "fixed"
9782
+ },
9783
+
9784
+ overlay : null, // current handle
9785
+ fixed : false, // indicates if the overlay has position "fixed"
9786
+ el : $('html'), // element that contains "the lock"
9787
+
9788
+ // Public methods
9789
+ create : function(opts) {
9790
+ var parent;
9791
+
9792
+ opts = $.extend({}, this.defaults, opts);
9793
+
9794
+ if (this.overlay) {
9795
+ this.close();
9796
+ }
9797
+
9798
+ parent = F.coming ? F.coming.parent : opts.parent;
9799
+
9800
+ this.overlay = $('<div class="envirabox-overlay"></div>').appendTo( parent && parent.lenth ? parent : 'body' );
9801
+ this.fixed = false;
9802
+
9803
+ if (opts.fixed && F.defaults.fixed) {
9804
+ this.overlay.addClass('envirabox-overlay-fixed');
9805
+
9806
+ this.fixed = true;
9807
+ }
9808
+ },
9809
+
9810
+ open : function(opts) {
9811
+ var that = this;
9812
+
9813
+ opts = $.extend({}, this.defaults, opts);
9814
+
9815
+ if (this.overlay) {
9816
+ this.overlay.unbind('.overlay').width('auto').height('auto');
9817
+
9818
+ } else {
9819
+ this.create(opts);
9820
+ }
9821
+
9822
+ if (!this.fixed) {
9823
+ W.bind('resize.overlay', $.proxy( this.update, this) );
9824
+
9825
+ this.update();
9826
+ }
9827
+
9828
+ if (opts.closeClick) {
9829
+ this.overlay.bind('click.overlay', function(e) {
9830
+ if ($(e.target).hasClass('envirabox-overlay')) {
9831
+ if (F.isActive) {
9832
+ F.close();
9833
+ } else {
9834
+ that.close();
9835
+ }
9836
+
9837
+ return false;
9838
+ }
9839
+ });
9840
+ }
9841
+
9842
+ this.overlay.css( opts.css ).show();
9843
+ },
9844
+
9845
+ close : function() {
9846
+ W.unbind('resize.overlay');
9847
+
9848
+ if (this.el.hasClass('envirabox-lock')) {
9849
+ $('.envirabox-margin').removeClass('envirabox-margin');
9850
+
9851
+ this.el.removeClass('envirabox-lock');
9852
+
9853
+ W.scrollTop( this.scrollV ).scrollLeft( this.scrollH );
9854
+ }
9855
+
9856
+ $('.envirabox-overlay').remove().hide();
9857
+
9858
+ $.extend(this, {
9859
+ overlay : null,
9860
+ fixed : false
9861
+ });
9862
+ },
9863
+
9864
+ // Private, callbacks
9865
+
9866
+ update : function () {
9867
+ var width = '100%', offsetWidth;
9868
+
9869
+ // Reset width/height so it will not mess
9870
+ this.overlay.width(width).height('100%');
9871
+
9872
+ // jQuery does not return reliable result for IE
9873
+ if (IE) {
9874
+ offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth);
9875
+
9876
+ if (D.width() > offsetWidth) {
9877
+ width = D.width();
9878
+ }
9879
+
9880
+ } else if (D.width() > W.width()) {
9881
+ width = D.width();
9882
+ }
9883
+
9884
+
9885
+ this.overlay.width(width).height(D.height());
9886
+ },
9887
+
9888
+ // This is where we can manipulate DOM, because later it would cause iframes to reload
9889
+ onReady : function (opts, obj) {
9890
+ var overlay = this.overlay;
9891
+
9892
+ $('.envirabox-overlay').stop(true, true);
9893
+
9894
+ if (!overlay) {
9895
+ this.create(opts);
9896
+ }
9897
+
9898
+ if (opts.locked && this.fixed && obj.fixed) {
9899
+ obj.locked = this.overlay.append( obj.wrap );
9900
+ obj.fixed = false;
9901
+ }
9902
+
9903
+ if (opts.showEarly === true) {
9904
+ this.beforeShow.apply(this, arguments);
9905
+ }
9906
+ },
9907
+
9908
+ beforeShow : function(opts, obj) {
9909
+ if (obj.locked && !this.el.hasClass('envirabox-lock')) {
9910
+ if (this.fixPosition !== false) {
9911
+ $('*').filter(function(){
9912
+ return ($(this).css('position') === 'fixed' && !$(this).hasClass("envirabox-overlay") && !$(this).hasClass("envirabox-wrap") );
9913
+ }).addClass('envirabox-margin');
9914
+ }
9915
+
9916
+ this.el.addClass('envirabox-margin');
9917
+
9918
+ this.scrollV = W.scrollTop();
9919
+ this.scrollH = W.scrollLeft();
9920
+
9921
+ this.el.addClass('envirabox-lock');
9922
+
9923
+ W.scrollTop( this.scrollV ).scrollLeft( this.scrollH );
9924
+ }
9925
+
9926
+ this.open(opts);
9927
+ },
9928
+
9929
+ onUpdate : function() {
9930
+ if (!this.fixed) {
9931
+ this.update();
9932
+ }
9933
+ },
9934
+
9935
+ afterClose: function (opts) {
9936
+ // Remove overlay if exists and envirabox is not opening
9937
+ // (e.g., it is not being open using afterClose callback)
9938
+ if (this.overlay && !F.coming) {
9939
+ this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this ));
9940
+ }
9941
+ }
9942
+ };
9943
+
9944
+ /*
9945
+ * Title helper
9946
+ */
9947
+
9948
+ F.helpers.title = {
9949
+ defaults : {
9950
+ type : 'float', // 'float', 'inside', 'outside' or 'over',
9951
+ position : 'bottom' // 'top' or 'bottom'
9952
+ },
9953
+
9954
+ beforeShow: function (opts) {
9955
+ var current = F.current,
9956
+ text = current.title,
9957
+ type = opts.type,
9958
+ title,
9959
+ target;
9960
+
9961
+ if ($.isFunction(text)) {
9962
+ text = text.call(current.element, current);
9963
+ }
9964
+
9965
+ if (!isString(text) || $.trim(text) === '') {
9966
+ return;
9967
+ }
9968
+
9969
+ title = $('<div class="envirabox-title envirabox-title-' + type + '-wrap">' + text + '</div>');
9970
+
9971
+ switch (type) {
9972
+ case 'inside':
9973
+ target = F.skin;
9974
+ break;
9975
+
9976
+ case 'outside':
9977
+ target = F.wrap;
9978
+ break;
9979
+
9980
+ case 'over':
9981
+ target = F.inner;
9982
+ break;
9983
+
9984
+ default: // 'float'
9985
+ target = F.skin;
9986
+
9987
+ title.appendTo('body');
9988
+
9989
+ if (IE) {
9990
+ title.width( title.width() );
9991
+ }
9992
+
9993
+ title.wrapInner('<span class="child"></span>');
9994
+
9995
+ //Increase bottom margin so this title will also fit into viewport
9996
+ F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) );
9997
+ break;
9998
+ }
9999
+
10000
+ title[ (opts.position === 'top' ? 'prependTo' : 'appendTo') ](target);
10001
+ }
10002
+ };
10003
+
10004
+ // jQuery plugin initialization
10005
+ $.fn.envirabox = function (options) {
10006
+ var index,
10007
+ that = $(this),
10008
+ selector = this.selector || '',
10009
+ run = function(e) {
10010
+ var what = $(this).blur(),
10011
+ idx = index,
10012
+ relType,
10013
+ relVal;
10014
+
10015
+ if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.envirabox-wrap')) {
10016
+ relType = options.groupAttr || 'data-envirabox-group';
10017
+ relVal = what.attr(relType);
10018
+
10019
+ if (!relVal) {
10020
+ relType = 'rel';
10021
+ relVal = what.get(0)[ relType ];
10022
+ }
10023
+
10024
+ if (relVal && relVal !== '' && relVal !== 'nofollow') {
10025
+ what = selector.length ? $(selector) : that;
10026
+ what = what.filter('[' + relType + '="' + relVal + '"]');
10027
+ idx = what.index(this);
10028
+ }
10029
+
10030
+ options.index = idx;
10031
+
10032
+ // Stop an event from bubbling if everything is fine
10033
+ if (F.open(what, options) !== false) {
10034
+ e.preventDefault();
10035
+ }
10036
+ }
10037
+ };
10038
+
10039
+ options = options || {};
10040
+ index = options.index || 0;
10041
+
10042
+ if (!selector || options.live === false) {
10043
+ that.unbind('click.fb-start').bind('click.fb-start', run);
10044
+
10045
+ } else {
10046
+ D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.envirabox-item, .envirabox-nav')", 'click.fb-start', run);
10047
+ }
10048
+
10049
+ this.filter('[data-envirabox-start=1]').trigger('click');
10050
+
10051
+ return this;
10052
+ };
10053
+
10054
+ // Tests that need a body at doc ready
10055
+ D.ready(function() {
10056
+ var w1, w2;
10057
+
10058
+ if ( $.scrollbarWidth === undefined ) {
10059
+ // http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth
10060
+ $.scrollbarWidth = function() {
10061
+ var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'),
10062
+ child = parent.children(),
10063
+ width = child.innerWidth() - child.height( 99 ).innerWidth();
10064
+
10065
+ parent.remove();
10066
+
10067
+ return width;
10068
+ };
10069
+ }
10070
+
10071
+ if ( $.support.fixedPosition === undefined ) {
10072
+ $.support.fixedPosition = (function() {
10073
+ var elem = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'),
10074
+ fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 );
10075
+
10076
+ elem.remove();
10077
+
10078
+ return fixed;
10079
+ }());
10080
+ }
10081
+
10082
+ $.extend(F.defaults, {
10083
+ scrollbarWidth : $.scrollbarWidth(),
10084
+ fixed : $.support.fixedPosition,
10085
+ parent : $('body')
10086
+ });
10087
+
10088
+ //Get real width of page scroll-bar
10089
+ w1 = $(window).width();
10090
+
10091
+ H.addClass('envirabox-lock-test');
10092
+
10093
+ w2 = $(window).width();
10094
+
10095
+ H.removeClass('envirabox-lock-test');
10096
+
10097
+ $("<style type='text/css'>.envirabox-margin{margin-right:" + (w2 - w1) + "px;}</style>").appendTo("head");
10098
+ });
10099
+
10100
+ }(window, document, jQuery));
10101
+
10102
+ /*!
10103
+ * Buttons helper for envirabox
10104
+ * version: 1.0.5 (Mon, 15 Oct 2012)
10105
+ * @requires envirabox v2.0 or later
10106
+ *
10107
+ * Usage:
10108
+ * $(".envirabox").envirabox({
10109
+ * helpers : {
10110
+ * buttons: {
10111
+ * position : 'top'
10112
+ * }
10113
+ * }
10114
+ * });
10115
+ *
10116
+ */
10117
+ ;(function ($) {
10118
+ //Shortcut for envirabox object
10119
+ var F = $.envirabox;
10120
+
10121
+ //Add helper object
10122
+ F.helpers.buttons = {
10123
+ defaults : {
10124
+ skipSingle : false, // disables if gallery contains single image
10125
+ position : 'top', // 'top' or 'bottom'
10126
+ inline : false, // if true, positioned to scroll with the content (typically set by the Comments helper)
10127
+ tpl : '<div id="envirabox-buttons"><ul><li><a class="btnPrev" title="Previous" href="javascript:;"></a></li><li><a class="btnPlay" title="Start slideshow" href="javascript:;"></a></li><li><a class="btnNext" title="Next" href="javascript:;"></a></li><li><a class="btnToggle" title="Toggle size" href="javascript:;"></a></li><li><a class="btnClose" title="Close" href="javascript:;"></a></li></ul></div>'
10128
+ },
10129
+
10130
+ list : null,
10131
+ buttons: null,
10132
+
10133
+ beforeLoad: function (opts, obj) {
10134
+ //Remove self if gallery do not have at least two items
10135
+
10136
+ if (opts.skipSingle && obj.group.length < 2) {
10137
+ obj.helpers.buttons = false;
10138
+ obj.closeBtn = true;
10139
+
10140
+ return;
10141
+ }
10142
+
10143
+ //Increase top margin to give space for buttons
10144
+ obj.margin[ opts.position === 'bottom' ? 2 : 0 ] += 30;
10145
+
10146
+ // If both buttons and thumbnails are set to display at the top, add a CSS class to thumbnails to adjust their position.
10147
+ if ( obj.helpers.thumbs != undefined && opts.position == 'top' && obj.helpers.thumbs.position == 'top' ) {
10148
+ obj.helpers.thumbs.position = 'top has-other-content';
10149
+ }
10150
+
10151
+ // If both buttons and thumbnails are set to display at the bottom, add a CSS class to thumbnails to adjust their position.
10152
+ if ( obj.helpers.thumbs != undefined && opts.position == 'bottom' && obj.helpers.thumbs.position == 'bottom' ) {
10153
+ obj.helpers.thumbs.position = 'bottom has-other-content';
10154
+ }
10155
+ },
10156
+
10157
+ onPlayStart: function () {
10158
+ if (this.buttons) {
10159
+ this.buttons.play.attr('title', 'Pause slideshow').addClass('btnPlayOn');
10160
+ }
10161
+ },
10162
+
10163
+ onPlayEnd: function () {
10164
+ if (this.buttons) {
10165
+ this.buttons.play.attr('title', 'Start slideshow').removeClass('btnPlayOn');
10166
+ }
10167
+ },
10168
+
10169
+ afterShow: function (opts, obj) {
10170
+ var buttons = this.buttons;
10171
+
10172
+ if (!buttons) {
10173
+ this.list = $(opts.tpl).addClass(opts.position).appendTo('body');
10174
+
10175
+ // If set to inline, add a class now
10176
+ if ( opts.inline ) {
10177
+ this.list.addClass( 'inline' );
10178
+ }
10179
+
10180
+ buttons = {
10181
+ prev : this.list.find('.btnPrev').click( F.prev ),
10182
+ next : this.list.find('.btnNext').click( F.next ),
10183
+ play : this.list.find('.btnPlay').click( F.play ),
10184
+ toggle : this.list.find('.btnToggle').click( F.toggle ),
10185
+ close : this.list.find('.btnClose').click( F.close )
10186
+ }
10187
+ }
10188
+
10189
+ //Prev
10190
+ if (obj.index > 0 || obj.loop) {
10191
+ buttons.prev.removeClass('btnDisabled');
10192
+ } else {
10193
+ buttons.prev.addClass('btnDisabled');
10194
+ }
10195
+
10196
+ //Next / Play
10197
+ if (obj.loop || obj.index < obj.group.length - 1) {
10198
+ buttons.next.removeClass('btnDisabled');
10199
+ buttons.play.removeClass('btnDisabled');
10200
+
10201
+ } else {
10202
+ buttons.next.addClass('btnDisabled');
10203
+ buttons.play.addClass('btnDisabled');
10204
+ }
10205
+
10206
+ this.buttons = buttons;
10207
+
10208
+ this.onUpdate(opts, obj);
10209
+ },
10210
+
10211
+ onUpdate: function (opts, obj) {
10212
+ var toggle;
10213
+
10214
+ if (!this.buttons) {
10215
+ return;
10216
+ }
10217
+
10218
+ toggle = this.buttons.toggle.removeClass('btnDisabled btnToggleOn');
10219
+
10220
+ //Size toggle button
10221
+ if (obj.canShrink) {
10222
+ toggle.addClass('btnToggleOn');
10223
+
10224
+ } else if (!obj.canExpand) {
10225
+ toggle.addClass('btnDisabled');
10226
+ }
10227
+ },
10228
+
10229
+ beforeClose: function () {
10230
+ if (this.list) {
10231
+ this.list.remove();
10232
+ }
10233
+
10234
+ this.list = null;
10235
+ this.buttons = null;
10236
+ }
10237
+ };
10238
+
10239
+ }(jQuery));
10240
+
10241
+ /*!
10242
+ * Media helper for envirabox
10243
+ * version: 1.0.6 (Fri, 14 Jun 2013)
10244
+ * @requires envirabox v2.0 or later
10245
+ *
10246
+ * Usage:
10247
+ * $(".envirabox").envirabox({
10248
+ * helpers : {
10249
+ * media: true
10250
+ * }
10251
+ * });
10252
+ *
10253
+ * Set custom URL parameters:
10254
+ * $(".envirabox").envirabox({
10255
+ * helpers : {
10256
+ * media: {
10257
+ * youtube : {
10258
+ * params : {
10259
+ * autoplay : 0
10260
+ * }
10261
+ * }
10262
+ * }
10263
+ * }
10264
+ * });
10265
+ *
10266
+ * Or:
10267
+ * $(".envirabox").envirabox({,
10268
+ * helpers : {
10269
+ * media: true
10270
+ * },
10271
+ * youtube : {
10272
+ * autoplay: 0
10273
+ * }
10274
+ * });
10275
+ *
10276
+ * Supports:
10277
+ *
10278
+ * Youtube
10279
+ * http://www.youtube.com/watch?v=opj24KnzrWo
10280
+ * http://www.youtube.com/embed/opj24KnzrWo
10281
+ * http://youtu.be/opj24KnzrWo
10282
+ * http://www.youtube-nocookie.com/embed/opj24KnzrWo
10283
+ * Vimeo
10284
+ * http://vimeo.com/40648169
10285
+ * http://vimeo.com/channels/staffpicks/38843628
10286
+ * http://vimeo.com/groups/surrealism/videos/36516384
10287
+ * http://player.vimeo.com/video/45074303
10288
+ * Metacafe
10289
+ * http://www.metacafe.com/watch/7635964/dr_seuss_the_lorax_movie_trailer/
10290
+ * http://www.metacafe.com/watch/7635964/
10291
+ * Dailymotion
10292
+ * http://www.dailymotion.com/video/xoytqh_dr-seuss-the-lorax-premiere_people
10293
+ * Twitvid
10294
+ * http://twitvid.com/QY7MD
10295
+ * Twitpic
10296
+ * http://twitpic.com/7p93st
10297
+ * Instagram
10298
+ * http://instagr.am/p/IejkuUGxQn/
10299
+ * http://instagram.com/p/IejkuUGxQn/
10300
+ * Google maps
10301
+ * http://maps.google.com/maps?q=Eiffel+Tower,+Avenue+Gustave+Eiffel,+Paris,+France&t=h&z=17
10302
+ * http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16
10303
+ * http://maps.google.com/?ll=48.859463,2.292626&spn=0.000965,0.002642&t=m&z=19&layer=c&cbll=48.859524,2.292532&panoid=YJ0lq28OOy3VT2IqIuVY0g&cbp=12,151.58,,0,-15.56
10304
+ */
10305
+ ;(function ($) {
10306
+ "use strict";
10307
+
10308
+ //Shortcut for envirabox object
10309
+ var F = $.envirabox,
10310
+ format = function( url, rez, params ) {
10311
+ params = params || '';
10312
+
10313
+ if ( $.type( params ) === "object" ) {
10314
+ params = $.param(params, true);
10315
+ }
10316
+
10317
+ $.each(rez, function(key, value) {
10318
+ url = url.replace( '$' + key, value || '' );
10319
+ });
10320
+
10321
+ if (params.length) {
10322
+ url += ( url.indexOf('?') > 0 ? '&' : '?' ) + params;
10323
+ }
10324
+
10325
+ return url;
10326
+ };
10327
+
10328
+ //Add helper object
10329
+ F.helpers.media = {
10330
+ defaults : {
10331
+ youtube : {
10332
+ matcher : /(youtube\.com|youtu\.be|youtube-nocookie\.com)\/(watch\?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*)).*/i,
10333
+ params : {
10334
+ autoplay : 1,
10335
+ autohide : 1,
10336
+ fs : 1,
10337
+ rel : 0,
10338
+ hd : 1,
10339
+ wmode : 'opaque',
10340
+ enablejsapi : 1
10341
+ },
10342
+ type : 'iframe',
10343
+ url : '//www.youtube.com/embed/$3'
10344
+ },
10345
+ vimeo : {
10346
+ matcher : /(?:vimeo(?:pro)?.com)\/(?:[^\d]+)?(\d+)(?:.*)/,
10347
+ params : {
10348
+ autoplay : 1,
10349
+ hd : 1,
10350
+ show_title : 1,
10351
+ show_byline : 1,
10352
+ show_portrait : 0,
10353
+ fullscreen : 1
10354
+ },
10355
+ type : 'iframe',
10356
+ url : '//player.vimeo.com/video/$1'
10357
+ },
10358
+ metacafe : {
10359
+ matcher : /metacafe.com\/(?:watch|fplayer)\/([\w\-]{1,10})/,
10360
+ params : {
10361
+ autoPlay : 'yes'
10362
+ },
10363
+ type : 'swf',
10364
+ url : function( rez, params, obj ) {
10365
+ obj.swf.flashVars = 'playerVars=' + $.param( params, true );
10366
+
10367
+ return '//www.metacafe.com/fplayer/' + rez[1] + '/.swf';
10368
+ }
10369
+ },
10370
+ dailymotion : {
10371
+ matcher : /dailymotion.com\/video\/(.*)\/?(.*)/,
10372
+ params : {
10373
+ additionalInfos : 0,
10374
+ autoStart : 1
10375
+ },
10376
+ type : 'swf',
10377
+ url : '//www.dailymotion.com/swf/video/$1'
10378
+ },
10379
+ twitvid : {
10380
+ matcher : /twitvid\.com\/([a-zA-Z0-9_\-\?\=]+)/i,
10381
+ params : {
10382
+ autoplay : 0
10383
+ },
10384
+ type : 'iframe',
10385
+ url : '//www.twitvid.com/embed.php?guid=$1'
10386
+ },
10387
+ twitpic : {
10388
+ matcher : /twitpic\.com\/(?!(?:place|photos|events)\/)([a-zA-Z0-9\?\=\-]+)/i,
10389
+ type : 'image',
10390
+ url : '//twitpic.com/show/full/$1/'
10391
+ },
10392
+ instagram : {
10393
+ matcher : /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i,
10394
+ type : 'image',
10395
+ url : '//$1/p/$2/media/?size=l'
10396
+ },
10397
+ google_maps : {
10398
+ matcher : /maps\.google\.([a-z]{2,3}(\.[a-z]{2})?)\/(\?ll=|maps\?)(.*)/i,
10399
+ type : 'iframe',
10400
+ url : function( rez ) {
10401
+ return '//maps.google.' + rez[1] + '/' + rez[3] + '' + rez[4] + '&output=' + (rez[4].indexOf('layer=c') > 0 ? 'svembed' : 'embed');
10402
+ }
10403
+ }
10404
+ },
10405
+
10406
+ beforeLoad : function(opts, obj) {
10407
+ var url = obj.href || '',
10408
+ type = false,
10409
+ what,
10410
+ item,
10411
+ rez,
10412
+ params;
10413
+
10414
+ for (what in opts) {
10415
+ if (opts.hasOwnProperty(what)) {
10416
+ item = opts[ what ];
10417
+ rez = url.match( item.matcher );
10418
+
10419
+ if (rez) {
10420
+ type = item.type;
10421
+ params = $.extend(true, {}, item.params, obj[ what ] || ($.isPlainObject(opts[ what ]) ? opts[ what ].params : null));
10422
+
10423
+ url = $.type( item.url ) === "function" ? item.url.call( this, rez, params, obj ) : format( item.url, rez, params );
10424
+
10425
+ break;
10426
+ }
10427
+ }
10428
+ }
10429
+
10430
+ if (type) {
10431
+ obj.href = url;
10432
+ obj.type = type;
10433
+
10434
+ obj.autoHeight = false;
10435
+ }
10436
+ }
10437
+ };
10438
+
10439
+ }(jQuery));
10440
+
10441
+ /*!
10442
+ * Thumbnail helper for envirabox
10443
+ * version: 1.0.7 (Mon, 01 Oct 2012)
10444
+ * @requires envirabox v2.0 or later
10445
+ *
10446
+ * Usage:
10447
+ * $(".envirabox").envirabox({
10448
+ * helpers : {
10449
+ * thumbs: {
10450
+ * width : 50,
10451
+ * height : 50
10452
+ * }
10453
+ * }
10454
+ * });
10455
+ *
10456
+ */
10457
+ ;(function ($) {
10458
+ //Shortcut for envirabox object
10459
+ var F = $.envirabox;
10460
+
10461
+ //Add helper object
10462
+ F.helpers.thumbs = {
10463
+ defaults : {
10464
+ width : 50, // thumbnail width
10465
+ height : 50, // thumbnail height
10466
+ position : 'bottom', // 'top' or 'bottom'
10467
+ inline : false, // if true, positioned to scroll with the content (typically set by the Comments helper)
10468
+ source : function ( item ) { // function to obtain the URL of the thumbnail image
10469
+ var href;
10470
+
10471
+ if (item.element) {
10472
+ href = $(item.element).find('img').attr('src');
10473
+ }
10474
+
10475
+ if (!href && item.type === 'image' && item.href) {
10476
+ href = item.href;
10477
+ }
10478
+
10479
+ return href;
10480
+ }
10481
+ },
10482
+
10483
+ wrap : null,
10484
+ list : null,
10485
+ width : 0,
10486
+
10487
+ init: function (opts, obj) {
10488
+ var that = this,
10489
+ list,
10490
+ thumbWidth = opts.width,
10491
+ thumbHeight = opts.height,
10492
+ thumbSource = opts.source;
10493
+
10494
+ //Build list structure
10495
+ list = '';
10496
+
10497
+ for (var n = 0; n < obj.group.length; n++) {
10498
+ list += '<li><a style="width:' + thumbWidth + 'px;height:' + thumbHeight + 'px;" href="javascript:jQuery.envirabox.jumpto(' + n + ');"></a></li>';
10499
+ }
10500
+
10501
+ this.wrap = $('<div id="envirabox-thumbs"></div>').addClass(opts.position).appendTo('body');
10502
+ this.list = $('<ul>' + list + '</ul>').appendTo(this.wrap);
10503
+
10504
+ //Load each thumbnail
10505
+ $.each(obj.group, function (i) {
10506
+ var el = obj.group[ i ],
10507
+ href = thumbSource( el );
10508
+
10509
+ if (!href) {
10510
+ return;
10511
+ }
10512
+
10513
+ $("<img />").load(function () {
10514
+ var width = this.width,
10515
+ height = this.height,
10516
+ widthRatio, heightRatio, parent;
10517
+
10518
+ if (!that.list || !width || !height) {
10519
+ return;
10520
+ }
10521
+
10522
+ //Calculate thumbnail width/height and center it
10523
+ widthRatio = width / thumbWidth;
10524
+ heightRatio = height / thumbHeight;
10525
+
10526
+ parent = that.list.children().eq(i).find('a');
10527
+
10528
+ if (widthRatio >= 1 && heightRatio >= 1) {
10529
+ if (widthRatio > heightRatio) {
10530
+ width = Math.floor(width / heightRatio);
10531
+ height = thumbHeight;
10532
+
10533
+ } else {
10534
+ width = thumbWidth;
10535
+ height = Math.floor(height / widthRatio);
10536
+ }
10537
+ }
10538
+
10539
+ $(this).css({
10540
+ width : width,
10541
+ height : height,
10542
+ top : Math.floor(thumbHeight / 2 - height / 2),
10543
+ left : Math.floor(thumbWidth / 2 - width / 2)
10544
+ });
10545
+
10546
+ parent.width(thumbWidth).height(thumbHeight);
10547
+
10548
+ $(this).hide().appendTo(parent).fadeIn(300);
10549
+
10550
+ })
10551
+ .attr('src', href)
10552
+ .attr('title', el.title);
10553
+ });
10554
+
10555
+ //Set initial width
10556
+ // outerWidth(true) doesn't include border width, so we calculate a single thumbnail's width manually
10557
+ // Old code is commented out.
10558
+ var thumb = this.list.children().eq(0),
10559
+ thumb_link = $('a', $(thumb));
10560
+
10561
+ // Link left border + link right border + li left margin + li right margin + li width = thumbnail width
10562
+ this.width = parseInt( thumb_link.css('border-left-width') ) + parseInt( thumb_link.css('border-left-width') ) + parseInt( thumb.css('margin-left') ) + parseInt( thumb.css('margin-right') ) + parseInt( thumb.css('width') );
10563
+
10564
+ /*
10565
+ // Debug
10566
+ console.log( parseInt( thumb_link.css('border-left-width') ) );
10567
+ console.log( parseInt( thumb_link.css('border-right-width') ) );
10568
+ console.log( parseInt( thumb.css('margin-left') ) );
10569
+ console.log( parseInt( thumb.css('margin-right') ) );
10570
+ console.log( parseInt( thumb.css('width') ) );
10571
+ console.log( this.width );
10572
+ */
10573
+
10574
+ this.list.width(this.width * obj.group.length).css('left', Math.floor($(window).width() * 0.5 - (obj.index * this.width + this.width * 0.5)));
10575
+
10576
+ //this.width = this.list.children().eq(0).outerWidth(true);
10577
+ //this.list.width(this.width * (obj.group.length + 1)).css('left', Math.floor($(window).width() * 0.5 - (obj.index * this.width + this.width * 0.5)));
10578
+ },
10579
+
10580
+ beforeLoad: function (opts, obj) {
10581
+ //Remove self if gallery do not have at least two items
10582
+ if (obj.group.length < 2) {
10583
+ obj.helpers.thumbs = false;
10584
+
10585
+ return;
10586
+ }
10587
+
10588
+ //Increase bottom margin to give space for thumbs
10589
+ obj.margin[ opts.position === 'top' ? 0 : 2 ] += ((opts.height) + 15);
10590
+ },
10591
+
10592
+ afterShow: function (opts, obj) {
10593
+ //Check if exists and create or update list
10594
+ if (this.list) {
10595
+ this.onUpdate(opts, obj);
10596
+
10597
+ } else {
10598
+ this.init(opts, obj);
10599
+ }
10600
+
10601
+ // If set to inline, add a class now
10602
+ if ( opts.inline ) {
10603
+ this.wrap.addClass( 'inline' );
10604
+ }
10605
+
10606
+ //Set active element
10607
+ this.list.children().removeClass('active').eq(obj.index).addClass('active');
10608
+ },
10609
+
10610
+ //Center list
10611
+ onUpdate: function (opts, obj) {
10612
+ if (this.list) {
10613
+ this.list.stop(true).animate({
10614
+ 'left': Math.floor($(window).width() * 0.5 - (obj.index * this.width + this.width * 0.5))
10615
+ }, 150);
10616
+ }
10617
+ },
10618
+
10619
+ beforeClose: function () {
10620
+ if (this.wrap) {
10621
+ this.wrap.remove();
10622
+ }
10623
+
10624
+ this.wrap = null;
10625
+ this.list = null;
10626
+ this.width = 0;
10627
+ }
10628
+ }
10629
+
10630
+ }(jQuery));
10631
+
envira-gallery-lite.php CHANGED
@@ -5,7 +5,7 @@
5
  * Description: Envira Gallery is best responsive WordPress gallery plugin. This is the lite version.
6
  * Author: Thomas Griffin
7
  * Author URI: http://enviragallery.com
8
- * Version: 1.5.0.8
9
  * Text Domain: envira-gallery
10
  *
11
  * Envira Gallery is free software: you can redistribute it and/or modify
@@ -53,7 +53,7 @@ class Envira_Gallery_Lite {
53
  *
54
  * @var string
55
  */
56
- public $version = '1.5.0.8';
57
 
58
  /**
59
  * The name of the plugin.
5
  * Description: Envira Gallery is best responsive WordPress gallery plugin. This is the lite version.
6
  * Author: Thomas Griffin
7
  * Author URI: http://enviragallery.com
8
+ * Version: 1.5.1
9
  * Text Domain: envira-gallery
10
  *
11
  * Envira Gallery is free software: you can redistribute it and/or modify
53
  *
54
  * @var string
55
  */
56
+ public $version = '1.5.1';
57
 
58
  /**
59
  * The name of the plugin.
includes/admin/media-view.php CHANGED
@@ -62,6 +62,16 @@ class Envira_Gallery_Media_View {
62
  */
63
  public function media_view_strings( $strings ) {
64
 
 
 
 
 
 
 
 
 
 
 
65
  return $strings;
66
 
67
  }
@@ -300,8 +310,8 @@ class Envira_Gallery_Media_View {
300
  <!-- Link in New Window -->
301
  <label class="setting">
302
  <span class="name"><?php _e( 'Open URL in New Window?', 'envira-gallery' ); ?></span>
303
- <input type="checkbox" name="link_new_window" value="1"<# if ( data.link_new_window == '1' ) { #> checked <# } #> />
304
  <span class="description">
 
305
  <?php _e( 'Opens your image links in a new browser window / tab.', 'envira-gallery' ); ?>
306
  </span>
307
  </label>
@@ -425,8 +435,8 @@ class Envira_Gallery_Media_View {
425
  <!-- Link in New Window -->
426
  <label class="setting">
427
  <span class="name"><?php _e( 'Open URL in New Window?', 'envira-gallery' ); ?></span>
428
- <input type="checkbox" name="link_new_window" value="1" />
429
  <span class="description">
 
430
  <?php _e( 'Opens your image links in a new browser window / tab.', 'envira-gallery' ); ?>
431
  </span>
432
  </label>
62
  */
63
  public function media_view_strings( $strings ) {
64
 
65
+ // Get the current screen, and check whether we're viewing the Envira or Envira Album Post Types.
66
+ $screen = get_current_screen();
67
+ if ( 'envira' !== $screen->post_type && 'envira_album' !== $screen->post_type ) {
68
+ return $strings;
69
+ }
70
+
71
+ // Remove The "insertFromUrlTitle" option
72
+
73
+ unset( $strings['insertFromUrlTitle'] );
74
+
75
  return $strings;
76
 
77
  }
310
  <!-- Link in New Window -->
311
  <label class="setting">
312
  <span class="name"><?php _e( 'Open URL in New Window?', 'envira-gallery' ); ?></span>
 
313
  <span class="description">
314
+ <input type="checkbox" name="link_new_window" value="1"<# if ( data.link_new_window == '1' ) { #> checked <# } #> />
315
  <?php _e( 'Opens your image links in a new browser window / tab.', 'envira-gallery' ); ?>
316
  </span>
317
  </label>
435
  <!-- Link in New Window -->
436
  <label class="setting">
437
  <span class="name"><?php _e( 'Open URL in New Window?', 'envira-gallery' ); ?></span>
 
438
  <span class="description">
439
+ <input type="checkbox" name="link_new_window" value="1" />
440
  <?php _e( 'Opens your image links in a new browser window / tab.', 'envira-gallery' ); ?>
441
  </span>
442
  </label>
includes/admin/metaboxes.php CHANGED
@@ -807,14 +807,14 @@ class Envira_Gallery_Metaboxes {
807
  </a>
808
  </small>
809
  </p>
810
- <table class="form-table">
811
  <tbody>
812
  <tr id="envira-config-columns-box">
813
  <th scope="row">
814
  <label for="envira-config-columns"><?php _e( 'Number of Gallery Columns', 'envira-gallery' ); ?></label>
815
  </th>
816
  <td>
817
- <select id="envira-config-columns" name="_envira_gallery[columns]">
818
  <?php foreach ( (array) $this->get_columns() as $i => $data ) : ?>
819
  <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'columns', $this->get_config_default( 'columns' ) ) ); ?>><?php echo $data['name']; ?></option>
820
  <?php endforeach; ?>
@@ -822,243 +822,285 @@ class Envira_Gallery_Metaboxes {
822
  <p class="description"><?php _e( 'Determines the number of columns in the gallery. Automatic will attempt to fill each row as much as possible before moving on to the next row.', 'envira-gallery' ); ?></p>
823
  </td>
824
  </tr>
825
- <tr id="envira-config-gallery-theme-box">
826
- <th scope="row">
827
- <label for="envira-config-gallery-theme"><?php _e( 'Gallery Theme', 'envira-gallery' ); ?></label>
828
- </th>
829
- <td>
830
- <select id="envira-config-gallery-theme" name="_envira_gallery[gallery_theme]">
831
- <?php foreach ( (array) $this->get_gallery_themes() as $i => $data ) : ?>
832
- <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'gallery_theme', $this->get_config_default( 'gallery_theme' ) ) ); ?>><?php echo $data['name']; ?></option>
833
- <?php endforeach; ?>
834
- </select>
835
- <p class="description"><?php _e( 'Sets the theme for the gallery display.', 'envira-gallery' ); ?></p>
836
- </td>
837
- </tr>
838
-
839
- <?php
840
- if ( class_exists( 'Envira_Gallery' ) ) {
841
- ?>
842
- <!-- Display Description -->
843
- <tr id="envira-config-display-description-box">
844
  <th scope="row">
845
- <label for="envira-config-display-description"><?php _e( 'Display Gallery Description?', 'envira-gallery' ); ?></label>
846
  </th>
847
  <td>
848
- <select id="envira-config-display-description" name="_envira_gallery[description_position]" data-envira-conditional="envira-config-description-box">
849
- <?php
850
- foreach ( (array) $this->get_display_description_options() as $i => $data ) {
851
- ?>
852
- <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'description_position', $this->get_config_default( 'description_position' ) ) ); ?>><?php echo $data['name']; ?></option>
853
- <?php
854
- }
855
- ?>
856
- </select>
857
- <p class="description"><?php _e( 'Choose to display a description above or below this gallery\'s images.', 'envira-gallery' ); ?></p>
858
  </td>
859
  </tr>
860
-
861
- <!-- Description -->
862
- <tr id="envira-config-description-box">
863
  <th scope="row">
864
- <label for="envira-config-gallery-description"><?php _e( 'Gallery Description', 'envira-gallery' ); ?></label>
865
  </th>
866
  <td>
867
- <?php
868
- $description = $this->get_config( 'description' );
869
- if ( empty( $description ) ) {
870
- $description = $this->get_config_default( 'description' );
871
- }
872
- wp_editor( $description, 'envira-gallery-description', array(
873
- 'media_buttons' => false,
874
- 'wpautop' => true,
875
- 'tinymce' => true,
876
- 'textarea_name' => '_envira_gallery[description]',
877
- ) );
878
- ?>
879
- <p class="description"><?php _e( 'The description to display for this gallery.', 'envira-gallery' ); ?></p>
880
  </td>
881
  </tr>
 
 
 
 
 
 
882
  <?php
883
- }
884
- ?>
885
-
886
- <tr id="envira-config-gutter-box">
887
- <th scope="row">
888
- <label for="envira-config-gutter"><?php _e( 'Column Gutter Width', 'envira-gallery' ); ?></label>
889
- </th>
890
- <td>
891
- <input id="envira-config-gutter" type="number" name="_envira_gallery[gutter]" value="<?php echo $this->get_config( 'gutter', $this->get_config_default( 'gutter' ) ); ?>" /> <span class="envira-unit"><?php _e( 'px', 'envira-gallery' ); ?></span>
892
- <p class="description"><?php _e( 'Sets the space between the columns (defaults to 10).', 'envira-gallery' ); ?></p>
893
- </td>
894
- </tr>
895
- <tr id="envira-config-margin-box">
896
- <th scope="row">
897
- <label for="envira-config-margin"><?php _e( 'Margin Below Each Image', 'envira-gallery' ); ?></label>
898
- </th>
899
- <td>
900
- <input id="envira-config-margin" type="number" name="_envira_gallery[margin]" value="<?php echo $this->get_config( 'margin', $this->get_config_default( 'margin' ) ); ?>" /> <span class="envira-unit"><?php _e( 'px', 'envira-gallery' ); ?></span>
901
- <p class="description"><?php _e( 'Sets the space below each item in the gallery.', 'envira-gallery' ); ?></p>
902
- </td>
903
- </tr>
904
 
905
- <?php
906
- if ( class_exists( 'Envira_Gallery' ) ) {
907
- ?>
908
- <!-- Sorting -->
909
- <tr id="envira-config-sorting-box">
910
- <th scope="row">
911
- <label for="envira-config-sorting"><?php _e( 'Sorting', 'envira-gallery' ); ?></label>
912
- </th>
913
- <td>
914
- <select id="envira-config-sorting" name="_envira_gallery[random]" data-envira-conditional="envira-config-sorting-direction-box">
915
  <?php
916
- foreach ( (array) $this->get_sorting_options() as $i => $data ) {
917
- ?>
918
- <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'random', $this->get_config_default( 'random' ) ) ); ?>><?php echo $data['name']; ?></option>
919
- <?php
920
  }
 
 
 
 
 
 
921
  ?>
922
- </select>
923
- <p class="description"><?php _e( 'Choose to sort the images in a different order than displayed on the Images tab.', 'envira-gallery' ); ?></p>
924
- </td>
925
- </tr>
926
- <tr id="envira-config-sorting-direction-box">
 
 
 
 
 
 
 
 
 
927
  <th scope="row">
928
- <label for="envira-config-sorting-direction"><?php _e( 'Direction', 'envira-gallery' ); ?></label>
929
  </th>
930
  <td>
931
- <select id="envira-config-sorting-direction" name="_envira_gallery[sorting_direction]">
932
- <?php
933
- foreach ( (array) $this->get_sorting_directions() as $i => $data ) {
934
- ?>
935
- <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'sorting_direction', $this->get_config_default( 'sorting_direction' ) ) ); ?>><?php echo $data['name']; ?></option>
936
- <?php
937
- }
938
- ?>
939
  </select>
 
940
  </td>
941
  </tr>
942
- <?php
943
- }
944
- ?>
945
 
946
- <!-- Dimensions -->
947
- <tr id="envira-config-image-size-box">
948
- <th scope="row">
949
- <label for="envira-config-image-size"><?php _e( 'Image Size', 'envira-gallery' ); ?></label>
950
- </th>
951
- <td>
952
- <select id="envira-config-image-size" name="_envira_gallery[image_size]" data-envira-conditional="envira-config-crop-size-box,envira-config-crop-box" data-envira-conditional-value="default">
953
- <?php
954
- foreach ( (array) $this->get_image_sizes() as $i => $data ) {
955
- ?>
956
- <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'image_size', $this->get_config_default( 'image_size' ) ) ); ?>><?php echo $data['name']; ?></option>
957
- <?php
958
- }
959
- ?>
960
- </select>
961
- <p class="description"><?php _e( 'Define the maximum image size for the Gallery view. Default will use the below Image Dimensions; Random will allow you to choose one or more WordPress image sizes, which will be used for the gallery output.', 'envira-gallery' ); ?></p>
962
- </td>
963
- </tr>
964
-
965
- <?php
966
- if ( class_exists( 'Envira_Gallery' ) ) {
967
- ?>
968
- <tr id="envira-config-image-sizes-random-box">
969
  <th scope="row">
970
- <label for="envira-config-image-sizes-random"><?php _e( 'Random Image Sizes', 'envira-gallery' ); ?></label>
971
  </th>
972
  <td>
973
- <?php
974
- // Get random image sizes that have been selected, if any.
975
- $image_sizes_random = (array) $this->get_config( 'image_sizes_random', $this->get_config_default( 'image_sizes_random' ) );
976
-
977
- foreach ( (array) $this->get_image_sizes( true ) as $i => $data ) {
978
- ?>
979
- <label for="envira-config-image-sizes-random-<?php echo $data['value']; ?>">
980
- <input id="envira-config-image-sizes-random-<?php echo $data['value']; ?>" type="checkbox" name="_envira_gallery[image_sizes_random][]" value="<?php echo $data['value']; ?>"<?php echo ( in_array( $data['value'], $image_sizes_random ) ? ' checked' : '' ); ?> />
981
- <?php echo $data['name']; ?>
982
- </label><br />
983
- <?php
984
- }
985
- ?>
986
- <p class="description"><?php _e( 'Define the WordPress registered image sizes to include when randomly assigning an image size to each image in your Gallery.', 'envira-gallery' ); ?></p>
987
  </td>
988
  </tr>
989
- <?php
990
- }
991
- ?>
992
-
993
- <tr id="envira-config-crop-size-box">
994
- <th scope="row">
995
- <label for="envira-config-crop-width"><?php _e( 'Image Dimensions', 'envira-gallery' ); ?></label>
996
- </th>
997
- <td>
998
- <input id="envira-config-crop-width" type="number" name="_envira_gallery[crop_width]" value="<?php echo $this->get_config( 'crop_width', $this->get_config_default( 'crop_width' ) ); ?>" /> &#215; <input id="envira-config-crop-height" type="number" name="_envira_gallery[crop_height]" value="<?php echo $this->get_config( 'crop_height', $this->get_config_default( 'crop_height' ) ); ?>" /> <span class="envira-unit"><?php _e( 'px', 'envira-gallery' ); ?></span>
999
- <p class="description"><?php _e( 'You should adjust these dimensions based on the number of columns in your gallery. This does not affect the full size lightbox images.', 'envira-gallery' ); ?></p>
1000
- </td>
1001
- </tr>
1002
- <tr id="envira-config-crop-box">
1003
- <th scope="row">
1004
- <label for="envira-config-crop"><?php _e( 'Crop Images?', 'envira-gallery' ); ?></label>
1005
- </th>
1006
- <td>
1007
- <input id="envira-config-crop" type="checkbox" name="_envira_gallery[crop]" value="<?php echo $this->get_config( 'crop', $this->get_config_default( 'crop' ) ); ?>" <?php checked( $this->get_config( 'crop', $this->get_config_default( 'crop' ) ), 1 ); ?> />
1008
- <span class="description"><?php _e( 'If enabled, forces images to exactly match the sizes defined above for Image Dimensions and Mobile Dimensions.', 'envira-gallery' ); ?></span>
1009
- <span class="description"><?php _e( 'If disabled, images will be resized to maintain their aspect ratio.', 'envira-gallery' ); ?></span>
1010
-
1011
- </td>
1012
- </tr>
1013
-
1014
- <?php
1015
- if ( class_exists( 'Envira_Gallery' ) ) {
1016
- ?>
1017
- <tr id="envira-config-dimensions-box">
1018
  <th scope="row">
1019
- <label for="envira-config-dimensions"><?php _e( 'Set Dimensions on Images?', 'envira-gallery' ); ?></label>
1020
  </th>
1021
  <td>
1022
- <input id="envira-config-dimensions" type="checkbox" name="_envira_gallery[dimensions]" value="<?php echo $this->get_config( 'dimensions', $this->get_config_default( 'dimensions' ) ); ?>" <?php checked( $this->get_config( 'dimensions', $this->get_config_default( 'dimensions' ) ), 1 ); ?> />
1023
- <span class="description"><?php _e( 'Enables or disables the width and height attributes on the img element. Only needs to be enabled if you need to meet Google Pagespeeds requirements.', 'envira-gallery' ); ?></span>
1024
  </td>
1025
  </tr>
1026
- <tr id="envira-config-isotope-box">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1027
  <th scope="row">
1028
- <label for="envira-config-isotope"><?php _e( 'Enable Isotope?', 'envira-gallery' ); ?></label>
1029
  </th>
1030
  <td>
1031
- <input id="envira-config-isotope" type="checkbox" name="_envira_gallery[isotope]" value="<?php echo $this->get_config( 'isotope', $this->get_config_default( 'isotope' ) ); ?>" <?php checked( $this->get_config( 'isotope', $this->get_config_default( 'isotope' ) ), 1 ); ?> />
1032
- <span class="description"><?php _e( 'Enables or disables isotope/masonry layout support for the main gallery images.', 'envira-gallery' ); ?></span>
 
 
 
 
 
 
 
 
1033
  </td>
1034
  </tr>
1035
 
1036
- <tr id="envira-config-css-animations-box">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1037
  <th scope="row">
1038
- <label for="envira-config-css-animations"><?php _e( 'Enable CSS Animations?', 'envira-gallery' ); ?></label>
1039
  </th>
1040
  <td>
1041
- <input id="envira-config-css-animations" type="checkbox" name="_envira_gallery[css_animations]" value="<?php echo $this->get_config( 'css_animations', $this->get_config_default( 'css_animations' ) ); ?>" <?php checked( $this->get_config( 'css_animations', $this->get_config_default( 'css_animations' ) ), 1 ); ?> data-envira-conditional="envira-config-css-opacity-box" />
1042
- <span class="description"><?php _e( 'Enables CSS animations when loading the main gallery images.', 'envira-gallery' ); ?></span>
1043
  </td>
1044
  </tr>
1045
-
1046
- <tr id="envira-config-css-opacity-box">
1047
  <th scope="row">
1048
- <label for="envira-config-css-opacity"><?php _e( 'Image Opacity', 'envira-gallery' ); ?></label>
1049
  </th>
1050
  <td>
1051
- <input id="envira-config-css-opacity" type="number" name="_envira_gallery[css_opacity]" min="0" max="100" step="1" value="<?php echo $this->get_config( 'css_opacity', $this->get_config_default( 'css_opacity' ) ); ?>" /><span class="envira-unit">%</span>
1052
- <p class="description"><?php _e( 'The opacity to display images at when loading the main gallery images using CSS animations (between 1 and 100%).', 'envira-gallery' ); ?></p>
 
 
1053
  </td>
1054
  </tr>
 
1055
  <?php
1056
- }
1057
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1058
 
1059
- <?php do_action( 'envira_gallery_config_box', $post ); ?>
1060
- </tbody>
1061
- </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1062
  </div>
1063
 
1064
  <?php
@@ -1812,6 +1854,7 @@ class Envira_Gallery_Metaboxes {
1812
  // Update Settings
1813
  $settings['config']['columns'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['columns'] );
1814
  $settings['config']['gallery_theme'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['gallery_theme'] );
 
1815
  $settings['config']['gutter'] = absint( $_POST['_envira_gallery']['gutter'] );
1816
  $settings['config']['margin'] = absint( $_POST['_envira_gallery']['margin'] );
1817
  $settings['config']['crop_width'] = absint( $_POST['_envira_gallery']['crop_width'] );
@@ -1863,6 +1906,7 @@ class Envira_Gallery_Metaboxes {
1863
  $settings['config']['type'] = isset( $_POST['_envira_gallery']['type'] ) ? $_POST['_envira_gallery']['type'] : $this->get_config_default( 'type' );
1864
  $settings['config']['columns'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['columns'] );
1865
  $settings['config']['gallery_theme'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['gallery_theme'] );
 
1866
  $settings['config']['gutter'] = absint( $_POST['_envira_gallery']['gutter'] );
1867
  $settings['config']['margin'] = absint( $_POST['_envira_gallery']['margin'] );
1868
  $settings['config']['image_size'] = sanitize_text_field( $_POST['_envira_gallery']['image_size'] );
@@ -1870,6 +1914,9 @@ class Envira_Gallery_Metaboxes {
1870
  $settings['config']['crop_height'] = absint( $_POST['_envira_gallery']['crop_height'] );
1871
  $settings['config']['crop'] = isset( $_POST['_envira_gallery']['crop'] ) ? 1 : 0;
1872
 
 
 
 
1873
  if ( 'Envira_Gallery' == get_class( $this->base ) ) {
1874
  $settings['config']['description_position'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['description_position'] );
1875
  $settings['config']['description'] = trim( $_POST['_envira_gallery']['description'] );
@@ -2101,9 +2148,9 @@ class Envira_Gallery_Metaboxes {
2101
  // Loop through the images and crop them.
2102
  if ( $images ) {
2103
  // Increase the time limit to account for large image sets and suspend cache invalidations.
2104
- // if ( ! ini_get( 'safe_mode' ) ) {
2105
  set_time_limit( Envira_Gallery_Common::get_instance()->get_max_execution_time() );
2106
- // }
2107
  wp_suspend_cache_invalidation( true );
2108
 
2109
  foreach ( $images as $id => $item ) {
@@ -2170,9 +2217,9 @@ class Envira_Gallery_Metaboxes {
2170
  // Loop through the images and crop them.
2171
  if ( $images ) {
2172
  // Increase the time limit to account for large image sets and suspend cache invalidations.
2173
- // if ( ! ini_get( 'safe_mode' ) ) {
2174
  set_time_limit( Envira_Gallery_Common::get_instance()->get_max_execution_time() );
2175
- // }
2176
  wp_suspend_cache_invalidation( true );
2177
 
2178
  foreach ( $images as $id => $item ) {
@@ -2284,6 +2331,20 @@ class Envira_Gallery_Metaboxes {
2284
 
2285
  }
2286
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2287
  /**
2288
  * Helper method for retrieving description options.
2289
  *
807
  </a>
808
  </small>
809
  </p>
810
+ <table class="form-table" style="margin-bottom: 0;">
811
  <tbody>
812
  <tr id="envira-config-columns-box">
813
  <th scope="row">
814
  <label for="envira-config-columns"><?php _e( 'Number of Gallery Columns', 'envira-gallery' ); ?></label>
815
  </th>
816
  <td>
817
+ <select data-envira-conditional-display="true" data-envira-conditional-value="0" data-envira-conditional="envira-config-justified-settings-box" data-envira-conditional-toggle="envira-config-standard-settings-box" data-envira-conditional-value="1" data-envira-conditional="envira-config-standard-settings-box" id="envira-config-columns" name="_envira_gallery[columns]">
818
  <?php foreach ( (array) $this->get_columns() as $i => $data ) : ?>
819
  <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'columns', $this->get_config_default( 'columns' ) ) ); ?>><?php echo $data['name']; ?></option>
820
  <?php endforeach; ?>
822
  <p class="description"><?php _e( 'Determines the number of columns in the gallery. Automatic will attempt to fill each row as much as possible before moving on to the next row.', 'envira-gallery' ); ?></p>
823
  </td>
824
  </tr>
825
+ </tbody>
826
+ </table>
827
+ <?php // New Automatic Layout / Justified Layout Options ?>
828
+ <div id="envira-config-justified-settings-box">
829
+ <table class="form-table" style="margin-bottom: 0;">
830
+ <tbody>
831
+ <tr id="envira-config-justified-row-height">
 
 
 
 
 
 
 
 
 
 
 
 
832
  <th scope="row">
833
+ <label for="envira-config-justified-row-height"><?php _e( 'Automatic Layout: Row Height', 'envira-gallery' ); ?></label>
834
  </th>
835
  <td>
836
+ <input id="envira-config-justified-row-height" type="number" name="_envira_gallery[justified_row_height]" value="<?php echo $this->get_config( 'justified_row_height', $this->get_config_default( 'justified_row_height' ) ); ?>" /> <span class="envira-unit"><?php _e( 'px', 'envira-gallery' ); ?></span>
837
+ <p class="description"><?php _e( 'Determines how high (in pixels) each row will be. 150px is default. ', 'envira-gallery' ); ?></p>
 
 
 
 
 
 
 
 
838
  </td>
839
  </tr>
840
+ <tr id="envira-config-gallery-justified-theme-box">
 
 
841
  <th scope="row">
842
+ <label for="envira-config-gallery-justified-theme"><?php _e( 'Automatic Layout: Gallery Theme', 'envira-gallery' ); ?></label>
843
  </th>
844
  <td>
845
+ <select id="envira-config-gallery-justified-theme" name="_envira_gallery[justified_gallery_theme]">
846
+ <?php foreach ( (array) $this->get_justified_gallery_themes() as $i => $data ) : ?>
847
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'justified_gallery_theme', $this->get_config_default( 'justified_gallery_theme' ) ) ); ?>><?php echo $data['name']; ?></option>
848
+ <?php endforeach; ?>
849
+ </select>
850
+ <p class="description"><?php _e( 'Sets the theme for the gallery display.', 'envira-gallery' ); ?></p>
 
 
 
 
 
 
 
851
  </td>
852
  </tr>
853
+ </tbody>
854
+ </table>
855
+ </div>
856
+ <div id="envira-config-description-settings-box">
857
+ <table class="form-table">
858
+ <tbody>
859
  <?php
860
+ if ( class_exists( 'Envira_Gallery' ) ) {
861
+ ?>
862
+ <!-- Display Description -->
863
+ <tr id="envira-config-display-description-box">
864
+ <th scope="row">
865
+ <label for="envira-config-display-description"><?php _e( 'Display Gallery Description?', 'envira-gallery' ); ?></label>
866
+ </th>
867
+ <td>
868
+ <select id="envira-config-display-description" name="_envira_gallery[description_position]" data-envira-conditional="envira-config-description-box">
869
+ <?php
870
+ foreach ( (array) $this->get_display_description_options() as $i => $data ) {
871
+ ?>
872
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'description_position', $this->get_config_default( 'description_position' ) ) ); ?>><?php echo $data['name']; ?></option>
873
+ <?php
874
+ }
875
+ ?>
876
+ </select>
877
+ <p class="description"><?php _e( 'Choose to display a description above or below this gallery\'s images.', 'envira-gallery' ); ?></p>
878
+ </td>
879
+ </tr>
 
880
 
881
+ <!-- Description -->
882
+ <tr id="envira-config-description-box">
883
+ <th scope="row">
884
+ <label for="envira-config-gallery-description"><?php _e( 'Gallery Description', 'envira-gallery' ); ?></label>
885
+ </th>
886
+ <td>
 
 
 
 
887
  <?php
888
+ $description = $this->get_config( 'description' );
889
+ if ( empty( $description ) ) {
890
+ $description = $this->get_config_default( 'description' );
 
891
  }
892
+ wp_editor( $description, 'envira-gallery-description', array(
893
+ 'media_buttons' => false,
894
+ 'wpautop' => true,
895
+ 'tinymce' => true,
896
+ 'textarea_name' => '_envira_gallery[description]',
897
+ ) );
898
  ?>
899
+ <p class="description"><?php _e( 'The description to display for this gallery.', 'envira-gallery' ); ?></p>
900
+ </td>
901
+ </tr>
902
+ <?php
903
+ }
904
+ ?>
905
+ </tbody>
906
+ </table>
907
+ </div>
908
+ <div id="envira-config-standard-settings-box">
909
+ <table class="form-table">
910
+ <tbody>
911
+ <?php // ?>
912
+ <tr id="envira-config-gallery-theme-box">
913
  <th scope="row">
914
+ <label for="envira-config-gallery-theme"><?php _e( 'Gallery Theme', 'envira-gallery' ); ?></label>
915
  </th>
916
  <td>
917
+ <select id="envira-config-gallery-theme" name="_envira_gallery[gallery_theme]">
918
+ <?php foreach ( (array) $this->get_gallery_themes() as $i => $data ) : ?>
919
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'gallery_theme', $this->get_config_default( 'gallery_theme' ) ) ); ?>><?php echo $data['name']; ?></option>
920
+ <?php endforeach; ?>
 
 
 
 
921
  </select>
922
+ <p class="description"><?php _e( 'Sets the theme for the gallery display.', 'envira-gallery' ); ?></p>
923
  </td>
924
  </tr>
925
+
 
 
926
 
927
+ <tr id="envira-config-gutter-box">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
928
  <th scope="row">
929
+ <label for="envira-config-gutter"><?php _e( 'Column Gutter Width', 'envira-gallery' ); ?></label>
930
  </th>
931
  <td>
932
+ <input id="envira-config-gutter" type="number" name="_envira_gallery[gutter]" value="<?php echo $this->get_config( 'gutter', $this->get_config_default( 'gutter' ) ); ?>" /> <span class="envira-unit"><?php _e( 'px', 'envira-gallery' ); ?></span>
933
+ <p class="description"><?php _e( 'Sets the space between the columns (defaults to 10).', 'envira-gallery' ); ?></p>
 
 
 
 
 
 
 
 
 
 
 
 
934
  </td>
935
  </tr>
936
+ <tr id="envira-config-margin-box">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
937
  <th scope="row">
938
+ <label for="envira-config-margin"><?php _e( 'Margin Below Each Image', 'envira-gallery' ); ?></label>
939
  </th>
940
  <td>
941
+ <input id="envira-config-margin" type="number" name="_envira_gallery[margin]" value="<?php echo $this->get_config( 'margin', $this->get_config_default( 'margin' ) ); ?>" /> <span class="envira-unit"><?php _e( 'px', 'envira-gallery' ); ?></span>
942
+ <p class="description"><?php _e( 'Sets the space below each item in the gallery.', 'envira-gallery' ); ?></p>
943
  </td>
944
  </tr>
945
+
946
+ <?php
947
+ if ( class_exists( 'Envira_Gallery' ) ) {
948
+ ?>
949
+ <!-- Sorting -->
950
+ <tr id="envira-config-sorting-box">
951
+ <th scope="row">
952
+ <label for="envira-config-sorting"><?php _e( 'Sorting', 'envira-gallery' ); ?></label>
953
+ </th>
954
+ <td>
955
+ <select id="envira-config-sorting" name="_envira_gallery[random]" data-envira-conditional="envira-config-sorting-direction-box">
956
+ <?php
957
+ foreach ( (array) $this->get_sorting_options() as $i => $data ) {
958
+ ?>
959
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'random', $this->get_config_default( 'random' ) ) ); ?>><?php echo $data['name']; ?></option>
960
+ <?php
961
+ }
962
+ ?>
963
+ </select>
964
+ <p class="description"><?php _e( 'Choose to sort the images in a different order than displayed on the Images tab.', 'envira-gallery' ); ?></p>
965
+ </td>
966
+ </tr>
967
+ <tr id="envira-config-sorting-direction-box">
968
+ <th scope="row">
969
+ <label for="envira-config-sorting-direction"><?php _e( 'Direction', 'envira-gallery' ); ?></label>
970
+ </th>
971
+ <td>
972
+ <select id="envira-config-sorting-direction" name="_envira_gallery[sorting_direction]">
973
+ <?php
974
+ foreach ( (array) $this->get_sorting_directions() as $i => $data ) {
975
+ ?>
976
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'sorting_direction', $this->get_config_default( 'sorting_direction' ) ) ); ?>><?php echo $data['name']; ?></option>
977
+ <?php
978
+ }
979
+ ?>
980
+ </select>
981
+ </td>
982
+ </tr>
983
+ <?php
984
+ }
985
+ ?>
986
+
987
+ <!-- Dimensions -->
988
+ <tr id="envira-config-image-size-box">
989
  <th scope="row">
990
+ <label for="envira-config-image-size"><?php _e( 'Image Size', 'envira-gallery' ); ?></label>
991
  </th>
992
  <td>
993
+ <select id="envira-config-image-size" name="_envira_gallery[image_size]" data-envira-conditional="envira-config-crop-size-box,envira-config-crop-box" data-envira-conditional-value="default">
994
+ <?php
995
+ foreach ( (array) $this->get_image_sizes() as $i => $data ) {
996
+ ?>
997
+ <option value="<?php echo $data['value']; ?>"<?php selected( $data['value'], $this->get_config( 'image_size', $this->get_config_default( 'image_size' ) ) ); ?>><?php echo $data['name']; ?></option>
998
+ <?php
999
+ }
1000
+ ?>
1001
+ </select>
1002
+ <p class="description"><?php _e( 'Define the maximum image size for the Gallery view. Default will use the below Image Dimensions; Random will allow you to choose one or more WordPress image sizes, which will be used for the gallery output.', 'envira-gallery' ); ?></p>
1003
  </td>
1004
  </tr>
1005
 
1006
+ <?php
1007
+ if ( class_exists( 'Envira_Gallery' ) ) {
1008
+ ?>
1009
+ <tr id="envira-config-image-sizes-random-box">
1010
+ <th scope="row">
1011
+ <label for="envira-config-image-sizes-random"><?php _e( 'Random Image Sizes', 'envira-gallery' ); ?></label>
1012
+ </th>
1013
+ <td>
1014
+ <?php
1015
+ // Get random image sizes that have been selected, if any.
1016
+ $image_sizes_random = (array) $this->get_config( 'image_sizes_random', $this->get_config_default( 'image_sizes_random' ) );
1017
+
1018
+ foreach ( (array) $this->get_image_sizes( true ) as $i => $data ) {
1019
+ ?>
1020
+ <label for="envira-config-image-sizes-random-<?php echo $data['value']; ?>">
1021
+ <input id="envira-config-image-sizes-random-<?php echo $data['value']; ?>" type="checkbox" name="_envira_gallery[image_sizes_random][]" value="<?php echo $data['value']; ?>"<?php echo ( in_array( $data['value'], $image_sizes_random ) ? ' checked' : '' ); ?> />
1022
+ <?php echo $data['name']; ?>
1023
+ </label><br />
1024
+ <?php
1025
+ }
1026
+ ?>
1027
+ <p class="description"><?php _e( 'Define the WordPress registered image sizes to include when randomly assigning an image size to each image in your Gallery.', 'envira-gallery' ); ?></p>
1028
+ </td>
1029
+ </tr>
1030
+ <?php
1031
+ }
1032
+ ?>
1033
+
1034
+ <tr id="envira-config-crop-size-box">
1035
  <th scope="row">
1036
+ <label for="envira-config-crop-width"><?php _e( 'Image Dimensions', 'envira-gallery' ); ?></label>
1037
  </th>
1038
  <td>
1039
+ <input id="envira-config-crop-width" type="number" name="_envira_gallery[crop_width]" value="<?php echo $this->get_config( 'crop_width', $this->get_config_default( 'crop_width' ) ); ?>" /> &#215; <input id="envira-config-crop-height" type="number" name="_envira_gallery[crop_height]" value="<?php echo $this->get_config( 'crop_height', $this->get_config_default( 'crop_height' ) ); ?>" /> <span class="envira-unit"><?php _e( 'px', 'envira-gallery' ); ?></span>
1040
+ <p class="description"><?php _e( 'You should adjust these dimensions based on the number of columns in your gallery. This does not affect the full size lightbox images.', 'envira-gallery' ); ?></p>
1041
  </td>
1042
  </tr>
1043
+ <tr id="envira-config-crop-box">
 
1044
  <th scope="row">
1045
+ <label for="envira-config-crop"><?php _e( 'Crop Images?', 'envira-gallery' ); ?></label>
1046
  </th>
1047
  <td>
1048
+ <input id="envira-config-crop" type="checkbox" name="_envira_gallery[crop]" value="<?php echo $this->get_config( 'crop', $this->get_config_default( 'crop' ) ); ?>" <?php checked( $this->get_config( 'crop', $this->get_config_default( 'crop' ) ), 1 ); ?> />
1049
+ <span class="description"><?php _e( 'If enabled, forces images to exactly match the sizes defined above for Image Dimensions and Mobile Dimensions.', 'envira-gallery' ); ?></span>
1050
+ <span class="description"><?php _e( 'If disabled, images will be resized to maintain their aspect ratio.', 'envira-gallery' ); ?></span>
1051
+
1052
  </td>
1053
  </tr>
1054
+
1055
  <?php
1056
+ if ( class_exists( 'Envira_Gallery' ) ) {
1057
+ ?>
1058
+ <tr id="envira-config-dimensions-box">
1059
+ <th scope="row">
1060
+ <label for="envira-config-dimensions"><?php _e( 'Set Dimensions on Images?', 'envira-gallery' ); ?></label>
1061
+ </th>
1062
+ <td>
1063
+ <input id="envira-config-dimensions" type="checkbox" name="_envira_gallery[dimensions]" value="<?php echo $this->get_config( 'dimensions', $this->get_config_default( 'dimensions' ) ); ?>" <?php checked( $this->get_config( 'dimensions', $this->get_config_default( 'dimensions' ) ), 1 ); ?> />
1064
+ <span class="description"><?php _e( 'Enables or disables the width and height attributes on the img element. Only needs to be enabled if you need to meet Google Pagespeeds requirements.', 'envira-gallery' ); ?></span>
1065
+ </td>
1066
+ </tr>
1067
+ <tr id="envira-config-isotope-box">
1068
+ <th scope="row">
1069
+ <label for="envira-config-isotope"><?php _e( 'Enable Isotope?', 'envira-gallery' ); ?></label>
1070
+ </th>
1071
+ <td>
1072
+ <input id="envira-config-isotope" type="checkbox" name="_envira_gallery[isotope]" value="<?php echo $this->get_config( 'isotope', $this->get_config_default( 'isotope' ) ); ?>" <?php checked( $this->get_config( 'isotope', $this->get_config_default( 'isotope' ) ), 1 ); ?> />
1073
+ <span class="description"><?php _e( 'Enables or disables isotope/masonry layout support for the main gallery images.', 'envira-gallery' ); ?></span>
1074
+ </td>
1075
+ </tr>
1076
 
1077
+ <tr id="envira-config-css-animations-box">
1078
+ <th scope="row">
1079
+ <label for="envira-config-css-animations"><?php _e( 'Enable CSS Animations?', 'envira-gallery' ); ?></label>
1080
+ </th>
1081
+ <td>
1082
+ <input id="envira-config-css-animations" type="checkbox" name="_envira_gallery[css_animations]" value="<?php echo $this->get_config( 'css_animations', $this->get_config_default( 'css_animations' ) ); ?>" <?php checked( $this->get_config( 'css_animations', $this->get_config_default( 'css_animations' ) ), 1 ); ?> data-envira-conditional="envira-config-css-opacity-box" />
1083
+ <span class="description"><?php _e( 'Enables CSS animations when loading the main gallery images.', 'envira-gallery' ); ?></span>
1084
+ </td>
1085
+ </tr>
1086
+
1087
+ <tr id="envira-config-css-opacity-box">
1088
+ <th scope="row">
1089
+ <label for="envira-config-css-opacity"><?php _e( 'Image Opacity', 'envira-gallery' ); ?></label>
1090
+ </th>
1091
+ <td>
1092
+ <input id="envira-config-css-opacity" type="number" name="_envira_gallery[css_opacity]" min="0" max="100" step="1" value="<?php echo $this->get_config( 'css_opacity', $this->get_config_default( 'css_opacity' ) ); ?>" /><span class="envira-unit">%</span>
1093
+ <p class="description"><?php _e( 'The opacity to display images at when loading the main gallery images using CSS animations (between 1 and 100%).', 'envira-gallery' ); ?></p>
1094
+ </td>
1095
+ </tr>
1096
+ <?php
1097
+ }
1098
+ ?>
1099
+
1100
+ <?php do_action( 'envira_gallery_config_box', $post ); ?>
1101
+ </tbody>
1102
+ </table>
1103
+ </div>
1104
  </div>
1105
 
1106
  <?php
1854
  // Update Settings
1855
  $settings['config']['columns'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['columns'] );
1856
  $settings['config']['gallery_theme'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['gallery_theme'] );
1857
+ $settings['config']['justified_gallery_theme'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['justified_gallery_theme'] );
1858
  $settings['config']['gutter'] = absint( $_POST['_envira_gallery']['gutter'] );
1859
  $settings['config']['margin'] = absint( $_POST['_envira_gallery']['margin'] );
1860
  $settings['config']['crop_width'] = absint( $_POST['_envira_gallery']['crop_width'] );
1906
  $settings['config']['type'] = isset( $_POST['_envira_gallery']['type'] ) ? $_POST['_envira_gallery']['type'] : $this->get_config_default( 'type' );
1907
  $settings['config']['columns'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['columns'] );
1908
  $settings['config']['gallery_theme'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['gallery_theme'] );
1909
+ $settings['config']['justified_gallery_theme'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['justified_gallery_theme'] );
1910
  $settings['config']['gutter'] = absint( $_POST['_envira_gallery']['gutter'] );
1911
  $settings['config']['margin'] = absint( $_POST['_envira_gallery']['margin'] );
1912
  $settings['config']['image_size'] = sanitize_text_field( $_POST['_envira_gallery']['image_size'] );
1914
  $settings['config']['crop_height'] = absint( $_POST['_envira_gallery']['crop_height'] );
1915
  $settings['config']['crop'] = isset( $_POST['_envira_gallery']['crop'] ) ? 1 : 0;
1916
 
1917
+ // Automatic/Justified
1918
+ $settings['config']['justified_row_height'] = isset( $_POST['_envira_gallery']['justified_row_height'] ) ? absint($_POST['_envira_gallery']['justified_row_height'] ) : 150;
1919
+
1920
  if ( 'Envira_Gallery' == get_class( $this->base ) ) {
1921
  $settings['config']['description_position'] = preg_replace( '#[^a-z0-9-_]#', '', $_POST['_envira_gallery']['description_position'] );
1922
  $settings['config']['description'] = trim( $_POST['_envira_gallery']['description'] );
2148
  // Loop through the images and crop them.
2149
  if ( $images ) {
2150
  // Increase the time limit to account for large image sets and suspend cache invalidations.
2151
+ if ( ! ini_get( 'safe_mode' ) ) {
2152
  set_time_limit( Envira_Gallery_Common::get_instance()->get_max_execution_time() );
2153
+ }
2154
  wp_suspend_cache_invalidation( true );
2155
 
2156
  foreach ( $images as $id => $item ) {
2217
  // Loop through the images and crop them.
2218
  if ( $images ) {
2219
  // Increase the time limit to account for large image sets and suspend cache invalidations.
2220
+ if ( ! ini_get( 'safe_mode' ) ) {
2221
  set_time_limit( Envira_Gallery_Common::get_instance()->get_max_execution_time() );
2222
+ }
2223
  wp_suspend_cache_invalidation( true );
2224
 
2225
  foreach ( $images as $id => $item ) {
2331
 
2332
  }
2333
 
2334
+ /**
2335
+ * Helper method for retrieving justified gallery themes.
2336
+ *
2337
+ * @since 1.1.1
2338
+ *
2339
+ * @return array Array of gallery theme data.
2340
+ */
2341
+ public function get_justified_gallery_themes() {
2342
+
2343
+ $instance = Envira_Gallery_Common::get_instance();
2344
+ return $instance->get_justified_gallery_themes();
2345
+
2346
+ }
2347
+
2348
  /**
2349
  * Helper method for retrieving description options.
2350
  *
includes/global/common.php CHANGED
@@ -113,6 +113,27 @@ class Envira_Gallery_Common {
113
 
114
  }
115
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  /**
117
  * Helper method for retrieving display description options.
118
  *
@@ -558,7 +579,9 @@ class Envira_Gallery_Common {
558
  'type' => 'default',
559
 
560
  // Config Tab
561
- 'columns' => '3',
 
 
562
  'gallery_theme' => 'base',
563
  'display_description' => 0,
564
  'description' => '',
@@ -764,6 +787,13 @@ class Envira_Gallery_Common {
764
  // and means our next statement fails
765
  $site_url = preg_replace( '/\?.*/', '', get_bloginfo( 'url' ) );
766
 
 
 
 
 
 
 
 
767
  if ( strpos( $url, $site_url ) === false ) {
768
  return $url;
769
  }
113
 
114
  }
115
 
116
+ /**
117
+ * Helper method for retrieving justified gallery themes.
118
+ *
119
+ * @since 1.1.1
120
+ *
121
+ * @return array Array of gallery theme data.
122
+ */
123
+ public function get_justified_gallery_themes() {
124
+
125
+ $themes = array(
126
+ array(
127
+ 'value' => 'normal',
128
+ 'name' => __( 'Normal', 'envira-gallery' ),
129
+ 'file' => $this->base->file
130
+ )
131
+ );
132
+
133
+ return apply_filters( 'envira_gallery_justified_gallery_themes', $themes );
134
+
135
+ }
136
+
137
  /**
138
  * Helper method for retrieving display description options.
139
  *
579
  'type' => 'default',
580
 
581
  // Config Tab
582
+ 'columns' => '0',
583
+ 'justified_row_height' => 150, // automatic/justified layout
584
+ 'justified_gallery_theme' => 'normal',
585
  'gallery_theme' => 'base',
586
  'display_description' => 0,
587
  'description' => '',
787
  // and means our next statement fails
788
  $site_url = preg_replace( '/\?.*/', '', get_bloginfo( 'url' ) );
789
 
790
+ // WPML check - if there is a /fr or any domain in the url, then remove that from the $site_url
791
+ if ( defined('ICL_LANGUAGE_CODE') ) {
792
+ if ( strpos( $site_url, '/'.ICL_LANGUAGE_CODE ) !== false ) {
793
+ $site_url = str_replace( '/'.ICL_LANGUAGE_CODE, '', $site_url );
794
+ }
795
+ }
796
+
797
  if ( strpos( $url, $site_url ) === false ) {
798
  return $url;
799
  }
includes/global/shortcode.php CHANGED
@@ -85,6 +85,9 @@ class Envira_Gallery_Shortcode {
85
  // Register main gallery style.
86
  wp_register_style( $this->base->plugin_slug . '-style', plugins_url( 'assets/css/envira.css', $this->base->file ), array(), $this->base->version );
87
 
 
 
 
88
  // Register main gallery script.
89
  wp_register_script( $this->base->plugin_slug . '-script', plugins_url( 'assets/js/min/envira-min.js', $this->base->file ), array( 'jquery' ), $this->base->version, true );
90
 
@@ -162,10 +165,12 @@ class Envira_Gallery_Shortcode {
162
 
163
  // Load scripts and styles.
164
  wp_enqueue_style( $this->base->plugin_slug . '-style' );
 
165
  wp_enqueue_script( $this->base->plugin_slug . '-script' );
166
 
167
  // Load custom gallery themes if necessary.
168
- if ( 'base' !== $this->get_config( 'gallery_theme', $data ) ) {
 
169
  $this->load_gallery_theme( $this->get_config( 'gallery_theme', $data ) );
170
  }
171
 
@@ -192,7 +197,13 @@ class Envira_Gallery_Shortcode {
192
  $gallery = $this->description( $gallery, $data );
193
  }
194
 
195
- $gallery .= '<div id="envira-gallery-' . sanitize_html_class( $data['id'] ) . '" class="envira-gallery-public envira-gallery-' . sanitize_html_class( $this->get_config( 'columns', $data ) ) . '-columns envira-clear' . ( $this->get_config( 'isotope', $data ) ? ' enviratope' : '' ) . ( $this->get_config( 'css_animations', $data ) ? ' envira-gallery-css-animations' : '' ) . '" data-envira-columns="' . $this->get_config( 'columns', $data ) . '">';
 
 
 
 
 
 
196
 
197
  // Start image loop
198
  foreach ( $data['gallery'] as $id => $item ) {
@@ -285,6 +296,26 @@ class Envira_Gallery_Shortcode {
285
  $output .= '<div class="envira-gallery-item-inner">';
286
  $output = apply_filters( 'envira_gallery_output_before_link', $output, $id, $item, $data, $i );
287
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  // Caption
289
  // Lite doesn't support captions, so we fallback to the title.
290
  if ( class_exists( 'Envira_Gallery_Lite' ) ) {
@@ -301,8 +332,10 @@ class Envira_Gallery_Shortcode {
301
 
302
  $output = apply_filters( 'envira_gallery_output_before_image', $output, $id, $item, $data, $i );
303
 
 
 
304
  // Build the image and allow filtering
305
- $output_item = '<img id="envira-gallery-image-' . sanitize_html_class( $id ) . '" class="envira-gallery-image envira-gallery-image-' . $i . '" data-envira-index="' . $i . '" src="' . esc_url( $imagesrc ) . '"' . ( $this->get_config( 'dimensions', $data ) ? ' width="' . $this->get_config( 'crop_width', $data ) . '" height="' . $this->get_config( 'crop_height', $data ) . '"' : '' ) . ' data-envira-src="' . esc_url( $imagesrc ) . '" data-envira-gallery-id="' . $data['id'] . '" data-envira-item-id="' . $id . '" alt="' . esc_attr( $item['alt'] ) . '" title="' . strip_tags( html_entity_decode( $item['title'] ) ) . '" ' . apply_filters( 'envira_gallery_output_image_attr', '', $id, $item, $data, $i ) . ' itemprop="thumbnailUrl" srcset="' . esc_url( $image_src_retina ) . ' 2x" />';
306
  $output_item = apply_filters( 'envira_gallery_output_image', $output_item, $id, $item, $data, $i );
307
 
308
  // Add image to output
@@ -587,6 +620,7 @@ class Envira_Gallery_Shortcode {
587
  // envira_isotopes stores all Isotope instances
588
  // envira_isotopes_config stores Isotope configs for each Gallery
589
  ?>
 
590
  <script type="text/javascript">
591
  <?php ob_start(); ?>
592
 
@@ -611,9 +645,85 @@ class Envira_Gallery_Shortcode {
611
  ?>
612
  var envira_container_<?php echo $data['id']; ?> = '';
613
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
614
  <?php
615
  // Isotope: Start
616
- if ( $this->get_config( 'isotope', $data ) ) {
617
  // Define config for this Isotope Gallery
618
  ?>
619
  envira_isotopes_config['<?php echo $data['id']; ?>'] = {
@@ -621,17 +731,17 @@ class Envira_Gallery_Shortcode {
621
  itemSelector: '.envira-gallery-item',
622
  <?php
623
  // If columns = 0, use fitRows
624
- if ( $this->get_config( 'columns', $data ) > 0 ) {
625
  ?>
626
  masonry: {
627
  columnWidth: '.envira-gallery-item'
628
  }
629
- <?php
630
  } else {
631
  ?>
632
  layoutMode: 'fitRows'
633
  <?php
634
- }
635
  ?>
636
  };
637
  <?php
@@ -681,70 +791,8 @@ class Envira_Gallery_Shortcode {
681
  // Those Addons can populate this array now which will tell envirabox which images to use.
682
  $lightbox_images = apply_filters( 'envira_gallery_lightbox_images', false, $data );
683
 
684
-
685
-
686
- if ( ! $lightbox_images ) {
687
- // No lightbox images specified, so use images from DOM
688
- ?>
689
- envira_galleries['<?php echo $data['id']; ?>'] = $('.envira-gallery-<?php echo $data['id']; ?>').envirabox({
690
- <?php
691
-
692
-
693
-
694
- } else {
695
- // Use images from $lightbox_images
696
- add_filter( 'envira_minify_strip_double_forward_slashes', '__return_false' );
697
- ?>
698
- var envira_gallery_images_<?php echo $data['id']; ?> = [];
699
- <?php
700
- // Build a JS array of all images
701
- $count = 0;
702
- foreach ( $lightbox_images as $image_id => $image ) {
703
- // If no image ID exists, skip
704
- if ( empty( $image_id ) ) {
705
- continue;
706
- }
707
- ?>
708
- envira_gallery_images_<?php echo $data['id']; ?>.push({
709
- href: '<?php echo $image['src']; ?>',
710
- gallery_id: <?php echo $data['id']; ?>,
711
- id: <?php echo $image_id; ?>,
712
- alt: '<?php echo addslashes( str_replace( "\n", '<br />', $image['alt'] ) ); ?>',
713
- caption: '<?php echo addslashes( str_replace( "\n", '<br />', $image['caption'] ) ); ?>',
714
- title: '<?php echo addslashes( str_replace( "\n", '<br />', $image['title'] ) ); ?>',
715
- index: <?php echo $count; ?>,
716
- thumbnail: '<?php echo ( isset( $image['thumb'] ) ? $image['thumb'] : '' ); ?>'
717
- <?php do_action( 'envira_gallery_api_lightbox_image_attributes', $image, $image_id, $lightbox_images, $data ); ?>
718
- });
719
- <?php
720
- $count++;
721
- }
722
-
723
- // Open envirabox when an image is clicked, telling envirabox which images are available to it.
724
- ?>
725
- $('#envira-gallery-wrap-<?php echo $data['id']; ?>').on('click', 'a.envira-gallery-link', function(e) {
726
- e.preventDefault();
727
- if ( $('#envira-gallery-wrap-<?php echo $data['id']; ?> div.envira-pagination').length > 0 ) { /* this exists, perhaps pagination doesn't display nav because it's only one page? */
728
- var envirabox_page = ( $('#envira-gallery-wrap-<?php echo $data['id']; ?> div.envira-pagination').data('page') - 1 );
729
- } else {
730
- var envirabox_page = 0;
731
- }
732
-
733
- if ( $('#envira-gallery-wrap-<?php echo $data['id']; ?> div.envira-pagination').length > 0 ) { /* this exists, perhaps pagination doesn't display nav because it's only one page? */
734
- var envirabox_per_page = $('#envira-gallery-wrap-<?php echo $data['id']; ?> div.envira-pagination').data('per-page');
735
- } else {
736
- var envirabox_per_page = $('.envira-gallery-image').length;
737
- }
738
-
739
- var envirabox_index = ( Number($('img', $(this)).data('envira-index')) - 1 );
740
-
741
- envira_galleries['<?php echo $data['id']; ?>'] = $.envirabox( envira_gallery_images_<?php echo $data['id']; ?>, {
742
- index: ((envirabox_page * envirabox_per_page) + envirabox_index),
743
- <?php
744
- }
745
-
746
  ?>
747
-
748
  <?php do_action( 'envira_gallery_api_config', $data ); // Depreciated ?>
749
  <?php do_action( 'envira_gallery_api_envirabox_config', $data ); ?>
750
  <?php if ( ! $this->get_config( 'keyboard', $data ) ) : ?>
@@ -754,7 +802,7 @@ class Envira_Gallery_Shortcode {
754
 
755
  //print_r ($data); exit;
756
 
757
- if ( isset($data['config']['social_lightbox']) && $data['config']['social_lightbox'] == 1 &&
758
  ( null !== $data['config']['social_lightbox_orientation'] && $data['config']['social_lightbox_orientation'] == "vertical" ) ):
759
 
760
  ?>
@@ -816,11 +864,11 @@ class Envira_Gallery_Shortcode {
816
  tpl: {
817
  wrap : '<?php echo $this->get_lightbox_template( $data ); ?>',
818
  image : '<img class="envirabox-image" src="{href}" alt="" data-envira-title="" data-envira-caption="" data-envira-index="" data-envira-data="" />',
819
- iframe : '<iframe id="envirabox-frame{rnd}" name="envirabox-frame{rnd}" class="envirabox-iframe" frameborder="0" vspace="0" hspace="0" allowtransparency="true" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>',
820
  error : '<p class="envirabox-error"><?php echo __( 'The requested content cannot be loaded.<br/>Please try again later.</p>', 'envira-gallery' ); ?>',
821
- closeBtn : '<a title="<?php echo __( 'Close', 'envira-gallery' ); ?>" class="envirabox-item envirabox-close" href="#close"></a>',
822
- next : '<a title="<?php echo __( 'Next', 'envira-gallery' ); ?>" class="envirabox-nav envirabox-next envirabox-arrows-<?php echo $this->get_config( 'arrows_position', $data ); ?>" href="#next"><span></span></a>',
823
- prev : '<a title="<?php echo __( 'Previous', 'envira-gallery' ); ?>" class="envirabox-nav envirabox-prev envirabox-arrows-<?php echo $this->get_config( 'arrows_position', $data ); ?>" href="#prev"><span></span></a>'
824
  <?php do_action( 'envira_gallery_api_templates', $data ); ?>
825
  },
826
  helpers: {
@@ -882,8 +930,10 @@ class Envira_Gallery_Shortcode {
882
  <?php do_action( 'envira_gallery_api_before_load', $data ); ?>
883
  },
884
  afterLoad: function(){
885
- $( ".envirabox-overlay-fixed" ).on( "touchmove", function(e) {
886
- e.preventDefault();
 
 
887
  });
888
 
889
  <?php do_action( 'envira_gallery_api_after_load', $data ); ?>
@@ -947,7 +997,8 @@ class Envira_Gallery_Shortcode {
947
  <?php
948
  if ( $this->get_config( 'mobile_touchwipe', $data ) ) {
949
  ?>
950
- $('.envirabox-wrap').swipe( {
 
951
  swipe: function(event, direction, distance, duration, fingerCount, fingerData) {
952
  if (direction === 'left') {
953
  $.envirabox.next(direction);
@@ -1015,12 +1066,65 @@ class Envira_Gallery_Shortcode {
1015
  onPlayEnd: function(){
1016
  <?php do_action( 'envira_gallery_api_on_play_end', $data ); ?>
1017
  }
1018
- });
1019
-
1020
  <?php
1021
- // If lightbox images were specified, we need to close the click handler now
1022
- if ( $lightbox_images !== false ) {
 
 
 
 
 
 
 
 
1023
  ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1024
  });
1025
  <?php
1026
  }
@@ -1040,6 +1144,7 @@ class Envira_Gallery_Shortcode {
1040
  <?php
1041
  // Minify before outputting to improve page load time.
1042
  echo $this->minify( ob_get_clean() );
 
1043
  ?>
1044
  </script>
1045
  <?php
@@ -1429,10 +1534,32 @@ class Envira_Gallery_Shortcode {
1429
  public function get_lightbox_template( $data ) {
1430
 
1431
  // Build out the lightbox template
1432
- $template = '<div class="envirabox-wrap" tabIndex="-1"><div class="envirabox-skin envirabox-theme-' . $this->get_config( 'lightbox_theme', $data ) . '"><div class="envirabox-outer"><div class="envirabox-inner"></div></div></div></div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1433
 
1434
  // Return the template, filters applied
1435
- return apply_filters( 'envira_gallery_lightbox_template', $template, $data );
1436
 
1437
  }
1438
 
@@ -1452,14 +1579,14 @@ class Envira_Gallery_Shortcode {
1452
  // If we are on a mobile device, some config keys have mobile equivalents, which we need to check instead
1453
  if ( wp_is_mobile() ) {
1454
  if ( class_exists( 'Envira_Gallery' ) ) {
1455
- $mobile_keys = array(
1456
- 'columns' => 'mobile_columns',
1457
- 'lightbox_enabled' => 'mobile_lightbox',
1458
- 'arrows' => 'mobile_arrows',
1459
- 'toolbar' => 'mobile_toolbar',
1460
- 'thumbnails' => 'mobile_thumbnails',
1461
- );
1462
- $mobile_keys = apply_filters( 'envira_gallery_get_config_mobile_keys', $mobile_keys );
1463
 
1464
  // When on mobile, use used to blindly look at the mobile_social option to determine social sharing button output
1465
  // However, what we need to do is look to see if the settings are active on the addon first
@@ -1473,11 +1600,11 @@ class Envira_Gallery_Shortcode {
1473
  }
1474
  }
1475
 
1476
- if ( array_key_exists( $key, $mobile_keys ) ) {
1477
- // Use the mobile array key to get the config value
1478
- $key = $mobile_keys[ $key ];
1479
- }
1480
- }
1481
 
1482
  }
1483
 
85
  // Register main gallery style.
86
  wp_register_style( $this->base->plugin_slug . '-style', plugins_url( 'assets/css/envira.css', $this->base->file ), array(), $this->base->version );
87
 
88
+ // if ( $this->get_config( 'columns', $data ) == 0 ) :
89
+ wp_register_style( $this->base->plugin_slug . '-jgallery', plugins_url( 'assets/css/justifiedGallery.css', $this->base->file ), array(), $this->base->version );
90
+
91
  // Register main gallery script.
92
  wp_register_script( $this->base->plugin_slug . '-script', plugins_url( 'assets/js/min/envira-min.js', $this->base->file ), array( 'jquery' ), $this->base->version, true );
93
 
165
 
166
  // Load scripts and styles.
167
  wp_enqueue_style( $this->base->plugin_slug . '-style' );
168
+ wp_enqueue_style( $this->base->plugin_slug . '-jgallery' );
169
  wp_enqueue_script( $this->base->plugin_slug . '-script' );
170
 
171
  // Load custom gallery themes if necessary.
172
+ if ( 'base' !== $this->get_config( 'gallery_theme', $data ) && $this->get_config( 'columns', $data ) > 0 ) {
173
+ // if columns is zero, then it's automattic which means we do not load gallery themes because it will mess up the new javascript layout
174
  $this->load_gallery_theme( $this->get_config( 'gallery_theme', $data ) );
175
  }
176
 
197
  $gallery = $this->description( $gallery, $data );
198
  }
199
 
200
+
201
+ $opacity_insert = false;
202
+ if ( $this->get_config( 'columns', $data ) == 0 ) {
203
+ $opacity_insert = ' style="opacity: 0.0" ';
204
+ }
205
+
206
+ $gallery .= '<div' . $opacity_insert . ' id="envira-gallery-' . sanitize_html_class( $data['id'] ) . '" class="envira-gallery-public envira-gallery-' . sanitize_html_class( $this->get_config( 'columns', $data ) ) . '-columns envira-clear' . ( $this->get_config( 'isotope', $data ) ? ' enviratope' : '' ) . ( $this->get_config( 'css_animations', $data ) ? ' envira-gallery-css-animations' : '' ) . '" data-envira-columns="' . $this->get_config( 'columns', $data ) . '">';
207
 
208
  // Start image loop
209
  foreach ( $data['gallery'] as $id => $item ) {
296
  $output .= '<div class="envira-gallery-item-inner">';
297
  $output = apply_filters( 'envira_gallery_output_before_link', $output, $id, $item, $data, $i );
298
 
299
+ // Top Left box
300
+ $output .= '<div class="envira-gallery-position-overlay envira-gallery-top-left">';
301
+ $output = apply_filters( 'envira_gallery_output_dynamic_position', $output, $id, $item, $data, $i, 'top-left' );
302
+ $output .= '</div>';
303
+
304
+ // Top Right box
305
+ $output .= '<div class="envira-gallery-position-overlay envira-gallery-top-right">';
306
+ $output = apply_filters( 'envira_gallery_output_dynamic_position', $output, $id, $item, $data, $i, 'top-right' );
307
+ $output .= '</div>';
308
+
309
+ // Bottom Left box
310
+ $output .= '<div class="envira-gallery-position-overlay envira-gallery-bottom-left">';
311
+ $output = apply_filters( 'envira_gallery_output_dynamic_position', $output, $id, $item, $data, $i, 'bottom-left' );
312
+ $output .= '</div>';
313
+
314
+ // Bottom Right box
315
+ $output .= '<div class="envira-gallery-position-overlay envira-gallery-bottom-right">';
316
+ $output = apply_filters( 'envira_gallery_output_dynamic_position', $output, $id, $item, $data, $i, 'bottom-right' );
317
+ $output .= '</div>';
318
+
319
  // Caption
320
  // Lite doesn't support captions, so we fallback to the title.
321
  if ( class_exists( 'Envira_Gallery_Lite' ) ) {
332
 
333
  $output = apply_filters( 'envira_gallery_output_before_image', $output, $id, $item, $data, $i );
334
 
335
+ $gallery_theme = $this->get_config( 'columns', $data ) == 0 ? ' envira-' . $this->get_config( 'justified_gallery_theme', $data ) : '';
336
+
337
  // Build the image and allow filtering
338
+ $output_item = '<img id="envira-gallery-image-' . sanitize_html_class( $id ) . '" class="envira-gallery-image envira-gallery-image-' . $i . $gallery_theme . '" data-envira-index="' . $i . '" src="' . esc_url( $imagesrc ) . '"' . ( $this->get_config( 'dimensions', $data ) ? ' width="' . $this->get_config( 'crop_width', $data ) . '" height="' . $this->get_config( 'crop_height', $data ) . '"' : '' ) . ' data-envira-src="' . esc_url( $imagesrc ) . '" data-envira-gallery-id="' . $data['id'] . '" data-envira-item-id="' . $id . '" data-envira-caption="' . $caption . '" alt="' . esc_attr( $item['alt'] ) . '" title="' . strip_tags( html_entity_decode( $item['title'] ) ) . '" ' . apply_filters( 'envira_gallery_output_image_attr', '', $id, $item, $data, $i ) . ' itemprop="thumbnailUrl" srcset="' . esc_url( $image_src_retina ) . ' 2x" />';
339
  $output_item = apply_filters( 'envira_gallery_output_image', $output_item, $id, $item, $data, $i );
340
 
341
  // Add image to output
620
  // envira_isotopes stores all Isotope instances
621
  // envira_isotopes_config stores Isotope configs for each Gallery
622
  ?>
623
+
624
  <script type="text/javascript">
625
  <?php ob_start(); ?>
626
 
645
  ?>
646
  var envira_container_<?php echo $data['id']; ?> = '';
647
 
648
+ <?php if ( $this->get_config( 'columns', $data ) == 0 ) : ?>
649
+
650
+ <?php
651
+
652
+ // if the user has selected a custom theme, only output the needed JS
653
+ $gallery_theme = $this->get_config( 'justified_gallery_theme', $data );
654
+
655
+ ?>
656
+
657
+ $('#envira-gallery-<?php echo $data["id"]; ?>').enviraJustifiedGallery({
658
+ rowHeight : <?php echo $this->get_config( 'justified_row_height', $data ); ?>,
659
+ maxRowHeight: -1,
660
+ selector: '> div > div',
661
+ lastRow: 'nojustify'
662
+ });
663
+
664
+ <?php if ( $gallery_theme == 'js-desaturate' || $gallery_theme == 'js-threshold' || $gallery_theme == 'js-blur' || $gallery_theme == 'js-vintage' ) : ?>
665
+
666
+ $('#envira-gallery-<?php echo $data["id"]; ?>').on('jg.complete', function (e) {
667
+ if( navigator.userAgent.match(/msie/i) || $.browser.msie || navigator.appVersion.indexOf('Trident/') > 0 ) {
668
+ $('#envira-gallery-<?php echo $data["id"]; ?> img').each(function() {
669
+ var keep_id = $(this).attr('id');
670
+ $(this).attr('id', keep_id + '-effects' );
671
+ $(this).wrap('<div class="effect-wrapper" style="display:inline-block;width:' + this.width + 'px;height:' + this.height + 'px;">').clone().addClass('gotcolors').css({'position': 'absolute', 'opacity' : 0, 'z-index' : 1 }).attr('id', keep_id).insertBefore(this);
672
+ <?php
673
+
674
+ switch ($gallery_theme) {
675
+ case 'js-desaturate':
676
+ echo 'this.src = jg_effect_desaturate($(this).attr("src"));';
677
+ break;
678
+ case 'js-threshold':
679
+ echo 'this.src = jg_effect_threshold(this.src);';
680
+ break;
681
+ case 'js-blur':
682
+ echo 'this.src = jg_effect_blur(this.src);';
683
+ break;
684
+ case 'js-vintage':
685
+ echo 'jg_effect_vintage( this );';
686
+ break;
687
+ }
688
+
689
+ ?>
690
+ });
691
+ $('#envira-gallery-<?php echo $data["id"]; ?> img').hover(
692
+ function() {
693
+ $(this).stop().animate({opacity: 1}, 200);
694
+ },
695
+ function() {
696
+ $(this).stop().animate({opacity: 0}, 200);
697
+ }
698
+ );
699
+ }
700
+ else {
701
+ /*$('#envira-gallery-<?php echo $data["id"]; ?> img').each(function() {
702
+ $(this).addClass('envira-<?php echo $gallery_theme; ?>');
703
+ });*/
704
+
705
+ $('#envira-gallery-<?php echo $data["id"]; ?> img').hover(
706
+ function() {
707
+ $(this).removeClass('envira-<?php echo $gallery_theme; ?>');
708
+ },
709
+ function() {
710
+ $(this).addClass('envira-<?php echo $gallery_theme; ?>');
711
+ }
712
+ );
713
+ }
714
+
715
+
716
+ });
717
+
718
+ <?php endif; ?>
719
+
720
+ $('#envira-gallery-<?php echo $data["id"]; ?>').css('opacity', '1');
721
+
722
+ <?php endif; ?>
723
+
724
  <?php
725
  // Isotope: Start
726
+ if ( $this->get_config( 'columns', $data ) > 0 && $this->get_config( 'isotope', $data ) ) {
727
  // Define config for this Isotope Gallery
728
  ?>
729
  envira_isotopes_config['<?php echo $data['id']; ?>'] = {
731
  itemSelector: '.envira-gallery-item',
732
  <?php
733
  // If columns = 0, use fitRows
734
+ // if ( $this->get_config( 'columns', $data ) > 0 ) {
735
  ?>
736
  masonry: {
737
  columnWidth: '.envira-gallery-item'
738
  }
739
+ <?php /*
740
  } else {
741
  ?>
742
  layoutMode: 'fitRows'
743
  <?php
744
+ } */
745
  ?>
746
  };
747
  <?php
791
  // Those Addons can populate this array now which will tell envirabox which images to use.
792
  $lightbox_images = apply_filters( 'envira_gallery_lightbox_images', false, $data );
793
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
794
  ?>
795
+ envira_gallery_options = {
796
  <?php do_action( 'envira_gallery_api_config', $data ); // Depreciated ?>
797
  <?php do_action( 'envira_gallery_api_envirabox_config', $data ); ?>
798
  <?php if ( ! $this->get_config( 'keyboard', $data ) ) : ?>
802
 
803
  //print_r ($data); exit;
804
 
805
+ if ( isset($data['config']['social_lightbox']) && $data['config']['social_lightbox'] == 1 &&
806
  ( null !== $data['config']['social_lightbox_orientation'] && $data['config']['social_lightbox_orientation'] == "vertical" ) ):
807
 
808
  ?>
864
  tpl: {
865
  wrap : '<?php echo $this->get_lightbox_template( $data ); ?>',
866
  image : '<img class="envirabox-image" src="{href}" alt="" data-envira-title="" data-envira-caption="" data-envira-index="" data-envira-data="" />',
867
+ iframe : '<iframe id="envirabox-frame{rnd}" name="envirabox-frame{rnd}" class="envirabox-iframe" frameborder="0" vspace="0" hspace="0" allowtransparency="true" wekitallowfullscreen mozallowfullscreen allowfullscreen></iframe>',
868
  error : '<p class="envirabox-error"><?php echo __( 'The requested content cannot be loaded.<br/>Please try again later.</p>', 'envira-gallery' ); ?>',
869
+ closeBtn : '<a title="<?php echo __( 'Close', 'envira-gallery' ); ?>" class="envirabox-item envirabox-close" href="#"></a>',
870
+ next : '<a title="<?php echo __( 'Next', 'envira-gallery' ); ?>" class="envirabox-nav envirabox-next envirabox-arrows-<?php echo $this->get_config( 'arrows_position', $data ); ?>" href="#"><span></span></a>',
871
+ prev : '<a title="<?php echo __( 'Previous', 'envira-gallery' ); ?>" class="envirabox-nav envirabox-prev envirabox-arrows-<?php echo $this->get_config( 'arrows_position', $data ); ?>" href="#"><span></span></a>'
872
  <?php do_action( 'envira_gallery_api_templates', $data ); ?>
873
  },
874
  helpers: {
930
  <?php do_action( 'envira_gallery_api_before_load', $data ); ?>
931
  },
932
  afterLoad: function(){
933
+ $('envirabox-overlay-fixed').on({
934
+ 'touchmove' : function(e){
935
+ e.preventDefault();
936
+ }
937
  });
938
 
939
  <?php do_action( 'envira_gallery_api_after_load', $data ); ?>
997
  <?php
998
  if ( $this->get_config( 'mobile_touchwipe', $data ) ) {
999
  ?>
1000
+ $('.envirabox-wrap, .envirabox-wrap a.envirabox-nav').swipe( {
1001
+ excludedElements:"label, button, input, select, textarea, .noSwipe",
1002
  swipe: function(event, direction, distance, duration, fingerCount, fingerData) {
1003
  if (direction === 'left') {
1004
  $.envirabox.next(direction);
1066
  onPlayEnd: function(){
1067
  <?php do_action( 'envira_gallery_api_on_play_end', $data ); ?>
1068
  }
1069
+ };
 
1070
  <?php
1071
+
1072
+ if ( ! $lightbox_images ) {
1073
+ // No lightbox images specified, so use images from DOM
1074
+ ?>
1075
+ envira_galleries['<?php echo $data['id']; ?>'] = $('.envira-gallery-<?php echo $data['id']; ?>').envirabox( envira_gallery_options );
1076
+ <?php
1077
+
1078
+ } else {
1079
+ // Use images from $lightbox_images
1080
+ add_filter( 'envira_minify_strip_double_forward_slashes', '__return_false' );
1081
  ?>
1082
+ var envira_gallery_images_<?php echo $data['id']; ?> = [];
1083
+ <?php
1084
+ // Build a JS array of all images
1085
+ $count = 0;
1086
+ foreach ( $lightbox_images as $image_id => $image ) {
1087
+ // If no image ID exists, skip
1088
+ if ( empty( $image_id ) ) {
1089
+ continue;
1090
+ }
1091
+ ?>
1092
+ envira_gallery_images_<?php echo $data['id']; ?>.push({
1093
+ href: '<?php echo $image['src']; ?>',
1094
+ gallery_id: <?php echo $data['id']; ?>,
1095
+ id: <?php echo $image_id; ?>,
1096
+ alt: '<?php echo addslashes( str_replace( "\n", '<br />', $image['alt'] ) ); ?>',
1097
+ caption: '<?php echo addslashes( str_replace( "\n", '<br />', $image['caption'] ) ); ?>',
1098
+ title: '<?php echo addslashes( str_replace( "\n", '<br />', $image['title'] ) ); ?>',
1099
+ index: <?php echo $count; ?>,
1100
+ thumbnail: '<?php echo ( isset( $image['thumb'] ) ? $image['thumb'] : '' ); ?>'
1101
+ <?php do_action( 'envira_gallery_api_lightbox_image_attributes', $image, $image_id, $lightbox_images, $data ); ?>
1102
+ });
1103
+ <?php
1104
+ $count++;
1105
+ }
1106
+
1107
+ // Open envirabox when an image is clicked, telling envirabox which images are available to it.
1108
+ ?>
1109
+ envira_galleries['<?php echo $data['id']; ?>'] = $('.envira-gallery-<?php echo $data['id']; ?>').envirabox( envira_gallery_options );
1110
+ $('#envira-gallery-wrap-<?php echo $data['id']; ?>').on('click', 'a.envira-gallery-link', function(e) {
1111
+ e.preventDefault();
1112
+ $.envirabox.close();
1113
+ if ( $('#envira-gallery-wrap-<?php echo $data['id']; ?> div.envira-pagination').length > 0 ) { /* this exists, perhaps pagination doesn't display nav because it's only one page? */
1114
+ var envirabox_page = ( $('#envira-gallery-wrap-<?php echo $data['id']; ?> div.envira-pagination').data('page') - 1 );
1115
+ } else {
1116
+ var envirabox_page = 0;
1117
+ }
1118
+
1119
+ if ( $('#envira-gallery-wrap-<?php echo $data['id']; ?> div.envira-pagination').length > 0 ) { /* this exists, perhaps pagination doesn't display nav because it's only one page? */
1120
+ var envirabox_per_page = $('#envira-gallery-wrap-<?php echo $data['id']; ?> div.envira-pagination').data('per-page');
1121
+ } else {
1122
+ var envirabox_per_page = $('.envira-gallery-image').length;
1123
+ }
1124
+
1125
+ var envirabox_index = ( Number($('img', $(this)).data('envira-index')) - 1 );
1126
+ envira_gallery_options.index = ((envirabox_page * envirabox_per_page) + envirabox_index);
1127
+ envira_galleries['<?php echo $data['id']; ?>'] = $.envirabox( envira_gallery_images_<?php echo $data['id']; ?>, envira_gallery_options );
1128
  });
1129
  <?php
1130
  }
1144
  <?php
1145
  // Minify before outputting to improve page load time.
1146
  echo $this->minify( ob_get_clean() );
1147
+ //echo ob_get_clean();
1148
  ?>
1149
  </script>
1150
  <?php
1534
  public function get_lightbox_template( $data ) {
1535
 
1536
  // Build out the lightbox template
1537
+ $template = '<div class="envirabox-wrap" tabIndex="-1"><div class="envirabox-skin envirabox-theme-' . $this->get_config( 'lightbox_theme', $data ) . '"><div class="envirabox-outer"><div class="envirabox-inner">';
1538
+
1539
+ // Top Left box
1540
+ $template .= '<div class="envirabox-position-overlay envira-gallery-top-left">';
1541
+ $template = apply_filters( 'envirabox_output_dynamic_position', $template, $data, 'top-left' );
1542
+ $template .= '</div>';
1543
+
1544
+ // Top Right box
1545
+ $template .= '<div class="envirabox-position-overlay envira-gallery-top-right">';
1546
+ $template = apply_filters( 'envirabox_output_dynamic_position', $template, $data, 'top-right' );
1547
+ $template .= '</div>';
1548
+
1549
+ // Bottom Left box
1550
+ $template .= '<div class="envirabox-position-overlay envira-gallery-bottom-left">';
1551
+ $template = apply_filters( 'envirabox_output_dynamic_position', $template, $data, 'bottom-left' );
1552
+ $template .= '</div>';
1553
+
1554
+ // Bottom Right box
1555
+ $template .= '<div class="envirabox-position-overlay envira-gallery-bottom-right">';
1556
+ $template = apply_filters( 'envirabox_output_dynamic_position', $template, $data, 'bottom-right' );
1557
+ $template .= '</div>';
1558
+
1559
+ $template .= '</div></div></div></div>';
1560
 
1561
  // Return the template, filters applied
1562
+ return apply_filters( 'envira_gallery_lightbox_template', str_replace( "\n", '', $template ), $data );
1563
 
1564
  }
1565
 
1579
  // If we are on a mobile device, some config keys have mobile equivalents, which we need to check instead
1580
  if ( wp_is_mobile() ) {
1581
  if ( class_exists( 'Envira_Gallery' ) ) {
1582
+ $mobile_keys = array(
1583
+ 'columns' => 'mobile_columns',
1584
+ 'lightbox_enabled' => 'mobile_lightbox',
1585
+ 'arrows' => 'mobile_arrows',
1586
+ 'toolbar' => 'mobile_toolbar',
1587
+ 'thumbnails' => 'mobile_thumbnails',
1588
+ );
1589
+ $mobile_keys = apply_filters( 'envira_gallery_get_config_mobile_keys', $mobile_keys );
1590
 
1591
  // When on mobile, use used to blindly look at the mobile_social option to determine social sharing button output
1592
  // However, what we need to do is look to see if the settings are active on the addon first
1600
  }
1601
  }
1602
 
1603
+ if ( array_key_exists( $key, $mobile_keys ) ) {
1604
+ // Use the mobile array key to get the config value
1605
+ $key = $mobile_keys[ $key ];
1606
+ }
1607
+ }
1608
 
1609
  }
1610
 
languages/envira-gallery-es_ES.mo CHANGED
Binary file
languages/envira-gallery-es_ES.po CHANGED
@@ -4,17 +4,28 @@ msgid ""
4
  msgstr ""
5
  "Project-Id-Version: Envira Gallery 1.3.8.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/envira-gallery\n"
7
- "POT-Creation-Date: 2016-04-30 17:50+0200\n"
8
- "PO-Revision-Date: 2016-04-30 18:15+0200\n"
9
  "Last-Translator: José Luis Pérez-Lozana <joseluis.perez.lozana@gmail.com>\n"
10
  "Language-Team: \n"
11
  "Language: es_ES\n"
12
  "MIME-Version: 1.0\n"
13
  "Content-Type: text/plain; charset=UTF-8\n"
14
  "Content-Transfer-Encoding: 8bit\n"
15
- "X-Generator: Poedit 1.8.7\n"
16
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
17
 
 
 
 
 
 
 
 
 
 
 
 
18
  #: envira-gallery.php:182
19
  msgid ""
20
  "Please <a href=\"plugins.php\">deactivate</a> the Envira Lite Plugin. Your "
@@ -45,125 +56,122 @@ msgstr ""
45
  "correctamente. Se ha desactivado el plugin. <a href=\"%s\">Pulse aquí para "
46
  "volver al escritorio</a>."
47
 
48
- #: includes/admin/addons.php:83 includes/admin/addons.php:199
49
  msgid "Envira Gallery Addons"
50
  msgstr "Complementos Envira Gallery"
51
 
52
- #: includes/admin/addons.php:84 includes/admin/addons.php:430
53
  msgid "Addons"
54
  msgstr "Complementos"
55
 
56
- #: includes/admin/addons.php:165 includes/admin/addons.php:490
57
- #: includes/admin/settings.php:410
58
  msgid "Status: Active"
59
  msgstr "Status: Activo"
60
 
61
- #: includes/admin/addons.php:166 includes/admin/addons.php:515
62
- #: includes/admin/settings.php:411
63
  msgid "Activate"
64
  msgstr "Activar"
65
 
66
- #: includes/admin/addons.php:168 includes/admin/settings.php:413
67
  msgid "Activating..."
68
  msgstr "Activando..."
69
 
70
- #: includes/admin/addons.php:170 includes/admin/addons.php:492
71
- #: includes/admin/settings.php:415
72
  msgid "Deactivate"
73
  msgstr "Desactivar"
74
 
75
- #: includes/admin/addons.php:172 includes/admin/settings.php:417
76
  msgid "Deactivating..."
77
  msgstr "Desactivando..."
78
 
79
- #: includes/admin/addons.php:173 includes/admin/addons.php:513
80
- #: includes/admin/settings.php:418
81
  msgid "Status: Inactive"
82
  msgstr "Status: Inactivo"
83
 
84
- #: includes/admin/addons.php:174 includes/admin/addons.php:504
85
- #: includes/admin/settings.php:419
86
  msgid "Install"
87
  msgstr "Instalar"
88
 
89
- #: includes/admin/addons.php:176 includes/admin/settings.php:421
90
  msgid "Installing..."
91
  msgstr "Instalando..."
92
 
93
- #: includes/admin/addons.php:177 includes/admin/settings.php:422
94
  msgid "Proceed"
95
  msgstr "Proceder"
96
 
97
- #: includes/admin/addons.php:236
 
 
 
 
 
 
 
 
 
 
 
 
98
  msgid ""
99
- "In order to get access to Addons, you need to verify your license key for "
100
- "Envira Gallery."
101
  msgstr ""
102
- "Para tener acceso a Complementos, es necesario verificar su clave de "
103
- "licencia de Envira Gallery."
104
 
105
  #: includes/admin/addons.php:241
106
  msgid ""
107
- "<strong>Missing addons that you think you should be able to see?</strong> "
108
- "Try clicking the button below to refresh the addon data."
109
  msgstr ""
110
- "<strong>¿Faltan complementos que piensa que debería poder ver?</strong> "
111
- "Intente hacer clic en el botón de abajo para actualizar la información sobre "
112
- "los complementos."
113
 
114
- #: includes/admin/addons.php:243 includes/admin/addons.php:306
115
  msgid "Refresh Addons"
116
  msgstr "Actualizar complementos"
117
 
118
- #: includes/admin/addons.php:286
 
 
 
 
119
  msgid "Unlock More Addons"
120
  msgstr "Desbloquear más complementos"
121
 
122
- #: includes/admin/addons.php:287
123
  msgid ""
124
- "<strong>Want even more addons?</strong> <a href=\"#\">Upgrade your Envira "
125
  "Gallery account</a> and unlock the following addons."
126
  msgstr ""
127
  "<strong>¿Aún quiere-más complementos?</strong> <a href=\"#\">Actualice su "
128
  "cuenta Envira Gallery</a> y desbloquee los siguientes complementos."
129
 
130
- #: includes/admin/addons.php:304
131
- msgid ""
132
- "There was an issue retrieving the addons for this site. Please click on the "
133
- "button below the refresh the addons data."
134
- msgstr ""
135
- "Hubo un problema al recuperar los complementos para este sitio. Por favor, "
136
- "haga clic en el botón de abajo para actualizar los datos de complementos."
137
-
138
- #: includes/admin/addons.php:312
139
- msgid ""
140
- "In order to get access to Addons, you need to resolve your license key "
141
- "errors."
142
- msgstr ""
143
- "Para tener acceso a Complementos, necesita corregir los errores de la clave "
144
- "de licencia."
145
-
146
- #: includes/admin/addons.php:479
147
  msgid "Upgrade Now"
148
  msgstr "Actualice ahora"
149
 
150
- #: includes/admin/addons.php:502
151
- msgid "Status: Not Installed"
152
- msgstr "Status: No instalado"
153
 
154
- #: includes/admin/addons.php:608
155
- msgid "Search Results"
156
- msgstr "Resultados de búsqueda"
157
 
158
- #: includes/admin/addons.php:610
159
- msgid "No add-ons were found with those search terms."
160
- msgstr "No se han encontrado complementos con estos términos de búsqueda."
161
 
162
- #: includes/admin/ajax.php:884 includes/admin/ajax.php:887
163
  msgid "The From Gallery ID has not been specified."
164
  msgstr "No se ha especificado el ID de la galería."
165
 
166
- #: includes/admin/ajax.php:890
167
  msgid "No images were selected to be moved between Galleries."
168
  msgstr "No se han seleccionado imágenes para moverlas entre las galerías."
169
 
@@ -178,8 +186,8 @@ msgstr ""
178
 
179
  #: includes/admin/editor.php:86 includes/admin/editor.php:87
180
  #: includes/admin/editor.php:93 includes/admin/editor.php:94
181
- #: includes/admin/metaboxes.php:262 includes/admin/metaboxes.php:263
182
- #: includes/admin/table.php:140 includes/admin/table.php:141
183
  msgid "Insert"
184
  msgstr "Insertar"
185
 
@@ -243,28 +251,28 @@ msgstr ""
243
  "Galería Envira importada. Por favor, compruebe que todas las imágenes y los "
244
  "datos han sido importados correctamente."
245
 
246
- #: includes/admin/license.php:128 includes/admin/license.php:221
247
- #: includes/admin/license.php:310
248
  msgid ""
249
  "There was an error connecting to the remote key API. Please try again later."
250
  msgstr ""
251
  "Hubo un error al conectarse a la llave API remota. Por favor, inténtelo de "
252
  "nuevo más tarde."
253
 
254
- #: includes/admin/license.php:145
255
  msgid "Congratulations! This site is now receiving automatic updates."
256
  msgstr "¡Felicidades! Este sitio está recibiendo actualizaciones automáticas."
257
 
258
- #: includes/admin/license.php:263
259
  msgid "Congratulations! Your key has been refreshed successfully."
260
  msgstr "¡Felicidades! Su clave ha sido actualizada correctamente."
261
 
262
- #: includes/admin/license.php:321
263
  msgid ""
264
  "Congratulations! You have deactivated the key from this site successfully."
265
  msgstr "¡Felicidades! Ha desactivado la clave de este sitio correctamente."
266
 
267
- #: includes/admin/license.php:415
268
  msgid ""
269
  "No valid license key has been entered, so automatic updates for Envira "
270
  "Gallery have been turned off. <a href=\"%s\">Please click here to enter your "
@@ -275,7 +283,7 @@ msgstr ""
275
  "\"%s\"> Haga clic aquí para introducir su clave de licencia y comenzar a "
276
  "recibir actualizaciones automáticas.</a>"
277
 
278
- #: includes/admin/license.php:424
279
  msgid ""
280
  "Your license key for Envira Gallery has expired. <a href=\"%s\" target="
281
  "\"_blank\">Please click here to renew your license key and continue "
@@ -285,7 +293,7 @@ msgstr ""
285
  "\"_blank\">Haga clic aquí para renovar su licencia y seguir recibiendo "
286
  "actualizaciones automáticas.</a>"
287
 
288
- #: includes/admin/license.php:433
289
  msgid ""
290
  "Your license key for Envira Gallery has been disabled. Please use a "
291
  "different key to continue receiving automatic updates."
@@ -293,7 +301,7 @@ msgstr ""
293
  "Se ha desactivado su clave de licencia para Envira Gallery. Utilice una "
294
  "clave diferente para seguir recibiendo las actualizaciones automáticas."
295
 
296
- #: includes/admin/license.php:442
297
  msgid ""
298
  "Your license key for Envira Gallery is invalid. The key no longer exists or "
299
  "the user associated with the key has been deleted. Please use a different "
@@ -304,11 +312,11 @@ msgstr ""
304
  "diferente para seguir recibiendo las actualizaciones automáticas."
305
 
306
  #: includes/admin/media-view.php:101 includes/admin/media-view.php:102
307
- #: includes/admin/media-view.php:475 includes/admin/media-view.php:476
308
  msgid "Search"
309
  msgstr "buscar"
310
 
311
- #: includes/admin/media-view.php:154 includes/admin/media-view.php:452
312
  msgid "Helpful Tips"
313
  msgstr "Consejos útiles"
314
 
@@ -347,7 +355,7 @@ msgstr "Opciones de inserción"
347
  msgid "Display Title"
348
  msgstr "Título que se mostrará"
349
 
350
- #: includes/admin/media-view.php:171 includes/global/common.php:714
351
  msgid "No"
352
  msgstr "No"
353
 
@@ -371,13 +379,13 @@ msgstr "Editar elemento multimedia siguiente"
371
  msgid "Edit Metadata"
372
  msgstr "Editar Metadatos"
373
 
374
- #: includes/admin/media-view.php:240 includes/admin/media-view.php:345
375
- #: includes/admin/table.php:165 includes/global/common.php:171
376
  #: includes/global/widget.php:153
377
  msgid "Title"
378
  msgstr "Título"
379
 
380
- #: includes/admin/media-view.php:243 includes/admin/media-view.php:348
381
  msgid ""
382
  "Image titles can take any type of HTML. You can adjust the position of the "
383
  "titles in the main Lightbox settings."
@@ -385,12 +393,12 @@ msgstr ""
385
  "Los títulos de imagen pueden tener cualquier tipo de HTML. Se puede ajustar "
386
  "la posición de los títulos en los ajustes generales de lightbox."
387
 
388
- #: includes/admin/media-view.php:249 includes/admin/media-view.php:354
389
  #: includes/global/common.php:175
390
  msgid "Caption"
391
  msgstr "Pie"
392
 
393
- #: includes/admin/media-view.php:263 includes/admin/media-view.php:368
394
  msgid ""
395
  "Captions can take any type of HTML, and are displayed when an image is "
396
  "clicked."
@@ -398,28 +406,28 @@ msgstr ""
398
  "Los pies de foto pueden usar cualquier tipo de HTML, y se muestra cuando se "
399
  "hace clic en una imagen."
400
 
401
- #: includes/admin/media-view.php:269 includes/admin/media-view.php:374
402
  msgid "Alt Text"
403
  msgstr "Texto alternativo"
404
 
405
- #: includes/admin/media-view.php:272 includes/admin/media-view.php:377
406
  msgid "Very important for SEO, the Alt Text describes the image."
407
  msgstr "Muy importante para SEO, el texto alternativo describe la imagen."
408
 
409
- #: includes/admin/media-view.php:278 includes/admin/media-view.php:383
410
  #: includes/global/common.php:183
411
  msgid "URL"
412
  msgstr "URL"
413
 
414
- #: includes/admin/media-view.php:282 includes/admin/media-view.php:387
415
  msgid "Media File"
416
  msgstr "Archivo multimedia"
417
 
418
- #: includes/admin/media-view.php:283 includes/admin/media-view.php:388
419
  msgid "Attachment Page"
420
  msgstr "Página de anexo"
421
 
422
- #: includes/admin/media-view.php:287 includes/admin/media-view.php:392
423
  msgid ""
424
  "Enter a hyperlink if you wish to link this image to somewhere other than its "
425
  "full size image."
@@ -427,33 +435,55 @@ msgstr ""
427
  "Introduzca un hipervínculo si desea enlazar esta imagen a un sitio diferente "
428
  "de su imagen a tamaño completo."
429
 
430
- #: includes/admin/media-view.php:293 includes/admin/media-view.php:398
431
  msgid "Open URL in New Window?"
432
  msgstr "¿Abrir la URL en una ventana nueva?"
433
 
434
- #: includes/admin/media-view.php:296 includes/admin/media-view.php:401
435
  msgid "Opens your image links in a new browser window / tab."
436
  msgstr ""
437
  "Abre sus enlaces de imagen en una nueva ventana / pestaña del navegador."
438
 
439
- #: includes/admin/media-view.php:307 includes/admin/media-view.php:308
440
- #: includes/admin/media-view.php:413
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  msgid "Save Metadata"
442
  msgstr "Guardar Metadatos"
443
 
444
- #: includes/admin/media-view.php:314 includes/admin/media-view.php:419
445
  msgid "Saved."
446
  msgstr "Guardado"
447
 
448
- #: includes/admin/media-view.php:329
449
  msgid "Bulk Edit"
450
  msgstr "Editar en bloque"
451
 
452
- #: includes/admin/media-view.php:412
453
  msgid "Save Metadata to Items"
454
  msgstr "Guardar Metadatos en los elementos"
455
 
456
- #: includes/admin/media-view.php:454
457
  msgid ""
458
  "Select the Gallery to move the selected images to by clicking on one of the "
459
  "boxes to the left."
@@ -461,7 +491,7 @@ msgstr ""
461
  "Seleccione la Galería a la que quiere mover las imágenes seleccionadas, "
462
  "haciendo clic en una de las cajas de la izquierda."
463
 
464
- #: includes/admin/media-view.php:457
465
  msgid ""
466
  "Once done, click the Move button, and the selected images will be moved to "
467
  "the chosen Gallery."
@@ -469,7 +499,7 @@ msgstr ""
469
  "Una vez hecho, haga clic en el botón Mover y las imágenes seleccionadas se "
470
  "moverán a la galería elegida."
471
 
472
- #: includes/admin/metaboxes.php:98
473
  msgid ""
474
  "The GD or Imagick libraries are not installed on your server. Envira Gallery "
475
  "requires at least one (preferably Imagick) in order to crop images and may "
@@ -482,166 +512,185 @@ msgstr ""
482
  "con su servicio de hosting y pídales que compilen GD o Imagick para su "
483
  "instalación de PHP."
484
 
485
- #: includes/admin/metaboxes.php:133
486
  msgid "Insert into Gallery"
487
  msgstr "Insertar en la galería"
488
 
489
- #: includes/admin/metaboxes.php:134 includes/admin/metaboxes.php:278
490
  msgid "Inserting..."
491
  msgstr "Insertando..."
492
 
493
- #: includes/admin/metaboxes.php:159
494
  msgid "Click Here to Insert from Other Image Sources"
495
  msgstr "Haga clic aquí para insertar desde otra fuentes de imágenes"
496
 
497
- #: includes/admin/metaboxes.php:160
498
  msgid "Select Files from Other Sources"
499
  msgstr "Seleccione los archivos de otras Fuentes"
500
 
501
- #: includes/admin/metaboxes.php:168
502
  msgid "Uploading Image"
503
  msgstr "Subiendo imagen"
504
 
505
- #: includes/admin/metaboxes.php:170
506
  msgid "of"
507
  msgstr "de"
508
 
509
- #: includes/admin/metaboxes.php:174
510
  msgid "All images uploaded."
511
  msgstr "Subidas todas las imágenes."
512
 
513
- #: includes/admin/metaboxes.php:276
514
  msgid "You must select a file to import before continuing."
515
  msgstr "Debe seleccionar un archivo para importar antes de continuar."
516
 
517
- #: includes/admin/metaboxes.php:284
518
  msgid "Move Media to Gallery"
519
  msgstr "Mover medios a la galería"
520
 
521
- #: includes/admin/metaboxes.php:285
522
  msgid "Move Media to Selected Gallery"
523
  msgstr "Mover medios a la galería seleccionada"
524
 
525
- #: includes/admin/metaboxes.php:288
526
  msgid "Are you sure you want to remove this image from the gallery?"
527
  msgstr "¿Seguro que quieres eliminar esta imagen de la galería?"
528
 
529
- #: includes/admin/metaboxes.php:289
530
  msgid "Are you sure you want to remove these images from the gallery?"
531
  msgstr "¿Seguro que desea eliminar estas imágenes de la galería?"
532
 
533
- #: includes/admin/metaboxes.php:293
534
  msgid "Saving..."
535
  msgstr "Guardando..."
536
 
537
- #: includes/admin/metaboxes.php:294
538
  msgid "Saved!"
539
  msgstr "¡Guardado!"
540
 
541
- #: includes/admin/metaboxes.php:296
542
  msgid "Select Files from Your Computer"
543
  msgstr "Seleccione los archivos de su ordenador"
544
 
545
- #. Plugin Name of the plugin/theme
546
- #: includes/admin/metaboxes.php:395 includes/admin/partials/header.php:14
547
  #: includes/global/posttype.php:52 includes/global/posttype.php:62
548
  #: includes/global/widget.php:50
549
  msgid "Envira Gallery"
550
  msgstr "Envira Gallery"
551
 
552
- #: includes/admin/metaboxes.php:399 includes/admin/settings.php:79
553
  msgid "Envira Gallery Settings"
554
  msgstr "Ajustes de Envira Gallery"
555
 
556
- #: includes/admin/metaboxes.php:404
557
  msgid "Envira Gallery Preview"
558
  msgstr "Vista previa de Envira Gallery"
559
 
560
- #: includes/admin/metaboxes.php:408
561
  msgid "Envira Gallery Code"
562
  msgstr "Código de Envira Gallery"
563
 
564
- #: includes/admin/metaboxes.php:579 includes/global/common.php:253
565
  msgid "Default"
566
  msgstr "Predeterminada"
567
 
568
- #: includes/admin/metaboxes.php:596
569
  msgid "Images"
570
  msgstr "Imágenes"
571
 
572
- #: includes/admin/metaboxes.php:597
573
  msgid "Config"
574
  msgstr "Configuración"
575
 
576
- #: includes/admin/metaboxes.php:598
577
  msgid "Lightbox"
578
  msgstr "Lightbox"
579
 
580
- #: includes/admin/metaboxes.php:599 includes/admin/metaboxes.php:1542
581
  msgid "Mobile"
582
  msgstr "Móvil"
583
 
584
- #: includes/admin/metaboxes.php:604
585
  msgid "Misc"
586
  msgstr "Varios"
587
 
588
- #: includes/admin/metaboxes.php:698
589
  msgid "Currently in your Gallery"
590
  msgstr "Actualmente en la galería"
591
 
592
- #: includes/admin/metaboxes.php:700 includes/admin/metaboxes.php:772
593
- #: includes/admin/metaboxes.php:1025 includes/admin/metaboxes.php:1314
594
- #: includes/admin/metaboxes.php:1450
595
  msgid "Need some help?"
596
  msgstr "¿Necesita ayuda?"
597
 
598
- #: includes/admin/metaboxes.php:702 includes/admin/metaboxes.php:774
599
- #: includes/admin/metaboxes.php:1027 includes/admin/metaboxes.php:1316
600
- #: includes/admin/metaboxes.php:1452
601
  msgid "Read the Documentation"
602
  msgstr "Lea la documentación"
603
 
604
- #: includes/admin/metaboxes.php:706 includes/admin/metaboxes.php:778
605
- #: includes/admin/metaboxes.php:1031 includes/admin/metaboxes.php:1320
606
- #: includes/admin/metaboxes.php:1456
607
  msgid "Watch a Video"
608
  msgstr "Mire el video"
609
 
610
- #: includes/admin/metaboxes.php:715
611
  msgid "Select All (<span class=\"count\">%d</span>)"
612
  msgstr "Seleccione todo (<span class=\"count\">%d</span>"
613
 
614
- #: includes/admin/metaboxes.php:720
615
  msgid "Grid View"
616
  msgstr "Vista de cuadrícula"
617
 
618
- #: includes/admin/metaboxes.php:723
619
  msgid "List View"
620
  msgstr "Vista de lista"
621
 
622
- #: includes/admin/metaboxes.php:729 includes/admin/metaboxes.php:749
623
  msgid "Edit Selected Images"
624
  msgstr "Editar imágenes seleccionadas"
625
 
626
- #: includes/admin/metaboxes.php:730 includes/admin/metaboxes.php:750
627
  msgid "Move Selected Images to another Gallery"
628
  msgstr "Mover las imágenes seleccionadas a otra galería"
629
 
630
- #: includes/admin/metaboxes.php:731 includes/admin/metaboxes.php:751
631
  msgid "Delete Selected Images from Gallery"
632
  msgstr "Borrar las imágenes seleccionadas de la galería"
633
 
634
- #: includes/admin/metaboxes.php:770
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
635
  msgid ""
636
  "The settings below adjust the basic configuration options for the gallery."
637
  msgstr ""
638
  "Los siguientes ajustes configuran las opciones básicas para la galería."
639
 
640
- #: includes/admin/metaboxes.php:786 includes/admin/metaboxes.php:1328
641
  msgid "Number of Gallery Columns"
642
  msgstr "Número de columnas de la galería"
643
 
644
- #: includes/admin/metaboxes.php:794
645
  msgid ""
646
  "Determines the number of columns in the gallery. Automatic will attempt to "
647
  "fill each row as much as possible before moving on to the next row."
@@ -649,62 +698,62 @@ msgstr ""
649
  "Determina el número de columnas en la galería. Automático tratará de "
650
  "rellenar la fila tanto como sea posible antes de pasar a la siguiente. "
651
 
652
- #: includes/admin/metaboxes.php:799 includes/admin/table.php:303
653
- #: includes/admin/table.php:380
654
  msgid "Gallery Theme"
655
  msgstr "Tema de la galería"
656
 
657
- #: includes/admin/metaboxes.php:807
658
  msgid "Sets the theme for the gallery display."
659
  msgstr "Establece el tema para la presentación de la galería."
660
 
661
- #: includes/admin/metaboxes.php:814
662
  msgid "Display Gallery Description?"
663
  msgstr "¿Mostrar la descripción de la galería?"
664
 
665
- #: includes/admin/metaboxes.php:826
666
  msgid "Choose to display a description above or below this gallery's images."
667
  msgstr ""
668
  "Elija si desea mostrar una descripción encima o debajo de las imágenes de "
669
  "esta galería."
670
 
671
- #: includes/admin/metaboxes.php:833
672
  msgid "Gallery Description"
673
  msgstr "Descripción de la galería"
674
 
675
- #: includes/admin/metaboxes.php:848
676
  msgid "The description to display for this gallery."
677
  msgstr "Descripción que se mostrará para esta galería"
678
 
679
- #: includes/admin/metaboxes.php:854 includes/admin/table.php:312
680
- #: includes/admin/table.php:391
681
  msgid "Column Gutter Width"
682
  msgstr "Ancho de separación de columnas"
683
 
684
- #: includes/admin/metaboxes.php:857 includes/admin/metaboxes.php:866
685
- #: includes/admin/metaboxes.php:950 includes/admin/metaboxes.php:1264
686
- #: includes/admin/metaboxes.php:1273 includes/admin/metaboxes.php:1355
687
  msgid "px"
688
  msgstr "px"
689
 
690
- #: includes/admin/metaboxes.php:858
691
  msgid "Sets the space between the columns (defaults to 10)."
692
  msgstr "Establece el espacio entre las columnas (por defecto 10)."
693
 
694
- #: includes/admin/metaboxes.php:863 includes/admin/table.php:317
695
- #: includes/admin/table.php:396
696
  msgid "Margin Below Each Image"
697
  msgstr "Margen debajo de cada imagen"
698
 
699
- #: includes/admin/metaboxes.php:867
700
  msgid "Sets the space below each item in the gallery."
701
  msgstr "Establece el espacio debajo de cada elemento en la galería."
702
 
703
- #: includes/admin/metaboxes.php:874
704
  msgid "Sorting"
705
  msgstr "Clasificar por:"
706
 
707
- #: includes/admin/metaboxes.php:886
708
  msgid ""
709
  "Choose to sort the images in a different order than displayed on the Images "
710
  "tab."
@@ -712,15 +761,15 @@ msgstr ""
712
  "Elija ordenar las imágenes en un orden diferente al que aparece en la "
713
  "pestaña Imágenes."
714
 
715
- #: includes/admin/metaboxes.php:891
716
  msgid "Direction"
717
  msgstr "Dirección"
718
 
719
- #: includes/admin/metaboxes.php:909 includes/admin/metaboxes.php:1069
720
  msgid "Image Size"
721
  msgstr "Tamaño de imagen"
722
 
723
- #: includes/admin/metaboxes.php:921
724
  msgid ""
725
  "Define the maximum image size for the Gallery view. Default will use the "
726
  "below Image Dimensions; Random will allow you to choose one or more "
@@ -731,11 +780,11 @@ msgstr ""
731
  "elegir entre uno o más tamaños de imagen de WordPress, que se utilizará para "
732
  "la galería."
733
 
734
- #: includes/admin/metaboxes.php:926
735
  msgid "Random Image Sizes"
736
  msgstr "Tamaños de imagen aleatorios"
737
 
738
- #: includes/admin/metaboxes.php:942
739
  msgid ""
740
  "Define the WordPress registered image sizes to include when randomly "
741
  "assigning an image size to each image in your Gallery."
@@ -743,12 +792,12 @@ msgstr ""
743
  "Definir los tamaños de imagen de WordPress para incluirlos cuando se asigna "
744
  "un tamaño de imagen aleatorio a cada imagen en la galería."
745
 
746
- #: includes/admin/metaboxes.php:947 includes/admin/table.php:323
747
- #: includes/admin/table.php:401
748
  msgid "Image Dimensions"
749
  msgstr "Dimensiones de la imagen"
750
 
751
- #: includes/admin/metaboxes.php:951
752
  msgid ""
753
  "You should adjust these dimensions based on the number of columns in your "
754
  "gallery. This does not affect the full size lightbox images."
@@ -756,11 +805,11 @@ msgstr ""
756
  "Debe ajustar estas dimensiones en función del número de columnas en su "
757
  "galería. Esto no afecta al tamaño de las imágenes de la galería lightbox."
758
 
759
- #: includes/admin/metaboxes.php:956
760
  msgid "Crop Images?"
761
  msgstr "¿Recortar imágenes?"
762
 
763
- #: includes/admin/metaboxes.php:960
764
  msgid ""
765
  "If enabled, forces images to exactly match the sizes defined above for Image "
766
  "Dimensions and Mobile Dimensions."
@@ -769,17 +818,17 @@ msgstr ""
769
  "definidos previamente para las dimensiones de imagen y las dimensiones para "
770
  "móviles."
771
 
772
- #: includes/admin/metaboxes.php:961
773
  msgid "If disabled, images will be resized to maintain their aspect ratio."
774
  msgstr ""
775
  "Si se desactiva, las imágenes se redimensionarán manteniendo la relación de "
776
  "aspecto."
777
 
778
- #: includes/admin/metaboxes.php:967
779
  msgid "Set Dimensions on Images?"
780
  msgstr "¿Establecer dimensiones de las imágenes?"
781
 
782
- #: includes/admin/metaboxes.php:971
783
  msgid ""
784
  "Enables or disables the width and height attributes on the img element. Only "
785
  "needs to be enabled if you need to meet Google Pagespeeds requirements."
@@ -788,11 +837,11 @@ msgstr ""
788
  "Sólo necesita activarlo si es necesario cumplir con los requisitos de Google "
789
  "Pagespeeds."
790
 
791
- #: includes/admin/metaboxes.php:976
792
  msgid "Enable Isotope?"
793
  msgstr "¿Activar isótopo?"
794
 
795
- #: includes/admin/metaboxes.php:980
796
  msgid ""
797
  "Enables or disables isotope/masonry layout support for the main gallery "
798
  "images."
@@ -800,20 +849,20 @@ msgstr ""
800
  "Activa o desactiva la compatibilidad con el diseño de isótopos / masonry "
801
  "para las imágenes de la galería."
802
 
803
- #: includes/admin/metaboxes.php:986
804
  msgid "Enable CSS Animations?"
805
  msgstr "¿Activar animaciones CSS?"
806
 
807
- #: includes/admin/metaboxes.php:990
808
  msgid "Enables CSS animations when loading the main gallery images."
809
  msgstr ""
810
  "Activa las animaciones CSS cuando se cargan las imágenes de la galería."
811
 
812
- #: includes/admin/metaboxes.php:996
813
  msgid "Image Opacity"
814
  msgstr "Opacidad de imagen"
815
 
816
- #: includes/admin/metaboxes.php:1000
817
  msgid ""
818
  "The opacity to display images at when loading the main gallery images using "
819
  "CSS animations (between 1 and 100%)."
@@ -821,27 +870,44 @@ msgstr ""
821
  "Opacidad para visualizar las imágenes cuando se cargan utilizando "
822
  "animaciones CSS (entre 1 y 100%)."
823
 
824
- #: includes/admin/metaboxes.php:1023
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
825
  msgid "The settings below adjust the lightbox output."
826
  msgstr "Los ajuste siguientes ajustan la vista en lightbox."
827
 
828
- #: includes/admin/metaboxes.php:1040 includes/admin/metaboxes.php:1375
829
  msgid "Enable Lightbox?"
830
  msgstr "¿Activar lightbox?"
831
 
832
- #: includes/admin/metaboxes.php:1044
833
  msgid "Enables or disables the gallery lightbox."
834
  msgstr "Activa o desactiva la galería lightbox."
835
 
836
- #: includes/admin/metaboxes.php:1055
837
  msgid "Gallery Lightbox Theme"
838
  msgstr "Tema de la galería lightbox"
839
 
840
- #: includes/admin/metaboxes.php:1063
841
  msgid "Sets the theme for the gallery lightbox display."
842
  msgstr "Establece el tema para la visualización de la galería lightbox."
843
 
844
- #: includes/admin/metaboxes.php:1077
845
  msgid ""
846
  "Define the maximum image size for the Lightbox view. Default will display "
847
  "the original, full size image."
@@ -849,113 +915,113 @@ msgstr ""
849
  "Define el tamaño máximo de imagen para la visualización de lightbox. De "
850
  "manera predeterminada mostrará la imagen a tamaño original."
851
 
852
- #: includes/admin/metaboxes.php:1083
853
  msgid "Caption Position"
854
  msgstr "Posición del pie"
855
 
856
- #: includes/admin/metaboxes.php:1091
857
  msgid "Sets the display of the lightbox image's caption."
858
  msgstr "Establece la forma de visualizar el pie de la imagen en lightbox. "
859
 
860
- #: includes/admin/metaboxes.php:1096 includes/admin/metaboxes.php:1402
861
  msgid "Enable Gallery Arrows?"
862
  msgstr "¿Activar las flechas en la galería?"
863
 
864
- #: includes/admin/metaboxes.php:1100
865
  msgid "Enables or disables the gallery lightbox navigation arrows."
866
  msgstr "Activa o desactiva las flechas de navegación en la galería lightbox."
867
 
868
- #: includes/admin/metaboxes.php:1105
869
  msgid "Gallery Arrow Position"
870
  msgstr "Posición de la flecha en la galería."
871
 
872
- #: includes/admin/metaboxes.php:1113
873
  msgid "Sets the position of the gallery lightbox navigation arrows."
874
  msgstr ""
875
  "Establece la posición de las flechas de navegación de la galería lightbox."
876
 
877
- #: includes/admin/metaboxes.php:1118
878
  msgid "Enable Keyboard Navigation?"
879
  msgstr "¿Activar navegación por teclado?"
880
 
881
- #: includes/admin/metaboxes.php:1122
882
  msgid "Enables or disables keyboard navigation in the gallery lightbox."
883
  msgstr "Activa o desactiva la navegación por teclado en la galería lightbox."
884
 
885
- #: includes/admin/metaboxes.php:1127
886
  msgid "Enable Mousewheel Navigation?"
887
  msgstr "¿Activar navegación con la rueda del ratón?"
888
 
889
- #: includes/admin/metaboxes.php:1131
890
  msgid "Enables or disables mousewheel navigation in the gallery."
891
  msgstr "Activa o desactiva la navegación con la rueda del ratón en la galería."
892
 
893
- #: includes/admin/metaboxes.php:1136 includes/admin/metaboxes.php:1411
894
  msgid "Enable Gallery Toolbar?"
895
  msgstr "¿Activar la barra de tareas en la galería?"
896
 
897
- #: includes/admin/metaboxes.php:1140
898
  msgid "Enables or disables the gallery lightbox toolbar."
899
  msgstr "Activa o desactiva la barra de tareas en la galería lightbox."
900
 
901
- #: includes/admin/metaboxes.php:1145
902
  msgid "Display Gallery Title in Toolbar?"
903
  msgstr "¿Mostrar el título de la galería en la barra de tareas?"
904
 
905
- #: includes/admin/metaboxes.php:1149
906
  msgid "Display the gallery title in the lightbox toolbar."
907
  msgstr "Muestra el título de la galería en la barra de tareas de lightbox."
908
 
909
- #: includes/admin/metaboxes.php:1154
910
  msgid "Gallery Toolbar Position"
911
  msgstr "Posición de la barra de tareas en la galería"
912
 
913
- #: includes/admin/metaboxes.php:1162
914
  msgid "Sets the position of the lightbox toolbar."
915
  msgstr "Establece la posición de la barra de tareas lightbox."
916
 
917
- #: includes/admin/metaboxes.php:1167
918
  msgid "Keep Aspect Ratio?"
919
  msgstr "¿Mantener relación de aspecto?"
920
 
921
- #: includes/admin/metaboxes.php:1171
922
  msgid ""
923
  "If enabled, images will always resize based on the original aspect ratio."
924
  msgstr ""
925
  "Si se activa, las imágenes se redimensionarán siempre manteniendo la "
926
  "relación de aspecto."
927
 
928
- #: includes/admin/metaboxes.php:1176
929
  msgid "Loop Gallery Navigation?"
930
  msgstr "¿Navegación en bucle en la galería?"
931
 
932
- #: includes/admin/metaboxes.php:1180
933
  msgid ""
934
  "Enables or disables infinite navigation cycling of the lightbox gallery."
935
  msgstr ""
936
  "Activa o desactiva una navegación infinita en bucle de la galería lightbox."
937
 
938
- #: includes/admin/metaboxes.php:1185
939
  msgid "Lightbox Open/Close Effect"
940
  msgstr "Abrir / cerrar efectos lightbox"
941
 
942
- #: includes/admin/metaboxes.php:1205
943
  msgid "Type of transition when opening and closing the lightbox."
944
  msgstr "Tipo de transición cuando se abre o cierra lightbox."
945
 
946
- #: includes/admin/metaboxes.php:1210
947
  msgid "Lightbox Transition Effect"
948
  msgstr "Efectos de transición lightbox"
949
 
950
- #: includes/admin/metaboxes.php:1230
951
  msgid "Type of transition between images in the lightbox view."
952
  msgstr "Tipo de transición entre imágenes en la visualización lightbox."
953
 
954
- #: includes/admin/metaboxes.php:1235
955
  msgid "HTML5 Output?"
956
  msgstr "¿Salida HTML5?"
957
 
958
- #: includes/admin/metaboxes.php:1239
959
  msgid ""
960
  "If enabled, uses data-envirabox-gallery instead of rel attributes for W3C "
961
  "HTML5 validation."
@@ -963,50 +1029,63 @@ msgstr ""
963
  "Si se activa, usa data-envirabox-gallery en lugar de atributos relativos "
964
  "para validación W3C HTML5."
965
 
966
- #: includes/admin/metaboxes.php:1247
967
  msgid ""
968
  "The settings below adjust the thumbnail views for the gallery lightbox "
969
  "display."
970
  msgstr ""
971
  "Los ajustes siguientes ajustan las miniaturas para la vista en lightbox."
972
 
973
- #: includes/admin/metaboxes.php:1252 includes/admin/metaboxes.php:1420
974
  msgid "Enable Gallery Thumbnails?"
975
  msgstr "¿Activar miniaturas en la galería?"
976
 
977
- #: includes/admin/metaboxes.php:1256
978
  msgid "Enables or disables the gallery lightbox thumbnails."
979
  msgstr "Activa o desactiva las miniaturas en la galería lightbox."
980
 
981
- #: includes/admin/metaboxes.php:1261
982
  msgid "Gallery Thumbnails Width"
983
  msgstr "Ancho de miniaturas de la galería"
984
 
985
- #: includes/admin/metaboxes.php:1265
986
  msgid "Sets the width of each lightbox thumbnail."
987
  msgstr "Establece el ancho de cada miniatura lightbox."
988
 
989
- #: includes/admin/metaboxes.php:1270
990
  msgid "Gallery Thumbnails Height"
991
  msgstr "Alto de miniaturas de la galería"
992
 
993
- #: includes/admin/metaboxes.php:1274
994
  msgid "Sets the height of each lightbox thumbnail."
995
  msgstr "Establece la altura de cada miniatura lightbox."
996
 
997
- #: includes/admin/metaboxes.php:1279
998
  msgid "Gallery Thumbnails Position"
999
  msgstr "Posición de miniaturas de lightbox"
1000
 
1001
- #: includes/admin/metaboxes.php:1287
1002
  msgid "Sets the position of the lightbox thumbnails."
1003
  msgstr "Establece la posición de las miniaturas lightbox."
1004
 
1005
- #: includes/admin/metaboxes.php:1311
1006
- msgid "Gallery Options"
1007
- msgstr "Opciones de la galería."
1008
 
1009
- #: includes/admin/metaboxes.php:1313
 
 
 
 
 
 
 
 
 
 
 
 
 
1010
  msgid ""
1011
  "The settings below adjust configuration options for the Gallery when viewed "
1012
  "on a mobile device."
@@ -1014,7 +1093,7 @@ msgstr ""
1014
  "Los siguientes ajustes configuran las opciones de la galería cuando se ven "
1015
  "en un dispositivo móvil."
1016
 
1017
- #: includes/admin/metaboxes.php:1336
1018
  msgid ""
1019
  "Determines the number of columns in the gallery on mobile devices. Automatic "
1020
  "will attempt to fill each row as much as possible before moving on to the "
@@ -1024,29 +1103,29 @@ msgstr ""
1024
  "Automático, intentará rellenar cualquier fila todo lo posible antes de pasar "
1025
  "a la siguiente fila."
1026
 
1027
- #: includes/admin/metaboxes.php:1342
1028
  msgid "Create Mobile Gallery Images?"
1029
  msgstr "¿Crear galería de imágenes para móvil?"
1030
 
1031
- #: includes/admin/metaboxes.php:1346
1032
  msgid "Enables or disables creating specific images for mobile devices."
1033
  msgstr "Activa o desactiva la creación de imágenes especificas para móvil."
1034
 
1035
- #: includes/admin/metaboxes.php:1352
1036
  msgid "Mobile Dimensions"
1037
  msgstr "Dimensiones para móvil"
1038
 
1039
- #: includes/admin/metaboxes.php:1356
1040
  msgid "These will be the sizes used for images displayed on mobile devices."
1041
  msgstr ""
1042
  "Estos serán los tamaños utilizados para las imágenes que aparecen en "
1043
  "dispositivos móviles."
1044
 
1045
- #: includes/admin/metaboxes.php:1366
1046
- msgid "Lightbox Options."
1047
- msgstr "Opciones de lightbox."
1048
 
1049
- #: includes/admin/metaboxes.php:1368
1050
  msgid ""
1051
  "The settings below adjust configuration options for the Lightbox when viewed "
1052
  "on a mobile device."
@@ -1054,15 +1133,15 @@ msgstr ""
1054
  "Los siguientes ajustes configuran las opciones de lightbox cuando se ven en "
1055
  "un dispositivo móvil."
1056
 
1057
- #: includes/admin/metaboxes.php:1379
1058
  msgid "Enables or disables the gallery lightbox on mobile devices."
1059
  msgstr "Activa o desactiva la galería lightbox en dispositivos móviles."
1060
 
1061
- #: includes/admin/metaboxes.php:1384
1062
  msgid "Enable Gallery Touchwipe?"
1063
  msgstr "¿Activar Touchwipe en la galería?"
1064
 
1065
- #: includes/admin/metaboxes.php:1388
1066
  msgid ""
1067
  "Enables or disables touchwipe support for the gallery lightbox on mobile "
1068
  "devices."
@@ -1070,11 +1149,11 @@ msgstr ""
1070
  "Activa o desactiva las funciones touchwipe para la galería lightbox en "
1071
  "dispositivos móviles."
1072
 
1073
- #: includes/admin/metaboxes.php:1393
1074
  msgid "Close Lightbox on Swipe Up?"
1075
  msgstr "Cerrar Lightbox deslizando el dedo hacia arriba?"
1076
 
1077
- #: includes/admin/metaboxes.php:1397
1078
  msgid ""
1079
  "Enables or disables closing the Lightbox when the user swipes up on mobile "
1080
  "devices."
@@ -1082,43 +1161,47 @@ msgstr ""
1082
  "Activa o desactiva el cierre de Lightbox cuando el usuario desliza el dedo "
1083
  "hacia arriba en los dispositivos móviles."
1084
 
1085
- #: includes/admin/metaboxes.php:1406
1086
  msgid ""
1087
  "Enables or disables the gallery lightbox navigation arrows on mobile devices."
1088
  msgstr ""
1089
  "Activa o desactiva las flechas de navegación de la galería lightbox en "
1090
  "dispositivos móviles."
1091
 
1092
- #: includes/admin/metaboxes.php:1415
1093
  msgid "Enables or disables the gallery lightbox toolbar on mobile devices."
1094
  msgstr ""
1095
  "Activa o desactiva la barra de herramientas de la galería lightbox en "
1096
  "dispositivos móviles."
1097
 
1098
- #: includes/admin/metaboxes.php:1424
1099
  msgid "Enables or disables the gallery lightbox thumbnails on mobile devices."
1100
  msgstr ""
1101
  "Activa o desactiva las miniaturas de la galería lightbox en dispositivos "
1102
  "móviles."
1103
 
1104
- #: includes/admin/metaboxes.php:1448
1105
- msgid "The settings below adjust miscellaneous settings for the gallery."
 
 
 
 
1106
  msgstr "Los ajustes siguientes configuran diversos ajustes para la galería."
1107
 
1108
- #: includes/admin/metaboxes.php:1464
1109
  msgid "Gallery Title"
1110
  msgstr "Título de la galería"
1111
 
1112
- #: includes/admin/metaboxes.php:1468
1113
  msgid "Internal gallery title for identification in the admin."
1114
  msgstr ""
1115
  "Título interno de la galería para su identificación en la administración"
1116
 
1117
- #: includes/admin/metaboxes.php:1473
1118
  msgid "Gallery Slug"
1119
  msgstr "Slug de la galería"
1120
 
1121
- #: includes/admin/metaboxes.php:1477
1122
  msgid ""
1123
  "<strong>Unique</strong> internal gallery slug for identification and "
1124
  "advanced gallery queries."
@@ -1126,63 +1209,74 @@ msgstr ""
1126
  "Slug interno <strong>único</strong> de la galería para la identificación y "
1127
  "consultas avanzadas."
1128
 
1129
- #: includes/admin/metaboxes.php:1482
1130
  msgid "Custom Gallery Classes"
1131
  msgstr "Clases personalizadas de la galería"
1132
 
1133
- #: includes/admin/metaboxes.php:1485
1134
  msgid "Enter custom gallery CSS classes here, one per line."
1135
  msgstr "Introduzca aquí, clases CSS personalizadas, una por línea."
1136
 
1137
- #: includes/admin/metaboxes.php:1486
1138
  msgid "Adds custom CSS classes to this gallery. Enter one class per line."
1139
  msgstr "Añade clases CSS personalizadas en la galería, una por línea."
1140
 
1141
- #: includes/admin/metaboxes.php:1491
1142
  msgid "Import/Export Gallery"
1143
  msgstr "Importar / Exportar galería"
1144
 
1145
- #: includes/admin/metaboxes.php:1504
1146
  msgid "Import Gallery"
1147
  msgstr "Importar galería"
1148
 
1149
- #: includes/admin/metaboxes.php:1511
1150
  msgid "Export Gallery"
1151
  msgstr "Exportar galería"
1152
 
1153
- #: includes/admin/metaboxes.php:1517
1154
  msgid "Enable RTL Support?"
1155
  msgstr "¿Activar funciones RTL?"
1156
 
1157
- #: includes/admin/metaboxes.php:1521
1158
  msgid "Enables or disables RTL support in Envira for right-to-left languages."
1159
  msgstr ""
1160
  "Activa o desactiva funciones RTL en Envira para idiomas que se escriben de "
1161
  "derecha a izquierda."
1162
 
1163
- #: includes/admin/metaboxes.php:1543
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1164
  msgid "Videos"
1165
  msgstr "Videos"
1166
 
1167
- #: includes/admin/metaboxes.php:1544
1168
  msgid "Social"
1169
  msgstr "Social"
1170
 
1171
- #: includes/admin/metaboxes.php:1545
1172
  msgid "Tags"
1173
  msgstr "Etiquetas"
1174
 
1175
- #: includes/admin/metaboxes.php:1546
1176
  msgid "Pagination"
1177
  msgstr "Paginación"
1178
 
1179
- #: includes/admin/metaboxes.php:1563 includes/admin/metaboxes.php:1585
1180
- #: includes/admin/metaboxes.php:1607 includes/admin/metaboxes.php:1629
1181
- #: includes/admin/metaboxes.php:1651
1182
- msgid "Want to take your galleries further?"
1183
- msgstr "¿Quiere mejorar aún más sus galerías?"
1184
-
1185
- #: includes/admin/metaboxes.php:1564
1186
  msgid ""
1187
  "By upgrading to Envira Pro, you can get access to mobile-specific settings, "
1188
  "including mobile image sizes, number of columns, mobile-specific lightbox "
@@ -1193,13 +1287,7 @@ msgstr ""
1193
  "moviles, número de columnas, opciones específicas para móviles en lighbox y "
1194
  "mucho más."
1195
 
1196
- #: includes/admin/metaboxes.php:1566 includes/admin/metaboxes.php:1588
1197
- #: includes/admin/metaboxes.php:1610 includes/admin/metaboxes.php:1632
1198
- #: includes/admin/metaboxes.php:1654
1199
- msgid "Click here to Upgrade"
1200
- msgstr "Haga clic aquí para actualizar."
1201
-
1202
- #: includes/admin/metaboxes.php:1586
1203
  msgid ""
1204
  "By upgrading to Envira Pro, you can add Videos to your Envira Galleries from "
1205
  "YouTube, Vimeo, Wistia, and your own self-hosted videos!"
@@ -1207,7 +1295,7 @@ msgstr ""
1207
  "Mediante la actualización a Envira Pro, puede añadir videos a sus galerías "
1208
  "Envira desde YouTube, Vimeo, Wistia, y vídeos alojados en su propio servidor."
1209
 
1210
- #: includes/admin/metaboxes.php:1608
1211
  msgid ""
1212
  "By upgrading to Envira Pro, you can add social sharing buttons to your "
1213
  "Gallery images and Lightbox images. With support for Facebook, Twitter, "
@@ -1218,7 +1306,7 @@ msgstr ""
1218
  "soporte para Facebook, Twitter, Google+ y Pinterest. ¿Por qué no echarle un "
1219
  "vistazo?"
1220
 
1221
- #: includes/admin/metaboxes.php:1630
1222
  msgid ""
1223
  "By upgrading to Envira Pro, you can add Tags to your Gallery images, allow "
1224
  "users to filter your Gallery by tag and so much more!"
@@ -1227,7 +1315,7 @@ msgstr ""
1227
  "imágenes de la Galería, permitir a los usuarios filtrar la galería por "
1228
  "etiquetas y mucho más."
1229
 
1230
- #: includes/admin/metaboxes.php:1652
1231
  msgid ""
1232
  "By upgrading to Envira Pro, you can split your Gallery across multiple pages "
1233
  "with pagination, load paginated images via AJAX, lazy loading and more!"
@@ -1236,11 +1324,11 @@ msgstr ""
1236
  "múltiples páginas con paginación, cargar imágenes paginadas mediante AJAX, "
1237
  "lazy loading y mucho más."
1238
 
1239
- #: includes/admin/metaboxes.php:1923
1240
  msgid "Remove Image from Gallery?"
1241
  msgstr "¿Quitar imagen de la galería?"
1242
 
1243
- #: includes/admin/metaboxes.php:1924
1244
  msgid "Modify Image"
1245
  msgstr "Modificar imagen"
1246
 
@@ -1259,7 +1347,7 @@ msgstr ""
1259
 
1260
  #: includes/admin/partials/metabox-gallery-code.php:14
1261
  #: includes/admin/partials/metabox-gallery-code.php:24
1262
- #: includes/admin/table.php:226
1263
  msgid "Copy Shortcode to Clipboard"
1264
  msgstr "Copiar el código corto al portapapeles"
1265
 
@@ -1267,7 +1355,7 @@ msgstr "Copiar el código corto al portapapeles"
1267
  #: includes/admin/partials/metabox-gallery-code.php:25
1268
  #: includes/admin/partials/metabox-gallery-code.php:36
1269
  #: includes/admin/partials/metabox-gallery-code.php:46
1270
- #: includes/admin/table.php:227
1271
  msgid "Copy to Clipboard"
1272
  msgstr "Copiar al portapapeles"
1273
 
@@ -1293,11 +1381,34 @@ msgstr "Galería Envira nativa"
1293
  msgid "External Gallery"
1294
  msgstr "galería externa"
1295
 
1296
- #: includes/admin/partials/metabox-gallery-type.php:45
1297
  msgid "Select Your Service"
1298
  msgstr "Seleccione su servicio"
1299
 
1300
- #: includes/admin/partials/metabox-gallery-type.php:70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1301
  msgid ""
1302
  "It doesn't look like you have any Addons activated which import images from "
1303
  "external sources."
@@ -1345,52 +1456,52 @@ msgstr "j \\d\\e\\ F \\d\\e\\ Y @ G:i"
1345
  msgid "Envira gallery draft updated."
1346
  msgstr "Borrador de galería Envira actualizado."
1347
 
1348
- #: includes/admin/settings.php:80 includes/admin/settings.php:660
1349
  msgid "Settings"
1350
  msgstr "Ajustes"
1351
 
1352
- #: includes/admin/settings.php:225
1353
  msgid " galleries(s) fixed successfully."
1354
  msgstr "Galería(s) reparada(s) satisfactoriamente."
1355
 
1356
- #: includes/admin/settings.php:359
1357
  msgid "Settings saved successfully."
1358
  msgstr "Ajustes guardados satisfactoriamente."
1359
 
1360
- #: includes/admin/settings.php:491
1361
  msgid "General"
1362
  msgstr "General"
1363
 
1364
- #: includes/admin/settings.php:521
1365
  msgid "Envira License Key"
1366
  msgstr "Clave de licencia de Envira"
1367
 
1368
- #: includes/admin/settings.php:527
1369
  msgid "Verify Key"
1370
  msgstr "Comprobar clave"
1371
 
1372
- #: includes/admin/settings.php:528
1373
  msgid "Deactivate Key"
1374
  msgstr "Desactivar clave"
1375
 
1376
- #: includes/admin/settings.php:529
1377
  msgid "License key to enable automatic updates for Envira."
1378
  msgstr ""
1379
  "Clave de licencia para activar las actualizaciones automáticas para Envira."
1380
 
1381
- #: includes/admin/settings.php:536
1382
  msgid "Envira License Key Type"
1383
  msgstr "Tipo de licencia Envira."
1384
 
1385
- #: includes/admin/settings.php:540
1386
  msgid "Your license key type for this site is <strong>%s.</strong>"
1387
  msgstr "Su tipo de licencia para este sitio es <strong>%s.</strong>"
1388
 
1389
- #: includes/admin/settings.php:543
1390
  msgid "Refresh Key"
1391
  msgstr "Actualizar clave"
1392
 
1393
- #: includes/admin/settings.php:544
1394
  msgid ""
1395
  "Your license key type (handles updates and Addons). Click refresh if your "
1396
  "license has been upgraded or the type is incorrect."
@@ -1399,15 +1510,15 @@ msgstr ""
1399
  "clic en actualizar si ha actualizado su tipo de licencia o el tipo es "
1400
  "incorrecto."
1401
 
1402
- #: includes/admin/settings.php:553
1403
  msgid "Fix Broken Migration"
1404
  msgstr "Solucionar migración rota"
1405
 
1406
- #: includes/admin/settings.php:558
1407
  msgid "Fix"
1408
  msgstr "Solucionar"
1409
 
1410
- #: includes/admin/settings.php:559
1411
  msgid ""
1412
  "If you have changed the URL of your WordPress web site, and manually "
1413
  "executed a search/replace query on URLs in your WordPress database, your "
@@ -1421,11 +1532,11 @@ msgstr ""
1421
  "es el caso, haga clic en el botón de arriba para solucionar este problema. "
1422
  "Le recomendamos que use un plugin o script de migración la próxima vez :)"
1423
 
1424
- #: includes/admin/settings.php:575
1425
  msgid "Add New Images"
1426
  msgstr "Añadir nuevas imágenes"
1427
 
1428
- #: includes/admin/settings.php:583
1429
  msgid ""
1430
  "When adding media to a Gallery, choose whether to add this media before or "
1431
  "after any existing images."
@@ -1433,11 +1544,11 @@ msgstr ""
1433
  "Si añade medios a una Galería, elija si desea añadir este medio antes o "
1434
  "después de las imágenes existentes."
1435
 
1436
- #: includes/admin/settings.php:590
1437
  msgid "Delete Image on Gallery Image Deletion"
1438
  msgstr "Elimina la imagen cuando se borra de una galería"
1439
 
1440
- #: includes/admin/settings.php:598
1441
  msgid ""
1442
  "When deleting an Image from a Gallery, choose whether to delete all media "
1443
  "associated with that image. Note: If image(s) in the Media Library are "
@@ -1447,11 +1558,11 @@ msgstr ""
1447
  "asociados con esa imagen. Nota: Si la imagen(es) en la biblioteca multimedia "
1448
  "está(n) vinculada(s) a otras entradas, no se borrarán."
1449
 
1450
- #: includes/admin/settings.php:604
1451
  msgid "Delete Images on Gallery Deletion"
1452
  msgstr "Elimina las imágenes cuando se borra una galería"
1453
 
1454
- #: includes/admin/settings.php:612
1455
  msgid ""
1456
  "When deleting a Gallery, choose whether to delete all media associated with "
1457
  "the gallery. Note: If image(s) in the Media Library are attached to other "
@@ -1461,7 +1572,7 @@ msgstr ""
1461
  "la galería. Nota: Si la imagen(es) en la biblioteca multimedia está(n) "
1462
  "vinculada(s) a otras entradas, no se borrarán."
1463
 
1464
- #: includes/admin/settings.php:621
1465
  msgid "Save Settings"
1466
  msgstr "Guardar ajustes"
1467
 
@@ -1470,35 +1581,35 @@ msgid "There was an error installing the addon. Please try again."
1470
  msgstr ""
1471
  "Hubo un error al instalar el complemento. Por favor, vuelva a intentarlo."
1472
 
1473
- #: includes/admin/table.php:167
1474
  msgid "Shortcode"
1475
  msgstr "Código corto"
1476
 
1477
- #: includes/admin/table.php:168
1478
  msgid "Posts"
1479
  msgstr "Entradas"
1480
 
1481
- #: includes/admin/table.php:169
1482
  msgid "Last Modified"
1483
  msgstr "última modificada"
1484
 
1485
- #: includes/admin/table.php:170
1486
  msgid "Date"
1487
  msgstr "Fecha"
1488
 
1489
- #: includes/admin/table.php:215
1490
  msgid "%d Image"
1491
  msgid_plural "%d Images"
1492
  msgstr[0] "%d Imagen"
1493
  msgstr[1] "%d Imagenes"
1494
 
1495
- #: includes/admin/table.php:294 includes/admin/table.php:369
1496
  msgid "Number of Columns"
1497
  msgstr "Número de columnas"
1498
 
1499
- #: includes/admin/table.php:371 includes/admin/table.php:382
1500
- #: includes/admin/table.php:392 includes/admin/table.php:397
1501
- #: includes/admin/table.php:402 includes/admin/table.php:404
1502
  msgid "— No Change —"
1503
  msgstr "— Sin cambios —"
1504
 
@@ -1654,23 +1765,23 @@ msgstr "Arriba"
1654
  msgid "Bottom"
1655
  msgstr "Abajo"
1656
 
1657
- #: includes/global/common.php:640
1658
  msgid "Image Files"
1659
  msgstr "Archivos de imagen"
1660
 
1661
- #: includes/global/common.php:690
1662
  msgid "Before Existing Images"
1663
  msgstr "Antes de las imágenes existentes"
1664
 
1665
- #: includes/global/common.php:694
1666
  msgid "After Existing Images"
1667
  msgstr "Después de las imágenes existentes"
1668
 
1669
- #: includes/global/common.php:718
1670
  msgid "Yes"
1671
  msgstr "Si"
1672
 
1673
- #: includes/global/common.php:786
1674
  msgid ""
1675
  "No image editor could be selected. Please verify with your webhost that you "
1676
  "have either the GD or Imagick image library compiled with your PHP install "
@@ -1680,15 +1791,15 @@ msgstr ""
1680
  "su servicio de hosting que tiene compilada en su instalación PHP de su "
1681
  "servidor una biblioteca de imágenes, ya sea GD o Imagick."
1682
 
1683
- #: includes/global/common.php:889
1684
  msgid "No image URL specified for cropping."
1685
  msgstr "No sé ha especificado ninguna URL de imagen para recortar."
1686
 
1687
- #: includes/global/common.php:908
1688
  msgid "No file could be found for the image URL specified."
1689
  msgstr "No se pudo encontrar el archivo de la URL de imagen especificada."
1690
 
1691
- #: includes/global/common.php:916 includes/global/common.php:928
1692
  msgid ""
1693
  "The dimensions of the original image could not be retrieved for cropping."
1694
  msgstr ""
@@ -1730,21 +1841,21 @@ msgstr "No se han encontrado galerías Envira."
1730
  msgid "No Envira galleries found in trash."
1731
  msgstr "No se han encontrado galerías Envira en la papelera."
1732
 
1733
- #: includes/global/shortcode.php:753
1734
  msgid "The requested content cannot be loaded.<br/>Please try again later.</p>"
1735
  msgstr ""
1736
  "El contenido solicitado no se puede cargar. <br/> Por favor, inténtelo de "
1737
  "nuevo más tarde. </ P>"
1738
 
1739
- #: includes/global/shortcode.php:754 includes/global/shortcode.php:1287
1740
  msgid "Close"
1741
  msgstr "Cerrar"
1742
 
1743
- #: includes/global/shortcode.php:755 includes/global/shortcode.php:1277
1744
  msgid "Next"
1745
  msgstr "Siguiente"
1746
 
1747
- #: includes/global/shortcode.php:756 includes/global/shortcode.php:1273
1748
  msgid "Previous"
1749
  msgstr "Anterior"
1750
 
@@ -1760,23 +1871,53 @@ msgstr "Galería"
1760
  msgid "Gallery ID #%s"
1761
  msgstr "ID de galería #%s"
1762
 
 
 
 
 
1763
  #. Plugin URI of the plugin/theme
 
1764
  msgid "http://enviragallery.com"
1765
  msgstr "http://enviragallery.com"
1766
 
1767
  #. Description of the plugin/theme
1768
- msgid "Envira Gallery is best responsive WordPress gallery plugin."
 
 
1769
  msgstr ""
1770
  "Envira Gallery is el mejor plugin de galería de Wordpress de diseño "
1771
- "adaptable."
1772
 
1773
  #. Author of the plugin/theme
1774
  msgid "Thomas Griffin"
1775
  msgstr "Thomas Griffin"
1776
 
1777
- #. Author URI of the plugin/theme
1778
- msgid "http://thomasgriffinmedia.com"
1779
- msgstr "http://thomasgriffinmedia.com"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1780
 
1781
  #~ msgid "Choose Your Gallery"
1782
  #~ msgstr "Seleccione su galería"
4
  msgstr ""
5
  "Project-Id-Version: Envira Gallery 1.3.8.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/envira-gallery\n"
7
+ "POT-Creation-Date: 2016-06-26 19:45+0200\n"
8
+ "PO-Revision-Date: 2016-06-26 20:05+0200\n"
9
  "Last-Translator: José Luis Pérez-Lozana <joseluis.perez.lozana@gmail.com>\n"
10
  "Language-Team: \n"
11
  "Language: es_ES\n"
12
  "MIME-Version: 1.0\n"
13
  "Content-Type: text/plain; charset=UTF-8\n"
14
  "Content-Transfer-Encoding: 8bit\n"
15
+ "X-Generator: Poedit 1.8.8\n"
16
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
17
 
18
+ #: envira-gallery-lite.php:508
19
+ msgid ""
20
+ "Sorry, but your version of WordPress does not meet Envira Gallery's required "
21
+ "version of <strong>4.0</strong> to run properly. The plugin has been "
22
+ "deactivated. <a href=\"%s\">Click here to return to the Dashboard</a>."
23
+ msgstr ""
24
+ "Lo sentimos, pero su versión de WordPress no cumple con la versión "
25
+ "<strong>4.0</strong> necesaria para que Envira Gallery funcione "
26
+ "correctamente. Se ha desactivado el plugin. <a href=\"%s\">Pulse aquí para "
27
+ "volver al escritorio</a>."
28
+
29
  #: envira-gallery.php:182
30
  msgid ""
31
  "Please <a href=\"plugins.php\">deactivate</a> the Envira Lite Plugin. Your "
56
  "correctamente. Se ha desactivado el plugin. <a href=\"%s\">Pulse aquí para "
57
  "volver al escritorio</a>."
58
 
59
+ #: includes/admin/addons.php:79 includes/admin/addons.php:193
60
  msgid "Envira Gallery Addons"
61
  msgstr "Complementos Envira Gallery"
62
 
63
+ #: includes/admin/addons.php:80 includes/admin/addons.php:447
64
  msgid "Addons"
65
  msgstr "Complementos"
66
 
67
+ #: includes/admin/addons.php:161 includes/admin/settings.php:413
 
68
  msgid "Status: Active"
69
  msgstr "Status: Activo"
70
 
71
+ #: includes/admin/addons.php:162 includes/admin/addons.php:554
72
+ #: includes/admin/settings.php:414
73
  msgid "Activate"
74
  msgstr "Activar"
75
 
76
+ #: includes/admin/addons.php:164 includes/admin/settings.php:416
77
  msgid "Activating..."
78
  msgstr "Activando..."
79
 
80
+ #: includes/admin/addons.php:166 includes/admin/addons.php:538
81
+ #: includes/admin/settings.php:418
82
  msgid "Deactivate"
83
  msgstr "Desactivar"
84
 
85
+ #: includes/admin/addons.php:168 includes/admin/settings.php:420
86
  msgid "Deactivating..."
87
  msgstr "Desactivando..."
88
 
89
+ #: includes/admin/addons.php:169 includes/admin/settings.php:421
 
90
  msgid "Status: Inactive"
91
  msgstr "Status: Inactivo"
92
 
93
+ #: includes/admin/addons.php:170 includes/admin/addons.php:520
94
+ #: includes/admin/settings.php:422
95
  msgid "Install"
96
  msgstr "Instalar"
97
 
98
+ #: includes/admin/addons.php:172 includes/admin/settings.php:424
99
  msgid "Installing..."
100
  msgstr "Instalando..."
101
 
102
+ #: includes/admin/addons.php:173 includes/admin/settings.php:425
103
  msgid "Proceed"
104
  msgstr "Proceder"
105
 
106
+ #: includes/admin/addons.php:196
107
+ msgid "Search Envira Addons"
108
+ msgstr "Buscar complementos de Envira"
109
+
110
+ #: includes/admin/addons.php:198
111
+ msgid "Sort Ascending (A-Z)"
112
+ msgstr "Ascendente (A-Z)"
113
+
114
+ #: includes/admin/addons.php:199
115
+ msgid "Sort Descending (Z-A)"
116
+ msgstr "Descendente (Z-A)"
117
+
118
+ #: includes/admin/addons.php:225
119
  msgid ""
120
+ "In order to get access to Addons, you need to resolve your license key "
121
+ "errors."
122
  msgstr ""
123
+ "Para tener acceso a Complementos, necesita corregir los errores de la clave "
124
+ "de licencia."
125
 
126
  #: includes/admin/addons.php:241
127
  msgid ""
128
+ "There was an issue retrieving the addons for this site. Please click on the "
129
+ "button below the refresh the addons data."
130
  msgstr ""
131
+ "Hubo un problema al recuperar los complementos para este sitio. Por favor, "
132
+ "haga clic en el botón de abajo para actualizar los datos de complementos."
 
133
 
134
+ #: includes/admin/addons.php:244
135
  msgid "Refresh Addons"
136
  msgstr "Actualizar complementos"
137
 
138
+ #: includes/admin/addons.php:262
139
+ msgid "Available Addons"
140
+ msgstr "Complementos disponibles"
141
+
142
+ #: includes/admin/addons.php:282
143
  msgid "Unlock More Addons"
144
  msgstr "Desbloquear más complementos"
145
 
146
+ #: includes/admin/addons.php:283
147
  msgid ""
148
+ "<strong>Want even more addons?</strong> <a href=\"%s\">Upgrade your Envira "
149
  "Gallery account</a> and unlock the following addons."
150
  msgstr ""
151
  "<strong>¿Aún quiere-más complementos?</strong> <a href=\"#\">Actualice su "
152
  "cuenta Envira Gallery</a> y desbloquee los siguientes complementos."
153
 
154
+ #: includes/admin/addons.php:501
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  msgid "Upgrade Now"
156
  msgstr "Actualice ahora"
157
 
158
+ #: includes/admin/addons.php:516
159
+ msgid "Status: <span>Not Installed</span>"
160
+ msgstr "Status: <span>No instalado</span>"
161
 
162
+ #: includes/admin/addons.php:534
163
+ msgid "Status: <span>Active</span>"
164
+ msgstr "Status: <span>Activo</span>"
165
 
166
+ #: includes/admin/addons.php:550
167
+ msgid "Status: <span>Inactive</span>"
168
+ msgstr "Status: <span>Inactivo</span>"
169
 
170
+ #: includes/admin/ajax.php:923 includes/admin/ajax.php:926
171
  msgid "The From Gallery ID has not been specified."
172
  msgstr "No se ha especificado el ID de la galería."
173
 
174
+ #: includes/admin/ajax.php:929
175
  msgid "No images were selected to be moved between Galleries."
176
  msgstr "No se han seleccionado imágenes para moverlas entre las galerías."
177
 
186
 
187
  #: includes/admin/editor.php:86 includes/admin/editor.php:87
188
  #: includes/admin/editor.php:93 includes/admin/editor.php:94
189
+ #: includes/admin/metaboxes.php:267 includes/admin/metaboxes.php:268
190
+ #: includes/admin/table.php:142 includes/admin/table.php:143
191
  msgid "Insert"
192
  msgstr "Insertar"
193
 
251
  "Galería Envira importada. Por favor, compruebe que todas las imágenes y los "
252
  "datos han sido importados correctamente."
253
 
254
+ #: includes/admin/license.php:131 includes/admin/license.php:224
255
+ #: includes/admin/license.php:313
256
  msgid ""
257
  "There was an error connecting to the remote key API. Please try again later."
258
  msgstr ""
259
  "Hubo un error al conectarse a la llave API remota. Por favor, inténtelo de "
260
  "nuevo más tarde."
261
 
262
+ #: includes/admin/license.php:148
263
  msgid "Congratulations! This site is now receiving automatic updates."
264
  msgstr "¡Felicidades! Este sitio está recibiendo actualizaciones automáticas."
265
 
266
+ #: includes/admin/license.php:266
267
  msgid "Congratulations! Your key has been refreshed successfully."
268
  msgstr "¡Felicidades! Su clave ha sido actualizada correctamente."
269
 
270
+ #: includes/admin/license.php:324
271
  msgid ""
272
  "Congratulations! You have deactivated the key from this site successfully."
273
  msgstr "¡Felicidades! Ha desactivado la clave de este sitio correctamente."
274
 
275
+ #: includes/admin/license.php:418
276
  msgid ""
277
  "No valid license key has been entered, so automatic updates for Envira "
278
  "Gallery have been turned off. <a href=\"%s\">Please click here to enter your "
283
  "\"%s\"> Haga clic aquí para introducir su clave de licencia y comenzar a "
284
  "recibir actualizaciones automáticas.</a>"
285
 
286
+ #: includes/admin/license.php:427
287
  msgid ""
288
  "Your license key for Envira Gallery has expired. <a href=\"%s\" target="
289
  "\"_blank\">Please click here to renew your license key and continue "
293
  "\"_blank\">Haga clic aquí para renovar su licencia y seguir recibiendo "
294
  "actualizaciones automáticas.</a>"
295
 
296
+ #: includes/admin/license.php:436
297
  msgid ""
298
  "Your license key for Envira Gallery has been disabled. Please use a "
299
  "different key to continue receiving automatic updates."
301
  "Se ha desactivado su clave de licencia para Envira Gallery. Utilice una "
302
  "clave diferente para seguir recibiendo las actualizaciones automáticas."
303
 
304
+ #: includes/admin/license.php:445
305
  msgid ""
306
  "Your license key for Envira Gallery is invalid. The key no longer exists or "
307
  "the user associated with the key has been deleted. Please use a different "
312
  "diferente para seguir recibiendo las actualizaciones automáticas."
313
 
314
  #: includes/admin/media-view.php:101 includes/admin/media-view.php:102
315
+ #: includes/admin/media-view.php:504 includes/admin/media-view.php:505
316
  msgid "Search"
317
  msgstr "buscar"
318
 
319
+ #: includes/admin/media-view.php:154 includes/admin/media-view.php:481
320
  msgid "Helpful Tips"
321
  msgstr "Consejos útiles"
322
 
355
  msgid "Display Title"
356
  msgstr "Título que se mostrará"
357
 
358
+ #: includes/admin/media-view.php:171 includes/global/common.php:723
359
  msgid "No"
360
  msgstr "No"
361
 
379
  msgid "Edit Metadata"
380
  msgstr "Editar Metadatos"
381
 
382
+ #: includes/admin/media-view.php:240 includes/admin/media-view.php:374
383
+ #: includes/admin/table.php:167 includes/global/common.php:171
384
  #: includes/global/widget.php:153
385
  msgid "Title"
386
  msgstr "Título"
387
 
388
+ #: includes/admin/media-view.php:243 includes/admin/media-view.php:377
389
  msgid ""
390
  "Image titles can take any type of HTML. You can adjust the position of the "
391
  "titles in the main Lightbox settings."
393
  "Los títulos de imagen pueden tener cualquier tipo de HTML. Se puede ajustar "
394
  "la posición de los títulos en los ajustes generales de lightbox."
395
 
396
+ #: includes/admin/media-view.php:252 includes/admin/media-view.php:383
397
  #: includes/global/common.php:175
398
  msgid "Caption"
399
  msgstr "Pie"
400
 
401
+ #: includes/admin/media-view.php:266 includes/admin/media-view.php:397
402
  msgid ""
403
  "Captions can take any type of HTML, and are displayed when an image is "
404
  "clicked."
406
  "Los pies de foto pueden usar cualquier tipo de HTML, y se muestra cuando se "
407
  "hace clic en una imagen."
408
 
409
+ #: includes/admin/media-view.php:275 includes/admin/media-view.php:403
410
  msgid "Alt Text"
411
  msgstr "Texto alternativo"
412
 
413
+ #: includes/admin/media-view.php:278 includes/admin/media-view.php:406
414
  msgid "Very important for SEO, the Alt Text describes the image."
415
  msgstr "Muy importante para SEO, el texto alternativo describe la imagen."
416
 
417
+ #: includes/admin/media-view.php:284 includes/admin/media-view.php:412
418
  #: includes/global/common.php:183
419
  msgid "URL"
420
  msgstr "URL"
421
 
422
+ #: includes/admin/media-view.php:288 includes/admin/media-view.php:416
423
  msgid "Media File"
424
  msgstr "Archivo multimedia"
425
 
426
+ #: includes/admin/media-view.php:289 includes/admin/media-view.php:417
427
  msgid "Attachment Page"
428
  msgstr "Página de anexo"
429
 
430
+ #: includes/admin/media-view.php:293 includes/admin/media-view.php:421
431
  msgid ""
432
  "Enter a hyperlink if you wish to link this image to somewhere other than its "
433
  "full size image."
435
  "Introduzca un hipervínculo si desea enlazar esta imagen a un sitio diferente "
436
  "de su imagen a tamaño completo."
437
 
438
+ #: includes/admin/media-view.php:302 includes/admin/media-view.php:427
439
  msgid "Open URL in New Window?"
440
  msgstr "¿Abrir la URL en una ventana nueva?"
441
 
442
+ #: includes/admin/media-view.php:305 includes/admin/media-view.php:430
443
  msgid "Opens your image links in a new browser window / tab."
444
  msgstr ""
445
  "Abre sus enlaces de imagen en una nueva ventana / pestaña del navegador."
446
 
447
+ #: includes/admin/media-view.php:316
448
+ msgid "Want Captions and more options?"
449
+ msgstr ""
450
+
451
+ #: includes/admin/media-view.php:317
452
+ msgid ""
453
+ "By upgrading to Envira Pro, you can get access to numerous other features, "
454
+ "including: HTML captions, open links in new windows, WooCommerce product "
455
+ "integration and so much more!"
456
+ msgstr ""
457
+ "Mediante la actualización a Envira Pro puede obtener acceso a otras muchas "
458
+ "características, incluyendo: subtítulos HTML, abrir enlaces en nuevas "
459
+ "ventanas, integrar productos WooCommerce y mucho más."
460
+
461
+ #: includes/admin/media-view.php:319 includes/admin/metaboxes.php:776
462
+ #: includes/admin/metaboxes.php:1072 includes/admin/metaboxes.php:1388
463
+ #: includes/admin/metaboxes.php:1643 includes/admin/metaboxes.php:1685
464
+ #: includes/admin/metaboxes.php:1707 includes/admin/metaboxes.php:1729
465
+ #: includes/admin/metaboxes.php:1751 includes/admin/metaboxes.php:1773
466
+ msgid "Click here to Upgrade"
467
+ msgstr "Haga clic aquí para actualizar."
468
+
469
+ #: includes/admin/media-view.php:336 includes/admin/media-view.php:337
470
+ #: includes/admin/media-view.php:442
471
  msgid "Save Metadata"
472
  msgstr "Guardar Metadatos"
473
 
474
+ #: includes/admin/media-view.php:343 includes/admin/media-view.php:448
475
  msgid "Saved."
476
  msgstr "Guardado"
477
 
478
+ #: includes/admin/media-view.php:358
479
  msgid "Bulk Edit"
480
  msgstr "Editar en bloque"
481
 
482
+ #: includes/admin/media-view.php:441
483
  msgid "Save Metadata to Items"
484
  msgstr "Guardar Metadatos en los elementos"
485
 
486
+ #: includes/admin/media-view.php:483
487
  msgid ""
488
  "Select the Gallery to move the selected images to by clicking on one of the "
489
  "boxes to the left."
491
  "Seleccione la Galería a la que quiere mover las imágenes seleccionadas, "
492
  "haciendo clic en una de las cajas de la izquierda."
493
 
494
+ #: includes/admin/media-view.php:486
495
  msgid ""
496
  "Once done, click the Move button, and the selected images will be moved to "
497
  "the chosen Gallery."
499
  "Una vez hecho, haga clic en el botón Mover y las imágenes seleccionadas se "
500
  "moverán a la galería elegida."
501
 
502
+ #: includes/admin/metaboxes.php:99
503
  msgid ""
504
  "The GD or Imagick libraries are not installed on your server. Envira Gallery "
505
  "requires at least one (preferably Imagick) in order to crop images and may "
512
  "con su servicio de hosting y pídales que compilen GD o Imagick para su "
513
  "instalación de PHP."
514
 
515
+ #: includes/admin/metaboxes.php:134
516
  msgid "Insert into Gallery"
517
  msgstr "Insertar en la galería"
518
 
519
+ #: includes/admin/metaboxes.php:135 includes/admin/metaboxes.php:283
520
  msgid "Inserting..."
521
  msgstr "Insertando..."
522
 
523
+ #: includes/admin/metaboxes.php:160
524
  msgid "Click Here to Insert from Other Image Sources"
525
  msgstr "Haga clic aquí para insertar desde otra fuentes de imágenes"
526
 
527
+ #: includes/admin/metaboxes.php:161
528
  msgid "Select Files from Other Sources"
529
  msgstr "Seleccione los archivos de otras Fuentes"
530
 
531
+ #: includes/admin/metaboxes.php:169
532
  msgid "Uploading Image"
533
  msgstr "Subiendo imagen"
534
 
535
+ #: includes/admin/metaboxes.php:171
536
  msgid "of"
537
  msgstr "de"
538
 
539
+ #: includes/admin/metaboxes.php:175
540
  msgid "All images uploaded."
541
  msgstr "Subidas todas las imágenes."
542
 
543
+ #: includes/admin/metaboxes.php:281
544
  msgid "You must select a file to import before continuing."
545
  msgstr "Debe seleccionar un archivo para importar antes de continuar."
546
 
547
+ #: includes/admin/metaboxes.php:289
548
  msgid "Move Media to Gallery"
549
  msgstr "Mover medios a la galería"
550
 
551
+ #: includes/admin/metaboxes.php:290
552
  msgid "Move Media to Selected Gallery"
553
  msgstr "Mover medios a la galería seleccionada"
554
 
555
+ #: includes/admin/metaboxes.php:293
556
  msgid "Are you sure you want to remove this image from the gallery?"
557
  msgstr "¿Seguro que quieres eliminar esta imagen de la galería?"
558
 
559
+ #: includes/admin/metaboxes.php:294
560
  msgid "Are you sure you want to remove these images from the gallery?"
561
  msgstr "¿Seguro que desea eliminar estas imágenes de la galería?"
562
 
563
+ #: includes/admin/metaboxes.php:298
564
  msgid "Saving..."
565
  msgstr "Guardando..."
566
 
567
+ #: includes/admin/metaboxes.php:299
568
  msgid "Saved!"
569
  msgstr "¡Guardado!"
570
 
571
+ #: includes/admin/metaboxes.php:301
572
  msgid "Select Files from Your Computer"
573
  msgstr "Seleccione los archivos de su ordenador"
574
 
575
+ #: includes/admin/metaboxes.php:402 includes/admin/partials/header.php:14
 
576
  #: includes/global/posttype.php:52 includes/global/posttype.php:62
577
  #: includes/global/widget.php:50
578
  msgid "Envira Gallery"
579
  msgstr "Envira Gallery"
580
 
581
+ #: includes/admin/metaboxes.php:406 includes/admin/settings.php:82
582
  msgid "Envira Gallery Settings"
583
  msgstr "Ajustes de Envira Gallery"
584
 
585
+ #: includes/admin/metaboxes.php:411
586
  msgid "Envira Gallery Preview"
587
  msgstr "Vista previa de Envira Gallery"
588
 
589
+ #: includes/admin/metaboxes.php:415
590
  msgid "Envira Gallery Code"
591
  msgstr "Código de Envira Gallery"
592
 
593
+ #: includes/admin/metaboxes.php:586 includes/global/common.php:253
594
  msgid "Default"
595
  msgstr "Predeterminada"
596
 
597
+ #: includes/admin/metaboxes.php:603
598
  msgid "Images"
599
  msgstr "Imágenes"
600
 
601
+ #: includes/admin/metaboxes.php:604
602
  msgid "Config"
603
  msgstr "Configuración"
604
 
605
+ #: includes/admin/metaboxes.php:605
606
  msgid "Lightbox"
607
  msgstr "Lightbox"
608
 
609
+ #: includes/admin/metaboxes.php:606 includes/admin/metaboxes.php:1661
610
  msgid "Mobile"
611
  msgstr "Móvil"
612
 
613
+ #: includes/admin/metaboxes.php:611
614
  msgid "Misc"
615
  msgstr "Varios"
616
 
617
+ #: includes/admin/metaboxes.php:705
618
  msgid "Currently in your Gallery"
619
  msgstr "Actualmente en la galería"
620
 
621
+ #: includes/admin/metaboxes.php:707 includes/admin/metaboxes.php:800
622
+ #: includes/admin/metaboxes.php:1096 includes/admin/metaboxes.php:1411
623
+ #: includes/admin/metaboxes.php:1549
624
  msgid "Need some help?"
625
  msgstr "¿Necesita ayuda?"
626
 
627
+ #: includes/admin/metaboxes.php:709 includes/admin/metaboxes.php:802
628
+ #: includes/admin/metaboxes.php:1098 includes/admin/metaboxes.php:1413
629
+ #: includes/admin/metaboxes.php:1551
630
  msgid "Read the Documentation"
631
  msgstr "Lea la documentación"
632
 
633
+ #: includes/admin/metaboxes.php:713 includes/admin/metaboxes.php:806
634
+ #: includes/admin/metaboxes.php:1102 includes/admin/metaboxes.php:1417
635
+ #: includes/admin/metaboxes.php:1555
636
  msgid "Watch a Video"
637
  msgstr "Mire el video"
638
 
639
+ #: includes/admin/metaboxes.php:725
640
  msgid "Select All (<span class=\"count\">%d</span>)"
641
  msgstr "Seleccione todo (<span class=\"count\">%d</span>"
642
 
643
+ #: includes/admin/metaboxes.php:730
644
  msgid "Grid View"
645
  msgstr "Vista de cuadrícula"
646
 
647
+ #: includes/admin/metaboxes.php:733
648
  msgid "List View"
649
  msgstr "Vista de lista"
650
 
651
+ #: includes/admin/metaboxes.php:739 includes/admin/metaboxes.php:764
652
  msgid "Edit Selected Images"
653
  msgstr "Editar imágenes seleccionadas"
654
 
655
+ #: includes/admin/metaboxes.php:740 includes/admin/metaboxes.php:765
656
  msgid "Move Selected Images to another Gallery"
657
  msgstr "Mover las imágenes seleccionadas a otra galería"
658
 
659
+ #: includes/admin/metaboxes.php:741 includes/admin/metaboxes.php:766
660
  msgid "Delete Selected Images from Gallery"
661
  msgstr "Borrar las imágenes seleccionadas de la galería"
662
 
663
+ #: includes/admin/metaboxes.php:773
664
+ msgid "Want to make your gallery workflow even better?"
665
+ msgstr "¿Quiere mejorar aún más flujo de trabajo?"
666
+
667
+ #: includes/admin/metaboxes.php:774
668
+ msgid ""
669
+ "By upgrading to Envira Pro, you can get access to numerous other features, "
670
+ "including: a fully featured gallery widget, complete gallery API, powerful "
671
+ "gallery documentation, full mobile and Retina support, dedicated customer "
672
+ "support and so much more!"
673
+ msgstr ""
674
+ "Mediante la actualización a Envira Pro puede obtener acceso a otras muchas "
675
+ "características, incluyendo: un widget de gallery con todas las funciones, "
676
+ "API de galería completa, documentación de galería potente, soporte móvil y "
677
+ "retina completos, atención al cliente y mucho más."
678
+
679
+ #: includes/admin/metaboxes.php:797
680
+ msgid "Gallery Settings"
681
+ msgstr "Ajustes de la galería"
682
+
683
+ #: includes/admin/metaboxes.php:799
684
  msgid ""
685
  "The settings below adjust the basic configuration options for the gallery."
686
  msgstr ""
687
  "Los siguientes ajustes configuran las opciones básicas para la galería."
688
 
689
+ #: includes/admin/metaboxes.php:814 includes/admin/metaboxes.php:1425
690
  msgid "Number of Gallery Columns"
691
  msgstr "Número de columnas de la galería"
692
 
693
+ #: includes/admin/metaboxes.php:822
694
  msgid ""
695
  "Determines the number of columns in the gallery. Automatic will attempt to "
696
  "fill each row as much as possible before moving on to the next row."
698
  "Determina el número de columnas en la galería. Automático tratará de "
699
  "rellenar la fila tanto como sea posible antes de pasar a la siguiente. "
700
 
701
+ #: includes/admin/metaboxes.php:827 includes/admin/table.php:305
702
+ #: includes/admin/table.php:382
703
  msgid "Gallery Theme"
704
  msgstr "Tema de la galería"
705
 
706
+ #: includes/admin/metaboxes.php:835
707
  msgid "Sets the theme for the gallery display."
708
  msgstr "Establece el tema para la presentación de la galería."
709
 
710
+ #: includes/admin/metaboxes.php:845
711
  msgid "Display Gallery Description?"
712
  msgstr "¿Mostrar la descripción de la galería?"
713
 
714
+ #: includes/admin/metaboxes.php:857
715
  msgid "Choose to display a description above or below this gallery's images."
716
  msgstr ""
717
  "Elija si desea mostrar una descripción encima o debajo de las imágenes de "
718
  "esta galería."
719
 
720
+ #: includes/admin/metaboxes.php:864
721
  msgid "Gallery Description"
722
  msgstr "Descripción de la galería"
723
 
724
+ #: includes/admin/metaboxes.php:879
725
  msgid "The description to display for this gallery."
726
  msgstr "Descripción que se mostrará para esta galería"
727
 
728
+ #: includes/admin/metaboxes.php:888 includes/admin/table.php:314
729
+ #: includes/admin/table.php:393
730
  msgid "Column Gutter Width"
731
  msgstr "Ancho de separación de columnas"
732
 
733
+ #: includes/admin/metaboxes.php:891 includes/admin/metaboxes.php:900
734
+ #: includes/admin/metaboxes.php:998 includes/admin/metaboxes.php:1345
735
+ #: includes/admin/metaboxes.php:1354 includes/admin/metaboxes.php:1452
736
  msgid "px"
737
  msgstr "px"
738
 
739
+ #: includes/admin/metaboxes.php:892
740
  msgid "Sets the space between the columns (defaults to 10)."
741
  msgstr "Establece el espacio entre las columnas (por defecto 10)."
742
 
743
+ #: includes/admin/metaboxes.php:897 includes/admin/table.php:319
744
+ #: includes/admin/table.php:398
745
  msgid "Margin Below Each Image"
746
  msgstr "Margen debajo de cada imagen"
747
 
748
+ #: includes/admin/metaboxes.php:901
749
  msgid "Sets the space below each item in the gallery."
750
  msgstr "Establece el espacio debajo de cada elemento en la galería."
751
 
752
+ #: includes/admin/metaboxes.php:911
753
  msgid "Sorting"
754
  msgstr "Clasificar por:"
755
 
756
+ #: includes/admin/metaboxes.php:923
757
  msgid ""
758
  "Choose to sort the images in a different order than displayed on the Images "
759
  "tab."
761
  "Elija ordenar las imágenes en un orden diferente al que aparece en la "
762
  "pestaña Imágenes."
763
 
764
+ #: includes/admin/metaboxes.php:928
765
  msgid "Direction"
766
  msgstr "Dirección"
767
 
768
+ #: includes/admin/metaboxes.php:949 includes/admin/metaboxes.php:1140
769
  msgid "Image Size"
770
  msgstr "Tamaño de imagen"
771
 
772
+ #: includes/admin/metaboxes.php:961
773
  msgid ""
774
  "Define the maximum image size for the Gallery view. Default will use the "
775
  "below Image Dimensions; Random will allow you to choose one or more "
780
  "elegir entre uno o más tamaños de imagen de WordPress, que se utilizará para "
781
  "la galería."
782
 
783
+ #: includes/admin/metaboxes.php:970
784
  msgid "Random Image Sizes"
785
  msgstr "Tamaños de imagen aleatorios"
786
 
787
+ #: includes/admin/metaboxes.php:986
788
  msgid ""
789
  "Define the WordPress registered image sizes to include when randomly "
790
  "assigning an image size to each image in your Gallery."
792
  "Definir los tamaños de imagen de WordPress para incluirlos cuando se asigna "
793
  "un tamaño de imagen aleatorio a cada imagen en la galería."
794
 
795
+ #: includes/admin/metaboxes.php:995 includes/admin/table.php:325
796
+ #: includes/admin/table.php:403
797
  msgid "Image Dimensions"
798
  msgstr "Dimensiones de la imagen"
799
 
800
+ #: includes/admin/metaboxes.php:999
801
  msgid ""
802
  "You should adjust these dimensions based on the number of columns in your "
803
  "gallery. This does not affect the full size lightbox images."
805
  "Debe ajustar estas dimensiones en función del número de columnas en su "
806
  "galería. Esto no afecta al tamaño de las imágenes de la galería lightbox."
807
 
808
+ #: includes/admin/metaboxes.php:1004
809
  msgid "Crop Images?"
810
  msgstr "¿Recortar imágenes?"
811
 
812
+ #: includes/admin/metaboxes.php:1008
813
  msgid ""
814
  "If enabled, forces images to exactly match the sizes defined above for Image "
815
  "Dimensions and Mobile Dimensions."
818
  "definidos previamente para las dimensiones de imagen y las dimensiones para "
819
  "móviles."
820
 
821
+ #: includes/admin/metaboxes.php:1009
822
  msgid "If disabled, images will be resized to maintain their aspect ratio."
823
  msgstr ""
824
  "Si se desactiva, las imágenes se redimensionarán manteniendo la relación de "
825
  "aspecto."
826
 
827
+ #: includes/admin/metaboxes.php:1019
828
  msgid "Set Dimensions on Images?"
829
  msgstr "¿Establecer dimensiones de las imágenes?"
830
 
831
+ #: includes/admin/metaboxes.php:1023
832
  msgid ""
833
  "Enables or disables the width and height attributes on the img element. Only "
834
  "needs to be enabled if you need to meet Google Pagespeeds requirements."
837
  "Sólo necesita activarlo si es necesario cumplir con los requisitos de Google "
838
  "Pagespeeds."
839
 
840
+ #: includes/admin/metaboxes.php:1028
841
  msgid "Enable Isotope?"
842
  msgstr "¿Activar isótopo?"
843
 
844
+ #: includes/admin/metaboxes.php:1032
845
  msgid ""
846
  "Enables or disables isotope/masonry layout support for the main gallery "
847
  "images."
849
  "Activa o desactiva la compatibilidad con el diseño de isótopos / masonry "
850
  "para las imágenes de la galería."
851
 
852
+ #: includes/admin/metaboxes.php:1038
853
  msgid "Enable CSS Animations?"
854
  msgstr "¿Activar animaciones CSS?"
855
 
856
+ #: includes/admin/metaboxes.php:1042
857
  msgid "Enables CSS animations when loading the main gallery images."
858
  msgstr ""
859
  "Activa las animaciones CSS cuando se cargan las imágenes de la galería."
860
 
861
+ #: includes/admin/metaboxes.php:1048
862
  msgid "Image Opacity"
863
  msgstr "Opacidad de imagen"
864
 
865
+ #: includes/admin/metaboxes.php:1052
866
  msgid ""
867
  "The opacity to display images at when loading the main gallery images using "
868
  "CSS animations (between 1 and 100%)."
870
  "Opacidad para visualizar las imágenes cuando se cargan utilizando "
871
  "animaciones CSS (entre 1 y 100%)."
872
 
873
+ #: includes/admin/metaboxes.php:1069
874
+ msgid "Want to do even more with your gallery display?"
875
+ msgstr "¿Quiere hacer aún más con la visualización de sus galerías?"
876
+
877
+ #: includes/admin/metaboxes.php:1070
878
+ msgid ""
879
+ "By upgrading to Envira Pro, you can get access to numerous other gallery "
880
+ "display features, including: custom image tagging and filtering, mobile "
881
+ "specific image assets for blazing fast load times, dedicated and unique "
882
+ "gallery URLs, custom gallery themes, gallery thumbnail support and so much "
883
+ "more!"
884
+ msgstr ""
885
+
886
+ #: includes/admin/metaboxes.php:1092
887
+ msgid "Lightbox Settings"
888
+ msgstr "Opciones de lightbox"
889
+
890
+ #: includes/admin/metaboxes.php:1094
891
  msgid "The settings below adjust the lightbox output."
892
  msgstr "Los ajuste siguientes ajustan la vista en lightbox."
893
 
894
+ #: includes/admin/metaboxes.php:1111 includes/admin/metaboxes.php:1472
895
  msgid "Enable Lightbox?"
896
  msgstr "¿Activar lightbox?"
897
 
898
+ #: includes/admin/metaboxes.php:1115
899
  msgid "Enables or disables the gallery lightbox."
900
  msgstr "Activa o desactiva la galería lightbox."
901
 
902
+ #: includes/admin/metaboxes.php:1126
903
  msgid "Gallery Lightbox Theme"
904
  msgstr "Tema de la galería lightbox"
905
 
906
+ #: includes/admin/metaboxes.php:1134
907
  msgid "Sets the theme for the gallery lightbox display."
908
  msgstr "Establece el tema para la visualización de la galería lightbox."
909
 
910
+ #: includes/admin/metaboxes.php:1148
911
  msgid ""
912
  "Define the maximum image size for the Lightbox view. Default will display "
913
  "the original, full size image."
915
  "Define el tamaño máximo de imagen para la visualización de lightbox. De "
916
  "manera predeterminada mostrará la imagen a tamaño original."
917
 
918
+ #: includes/admin/metaboxes.php:1154
919
  msgid "Caption Position"
920
  msgstr "Posición del pie"
921
 
922
+ #: includes/admin/metaboxes.php:1162
923
  msgid "Sets the display of the lightbox image's caption."
924
  msgstr "Establece la forma de visualizar el pie de la imagen en lightbox. "
925
 
926
+ #: includes/admin/metaboxes.php:1171 includes/admin/metaboxes.php:1499
927
  msgid "Enable Gallery Arrows?"
928
  msgstr "¿Activar las flechas en la galería?"
929
 
930
+ #: includes/admin/metaboxes.php:1175
931
  msgid "Enables or disables the gallery lightbox navigation arrows."
932
  msgstr "Activa o desactiva las flechas de navegación en la galería lightbox."
933
 
934
+ #: includes/admin/metaboxes.php:1180
935
  msgid "Gallery Arrow Position"
936
  msgstr "Posición de la flecha en la galería."
937
 
938
+ #: includes/admin/metaboxes.php:1188
939
  msgid "Sets the position of the gallery lightbox navigation arrows."
940
  msgstr ""
941
  "Establece la posición de las flechas de navegación de la galería lightbox."
942
 
943
+ #: includes/admin/metaboxes.php:1193
944
  msgid "Enable Keyboard Navigation?"
945
  msgstr "¿Activar navegación por teclado?"
946
 
947
+ #: includes/admin/metaboxes.php:1197
948
  msgid "Enables or disables keyboard navigation in the gallery lightbox."
949
  msgstr "Activa o desactiva la navegación por teclado en la galería lightbox."
950
 
951
+ #: includes/admin/metaboxes.php:1202
952
  msgid "Enable Mousewheel Navigation?"
953
  msgstr "¿Activar navegación con la rueda del ratón?"
954
 
955
+ #: includes/admin/metaboxes.php:1206
956
  msgid "Enables or disables mousewheel navigation in the gallery."
957
  msgstr "Activa o desactiva la navegación con la rueda del ratón en la galería."
958
 
959
+ #: includes/admin/metaboxes.php:1211 includes/admin/metaboxes.php:1508
960
  msgid "Enable Gallery Toolbar?"
961
  msgstr "¿Activar la barra de tareas en la galería?"
962
 
963
+ #: includes/admin/metaboxes.php:1215
964
  msgid "Enables or disables the gallery lightbox toolbar."
965
  msgstr "Activa o desactiva la barra de tareas en la galería lightbox."
966
 
967
+ #: includes/admin/metaboxes.php:1220
968
  msgid "Display Gallery Title in Toolbar?"
969
  msgstr "¿Mostrar el título de la galería en la barra de tareas?"
970
 
971
+ #: includes/admin/metaboxes.php:1224
972
  msgid "Display the gallery title in the lightbox toolbar."
973
  msgstr "Muestra el título de la galería en la barra de tareas de lightbox."
974
 
975
+ #: includes/admin/metaboxes.php:1229
976
  msgid "Gallery Toolbar Position"
977
  msgstr "Posición de la barra de tareas en la galería"
978
 
979
+ #: includes/admin/metaboxes.php:1237
980
  msgid "Sets the position of the lightbox toolbar."
981
  msgstr "Establece la posición de la barra de tareas lightbox."
982
 
983
+ #: includes/admin/metaboxes.php:1242
984
  msgid "Keep Aspect Ratio?"
985
  msgstr "¿Mantener relación de aspecto?"
986
 
987
+ #: includes/admin/metaboxes.php:1246
988
  msgid ""
989
  "If enabled, images will always resize based on the original aspect ratio."
990
  msgstr ""
991
  "Si se activa, las imágenes se redimensionarán siempre manteniendo la "
992
  "relación de aspecto."
993
 
994
+ #: includes/admin/metaboxes.php:1251
995
  msgid "Loop Gallery Navigation?"
996
  msgstr "¿Navegación en bucle en la galería?"
997
 
998
+ #: includes/admin/metaboxes.php:1255
999
  msgid ""
1000
  "Enables or disables infinite navigation cycling of the lightbox gallery."
1001
  msgstr ""
1002
  "Activa o desactiva una navegación infinita en bucle de la galería lightbox."
1003
 
1004
+ #: includes/admin/metaboxes.php:1260
1005
  msgid "Lightbox Open/Close Effect"
1006
  msgstr "Abrir / cerrar efectos lightbox"
1007
 
1008
+ #: includes/admin/metaboxes.php:1280
1009
  msgid "Type of transition when opening and closing the lightbox."
1010
  msgstr "Tipo de transición cuando se abre o cierra lightbox."
1011
 
1012
+ #: includes/admin/metaboxes.php:1285
1013
  msgid "Lightbox Transition Effect"
1014
  msgstr "Efectos de transición lightbox"
1015
 
1016
+ #: includes/admin/metaboxes.php:1305
1017
  msgid "Type of transition between images in the lightbox view."
1018
  msgstr "Tipo de transición entre imágenes en la visualización lightbox."
1019
 
1020
+ #: includes/admin/metaboxes.php:1310
1021
  msgid "HTML5 Output?"
1022
  msgstr "¿Salida HTML5?"
1023
 
1024
+ #: includes/admin/metaboxes.php:1314
1025
  msgid ""
1026
  "If enabled, uses data-envirabox-gallery instead of rel attributes for W3C "
1027
  "HTML5 validation."
1029
  "Si se activa, usa data-envirabox-gallery en lugar de atributos relativos "
1030
  "para validación W3C HTML5."
1031
 
1032
+ #: includes/admin/metaboxes.php:1328
1033
  msgid ""
1034
  "The settings below adjust the thumbnail views for the gallery lightbox "
1035
  "display."
1036
  msgstr ""
1037
  "Los ajustes siguientes ajustan las miniaturas para la vista en lightbox."
1038
 
1039
+ #: includes/admin/metaboxes.php:1333 includes/admin/metaboxes.php:1517
1040
  msgid "Enable Gallery Thumbnails?"
1041
  msgstr "¿Activar miniaturas en la galería?"
1042
 
1043
+ #: includes/admin/metaboxes.php:1337
1044
  msgid "Enables or disables the gallery lightbox thumbnails."
1045
  msgstr "Activa o desactiva las miniaturas en la galería lightbox."
1046
 
1047
+ #: includes/admin/metaboxes.php:1342
1048
  msgid "Gallery Thumbnails Width"
1049
  msgstr "Ancho de miniaturas de la galería"
1050
 
1051
+ #: includes/admin/metaboxes.php:1346
1052
  msgid "Sets the width of each lightbox thumbnail."
1053
  msgstr "Establece el ancho de cada miniatura lightbox."
1054
 
1055
+ #: includes/admin/metaboxes.php:1351
1056
  msgid "Gallery Thumbnails Height"
1057
  msgstr "Alto de miniaturas de la galería"
1058
 
1059
+ #: includes/admin/metaboxes.php:1355
1060
  msgid "Sets the height of each lightbox thumbnail."
1061
  msgstr "Establece la altura de cada miniatura lightbox."
1062
 
1063
+ #: includes/admin/metaboxes.php:1360
1064
  msgid "Gallery Thumbnails Position"
1065
  msgstr "Posición de miniaturas de lightbox"
1066
 
1067
+ #: includes/admin/metaboxes.php:1368
1068
  msgid "Sets the position of the lightbox thumbnails."
1069
  msgstr "Establece la posición de las miniaturas lightbox."
1070
 
1071
+ #: includes/admin/metaboxes.php:1385
1072
+ msgid "Want even more fine tuned control over your lightbox display?"
1073
+ msgstr "¿Quiere tener un control aún más fino sobre su visualización lightbox?"
1074
 
1075
+ #: includes/admin/metaboxes.php:1386
1076
+ msgid ""
1077
+ "By upgrading to Envira Pro, you can get access to numerous other lightbox "
1078
+ "features, including: custom lightbox titles, enable/disable lightbox "
1079
+ "controls (arrow, keyboard and mousehweel navigation), custom lightbox "
1080
+ "transition effects, native fullscreen support, gallery deeplinking, image "
1081
+ "protection, lightbox supersize effects, lightbox slideshows and so much more!"
1082
+ msgstr ""
1083
+
1084
+ #: includes/admin/metaboxes.php:1408
1085
+ msgid "Mobile Gallery Settings"
1086
+ msgstr "Opciones de la galería en moviles"
1087
+
1088
+ #: includes/admin/metaboxes.php:1410
1089
  msgid ""
1090
  "The settings below adjust configuration options for the Gallery when viewed "
1091
  "on a mobile device."
1093
  "Los siguientes ajustes configuran las opciones de la galería cuando se ven "
1094
  "en un dispositivo móvil."
1095
 
1096
+ #: includes/admin/metaboxes.php:1433
1097
  msgid ""
1098
  "Determines the number of columns in the gallery on mobile devices. Automatic "
1099
  "will attempt to fill each row as much as possible before moving on to the "
1103
  "Automático, intentará rellenar cualquier fila todo lo posible antes de pasar "
1104
  "a la siguiente fila."
1105
 
1106
+ #: includes/admin/metaboxes.php:1439
1107
  msgid "Create Mobile Gallery Images?"
1108
  msgstr "¿Crear galería de imágenes para móvil?"
1109
 
1110
+ #: includes/admin/metaboxes.php:1443
1111
  msgid "Enables or disables creating specific images for mobile devices."
1112
  msgstr "Activa o desactiva la creación de imágenes especificas para móvil."
1113
 
1114
+ #: includes/admin/metaboxes.php:1449
1115
  msgid "Mobile Dimensions"
1116
  msgstr "Dimensiones para móvil"
1117
 
1118
+ #: includes/admin/metaboxes.php:1453
1119
  msgid "These will be the sizes used for images displayed on mobile devices."
1120
  msgstr ""
1121
  "Estos serán los tamaños utilizados para las imágenes que aparecen en "
1122
  "dispositivos móviles."
1123
 
1124
+ #: includes/admin/metaboxes.php:1463
1125
+ msgid "Mobile Lightbox Settings"
1126
+ msgstr "Opciones de lightbox en moviles."
1127
 
1128
+ #: includes/admin/metaboxes.php:1465
1129
  msgid ""
1130
  "The settings below adjust configuration options for the Lightbox when viewed "
1131
  "on a mobile device."
1133
  "Los siguientes ajustes configuran las opciones de lightbox cuando se ven en "
1134
  "un dispositivo móvil."
1135
 
1136
+ #: includes/admin/metaboxes.php:1476
1137
  msgid "Enables or disables the gallery lightbox on mobile devices."
1138
  msgstr "Activa o desactiva la galería lightbox en dispositivos móviles."
1139
 
1140
+ #: includes/admin/metaboxes.php:1481
1141
  msgid "Enable Gallery Touchwipe?"
1142
  msgstr "¿Activar Touchwipe en la galería?"
1143
 
1144
+ #: includes/admin/metaboxes.php:1485
1145
  msgid ""
1146
  "Enables or disables touchwipe support for the gallery lightbox on mobile "
1147
  "devices."
1149
  "Activa o desactiva las funciones touchwipe para la galería lightbox en "
1150
  "dispositivos móviles."
1151
 
1152
+ #: includes/admin/metaboxes.php:1490
1153
  msgid "Close Lightbox on Swipe Up?"
1154
  msgstr "Cerrar Lightbox deslizando el dedo hacia arriba?"
1155
 
1156
+ #: includes/admin/metaboxes.php:1494
1157
  msgid ""
1158
  "Enables or disables closing the Lightbox when the user swipes up on mobile "
1159
  "devices."
1161
  "Activa o desactiva el cierre de Lightbox cuando el usuario desliza el dedo "
1162
  "hacia arriba en los dispositivos móviles."
1163
 
1164
+ #: includes/admin/metaboxes.php:1503
1165
  msgid ""
1166
  "Enables or disables the gallery lightbox navigation arrows on mobile devices."
1167
  msgstr ""
1168
  "Activa o desactiva las flechas de navegación de la galería lightbox en "
1169
  "dispositivos móviles."
1170
 
1171
+ #: includes/admin/metaboxes.php:1512
1172
  msgid "Enables or disables the gallery lightbox toolbar on mobile devices."
1173
  msgstr ""
1174
  "Activa o desactiva la barra de herramientas de la galería lightbox en "
1175
  "dispositivos móviles."
1176
 
1177
+ #: includes/admin/metaboxes.php:1521
1178
  msgid "Enables or disables the gallery lightbox thumbnails on mobile devices."
1179
  msgstr ""
1180
  "Activa o desactiva las miniaturas de la galería lightbox en dispositivos "
1181
  "móviles."
1182
 
1183
+ #: includes/admin/metaboxes.php:1545
1184
+ msgid "Miscellaneous Settings"
1185
+ msgstr "Otros ajustes"
1186
+
1187
+ #: includes/admin/metaboxes.php:1547
1188
+ msgid "The settings below adjust miscellaneous options for the Gallery."
1189
  msgstr "Los ajustes siguientes configuran diversos ajustes para la galería."
1190
 
1191
+ #: includes/admin/metaboxes.php:1563
1192
  msgid "Gallery Title"
1193
  msgstr "Título de la galería"
1194
 
1195
+ #: includes/admin/metaboxes.php:1567
1196
  msgid "Internal gallery title for identification in the admin."
1197
  msgstr ""
1198
  "Título interno de la galería para su identificación en la administración"
1199
 
1200
+ #: includes/admin/metaboxes.php:1572
1201
  msgid "Gallery Slug"
1202
  msgstr "Slug de la galería"
1203
 
1204
+ #: includes/admin/metaboxes.php:1576
1205
  msgid ""
1206
  "<strong>Unique</strong> internal gallery slug for identification and "
1207
  "advanced gallery queries."
1209
  "Slug interno <strong>único</strong> de la galería para la identificación y "
1210
  "consultas avanzadas."
1211
 
1212
+ #: includes/admin/metaboxes.php:1581
1213
  msgid "Custom Gallery Classes"
1214
  msgstr "Clases personalizadas de la galería"
1215
 
1216
+ #: includes/admin/metaboxes.php:1584
1217
  msgid "Enter custom gallery CSS classes here, one per line."
1218
  msgstr "Introduzca aquí, clases CSS personalizadas, una por línea."
1219
 
1220
+ #: includes/admin/metaboxes.php:1585
1221
  msgid "Adds custom CSS classes to this gallery. Enter one class per line."
1222
  msgstr "Añade clases CSS personalizadas en la galería, una por línea."
1223
 
1224
+ #: includes/admin/metaboxes.php:1594
1225
  msgid "Import/Export Gallery"
1226
  msgstr "Importar / Exportar galería"
1227
 
1228
+ #: includes/admin/metaboxes.php:1607
1229
  msgid "Import Gallery"
1230
  msgstr "Importar galería"
1231
 
1232
+ #: includes/admin/metaboxes.php:1614
1233
  msgid "Export Gallery"
1234
  msgstr "Exportar galería"
1235
 
1236
+ #: includes/admin/metaboxes.php:1624
1237
  msgid "Enable RTL Support?"
1238
  msgstr "¿Activar funciones RTL?"
1239
 
1240
+ #: includes/admin/metaboxes.php:1628
1241
  msgid "Enables or disables RTL support in Envira for right-to-left languages."
1242
  msgstr ""
1243
  "Activa o desactiva funciones RTL en Envira para idiomas que se escriben de "
1244
  "derecha a izquierda."
1245
 
1246
+ #: includes/admin/metaboxes.php:1640 includes/admin/metaboxes.php:1682
1247
+ #: includes/admin/metaboxes.php:1704 includes/admin/metaboxes.php:1726
1248
+ #: includes/admin/metaboxes.php:1748 includes/admin/metaboxes.php:1770
1249
+ msgid "Want to take your galleries further?"
1250
+ msgstr "¿Quiere mejorar aún más sus galerías?"
1251
+
1252
+ #: includes/admin/metaboxes.php:1641
1253
+ msgid ""
1254
+ "By upgrading to Envira Pro, you can get access to numerous other features, "
1255
+ "including: a fully-integrated import/export module for your galleries, "
1256
+ "custom CSS controls for each gallery and so much more!"
1257
+ msgstr ""
1258
+ "Mediante la actualización a Envira Pro puede obtener acceso a otras muchas "
1259
+ "características, incluyendo: un módulo totalmente integrado de importación / "
1260
+ "exportación para sus galerías, controles CSS personalizados para cada "
1261
+ "galería y mucho más."
1262
+
1263
+ #: includes/admin/metaboxes.php:1662
1264
  msgid "Videos"
1265
  msgstr "Videos"
1266
 
1267
+ #: includes/admin/metaboxes.php:1663
1268
  msgid "Social"
1269
  msgstr "Social"
1270
 
1271
+ #: includes/admin/metaboxes.php:1664
1272
  msgid "Tags"
1273
  msgstr "Etiquetas"
1274
 
1275
+ #: includes/admin/metaboxes.php:1665
1276
  msgid "Pagination"
1277
  msgstr "Paginación"
1278
 
1279
+ #: includes/admin/metaboxes.php:1683
 
 
 
 
 
 
1280
  msgid ""
1281
  "By upgrading to Envira Pro, you can get access to mobile-specific settings, "
1282
  "including mobile image sizes, number of columns, mobile-specific lightbox "
1287
  "moviles, número de columnas, opciones específicas para móviles en lighbox y "
1288
  "mucho más."
1289
 
1290
+ #: includes/admin/metaboxes.php:1705
 
 
 
 
 
 
1291
  msgid ""
1292
  "By upgrading to Envira Pro, you can add Videos to your Envira Galleries from "
1293
  "YouTube, Vimeo, Wistia, and your own self-hosted videos!"
1295
  "Mediante la actualización a Envira Pro, puede añadir videos a sus galerías "
1296
  "Envira desde YouTube, Vimeo, Wistia, y vídeos alojados en su propio servidor."
1297
 
1298
+ #: includes/admin/metaboxes.php:1727
1299
  msgid ""
1300
  "By upgrading to Envira Pro, you can add social sharing buttons to your "
1301
  "Gallery images and Lightbox images. With support for Facebook, Twitter, "
1306
  "soporte para Facebook, Twitter, Google+ y Pinterest. ¿Por qué no echarle un "
1307
  "vistazo?"
1308
 
1309
+ #: includes/admin/metaboxes.php:1749
1310
  msgid ""
1311
  "By upgrading to Envira Pro, you can add Tags to your Gallery images, allow "
1312
  "users to filter your Gallery by tag and so much more!"
1315
  "imágenes de la Galería, permitir a los usuarios filtrar la galería por "
1316
  "etiquetas y mucho más."
1317
 
1318
+ #: includes/admin/metaboxes.php:1771
1319
  msgid ""
1320
  "By upgrading to Envira Pro, you can split your Gallery across multiple pages "
1321
  "with pagination, load paginated images via AJAX, lazy loading and more!"
1324
  "múltiples páginas con paginación, cargar imágenes paginadas mediante AJAX, "
1325
  "lazy loading y mucho más."
1326
 
1327
+ #: includes/admin/metaboxes.php:2048
1328
  msgid "Remove Image from Gallery?"
1329
  msgstr "¿Quitar imagen de la galería?"
1330
 
1331
+ #: includes/admin/metaboxes.php:2049
1332
  msgid "Modify Image"
1333
  msgstr "Modificar imagen"
1334
 
1347
 
1348
  #: includes/admin/partials/metabox-gallery-code.php:14
1349
  #: includes/admin/partials/metabox-gallery-code.php:24
1350
+ #: includes/admin/table.php:228
1351
  msgid "Copy Shortcode to Clipboard"
1352
  msgstr "Copiar el código corto al portapapeles"
1353
 
1355
  #: includes/admin/partials/metabox-gallery-code.php:25
1356
  #: includes/admin/partials/metabox-gallery-code.php:36
1357
  #: includes/admin/partials/metabox-gallery-code.php:46
1358
+ #: includes/admin/table.php:229
1359
  msgid "Copy to Clipboard"
1360
  msgstr "Copiar al portapapeles"
1361
 
1381
  msgid "External Gallery"
1382
  msgstr "galería externa"
1383
 
1384
+ #: includes/admin/partials/metabox-gallery-type.php:46
1385
  msgid "Select Your Service"
1386
  msgstr "Seleccione su servicio"
1387
 
1388
+ #: includes/admin/partials/metabox-gallery-type.php:75
1389
+ msgid "Create Dynamic Galleries with Envira"
1390
+ msgstr ""
1391
+
1392
+ #: includes/admin/partials/metabox-gallery-type.php:78
1393
+ msgid "Build Galleries from Instagram images."
1394
+ msgstr ""
1395
+
1396
+ #: includes/admin/partials/metabox-gallery-type.php:80
1397
+ msgid "Instagram"
1398
+ msgstr "Instagram"
1399
+
1400
+ #: includes/admin/partials/metabox-gallery-type.php:85
1401
+ msgid ""
1402
+ "Envira Pro allows you to build galleries from Instagram photos, images from "
1403
+ "your posts, and more."
1404
+ msgstr ""
1405
+
1406
+ #: includes/admin/partials/metabox-gallery-type.php:88
1407
+ #: includes/admin/partials/metabox-gallery-type.php:89
1408
+ msgid "Click Here to Upgrade"
1409
+ msgstr "Haga clic aquí para actualizar."
1410
+
1411
+ #: includes/admin/partials/metabox-gallery-type.php:95
1412
  msgid ""
1413
  "It doesn't look like you have any Addons activated which import images from "
1414
  "external sources."
1456
  msgid "Envira gallery draft updated."
1457
  msgstr "Borrador de galería Envira actualizado."
1458
 
1459
+ #: includes/admin/settings.php:83 includes/admin/settings.php:663
1460
  msgid "Settings"
1461
  msgstr "Ajustes"
1462
 
1463
+ #: includes/admin/settings.php:228
1464
  msgid " galleries(s) fixed successfully."
1465
  msgstr "Galería(s) reparada(s) satisfactoriamente."
1466
 
1467
+ #: includes/admin/settings.php:362
1468
  msgid "Settings saved successfully."
1469
  msgstr "Ajustes guardados satisfactoriamente."
1470
 
1471
+ #: includes/admin/settings.php:494
1472
  msgid "General"
1473
  msgstr "General"
1474
 
1475
+ #: includes/admin/settings.php:524
1476
  msgid "Envira License Key"
1477
  msgstr "Clave de licencia de Envira"
1478
 
1479
+ #: includes/admin/settings.php:530
1480
  msgid "Verify Key"
1481
  msgstr "Comprobar clave"
1482
 
1483
+ #: includes/admin/settings.php:531
1484
  msgid "Deactivate Key"
1485
  msgstr "Desactivar clave"
1486
 
1487
+ #: includes/admin/settings.php:532
1488
  msgid "License key to enable automatic updates for Envira."
1489
  msgstr ""
1490
  "Clave de licencia para activar las actualizaciones automáticas para Envira."
1491
 
1492
+ #: includes/admin/settings.php:539
1493
  msgid "Envira License Key Type"
1494
  msgstr "Tipo de licencia Envira."
1495
 
1496
+ #: includes/admin/settings.php:543
1497
  msgid "Your license key type for this site is <strong>%s.</strong>"
1498
  msgstr "Su tipo de licencia para este sitio es <strong>%s.</strong>"
1499
 
1500
+ #: includes/admin/settings.php:546
1501
  msgid "Refresh Key"
1502
  msgstr "Actualizar clave"
1503
 
1504
+ #: includes/admin/settings.php:547
1505
  msgid ""
1506
  "Your license key type (handles updates and Addons). Click refresh if your "
1507
  "license has been upgraded or the type is incorrect."
1510
  "clic en actualizar si ha actualizado su tipo de licencia o el tipo es "
1511
  "incorrecto."
1512
 
1513
+ #: includes/admin/settings.php:556
1514
  msgid "Fix Broken Migration"
1515
  msgstr "Solucionar migración rota"
1516
 
1517
+ #: includes/admin/settings.php:561
1518
  msgid "Fix"
1519
  msgstr "Solucionar"
1520
 
1521
+ #: includes/admin/settings.php:562
1522
  msgid ""
1523
  "If you have changed the URL of your WordPress web site, and manually "
1524
  "executed a search/replace query on URLs in your WordPress database, your "
1532
  "es el caso, haga clic en el botón de arriba para solucionar este problema. "
1533
  "Le recomendamos que use un plugin o script de migración la próxima vez :)"
1534
 
1535
+ #: includes/admin/settings.php:578
1536
  msgid "Add New Images"
1537
  msgstr "Añadir nuevas imágenes"
1538
 
1539
+ #: includes/admin/settings.php:586
1540
  msgid ""
1541
  "When adding media to a Gallery, choose whether to add this media before or "
1542
  "after any existing images."
1544
  "Si añade medios a una Galería, elija si desea añadir este medio antes o "
1545
  "después de las imágenes existentes."
1546
 
1547
+ #: includes/admin/settings.php:593
1548
  msgid "Delete Image on Gallery Image Deletion"
1549
  msgstr "Elimina la imagen cuando se borra de una galería"
1550
 
1551
+ #: includes/admin/settings.php:601
1552
  msgid ""
1553
  "When deleting an Image from a Gallery, choose whether to delete all media "
1554
  "associated with that image. Note: If image(s) in the Media Library are "
1558
  "asociados con esa imagen. Nota: Si la imagen(es) en la biblioteca multimedia "
1559
  "está(n) vinculada(s) a otras entradas, no se borrarán."
1560
 
1561
+ #: includes/admin/settings.php:607
1562
  msgid "Delete Images on Gallery Deletion"
1563
  msgstr "Elimina las imágenes cuando se borra una galería"
1564
 
1565
+ #: includes/admin/settings.php:615
1566
  msgid ""
1567
  "When deleting a Gallery, choose whether to delete all media associated with "
1568
  "the gallery. Note: If image(s) in the Media Library are attached to other "
1572
  "la galería. Nota: Si la imagen(es) en la biblioteca multimedia está(n) "
1573
  "vinculada(s) a otras entradas, no se borrarán."
1574
 
1575
+ #: includes/admin/settings.php:624
1576
  msgid "Save Settings"
1577
  msgstr "Guardar ajustes"
1578
 
1581
  msgstr ""
1582
  "Hubo un error al instalar el complemento. Por favor, vuelva a intentarlo."
1583
 
1584
+ #: includes/admin/table.php:169
1585
  msgid "Shortcode"
1586
  msgstr "Código corto"
1587
 
1588
+ #: includes/admin/table.php:170
1589
  msgid "Posts"
1590
  msgstr "Entradas"
1591
 
1592
+ #: includes/admin/table.php:171
1593
  msgid "Last Modified"
1594
  msgstr "última modificada"
1595
 
1596
+ #: includes/admin/table.php:172
1597
  msgid "Date"
1598
  msgstr "Fecha"
1599
 
1600
+ #: includes/admin/table.php:217
1601
  msgid "%d Image"
1602
  msgid_plural "%d Images"
1603
  msgstr[0] "%d Imagen"
1604
  msgstr[1] "%d Imagenes"
1605
 
1606
+ #: includes/admin/table.php:296 includes/admin/table.php:371
1607
  msgid "Number of Columns"
1608
  msgstr "Número de columnas"
1609
 
1610
+ #: includes/admin/table.php:373 includes/admin/table.php:384
1611
+ #: includes/admin/table.php:394 includes/admin/table.php:399
1612
+ #: includes/admin/table.php:404 includes/admin/table.php:406
1613
  msgid "— No Change —"
1614
  msgstr "— Sin cambios —"
1615
 
1765
  msgid "Bottom"
1766
  msgstr "Abajo"
1767
 
1768
+ #: includes/global/common.php:649
1769
  msgid "Image Files"
1770
  msgstr "Archivos de imagen"
1771
 
1772
+ #: includes/global/common.php:699
1773
  msgid "Before Existing Images"
1774
  msgstr "Antes de las imágenes existentes"
1775
 
1776
+ #: includes/global/common.php:703
1777
  msgid "After Existing Images"
1778
  msgstr "Después de las imágenes existentes"
1779
 
1780
+ #: includes/global/common.php:727
1781
  msgid "Yes"
1782
  msgstr "Si"
1783
 
1784
+ #: includes/global/common.php:795
1785
  msgid ""
1786
  "No image editor could be selected. Please verify with your webhost that you "
1787
  "have either the GD or Imagick image library compiled with your PHP install "
1791
  "su servicio de hosting que tiene compilada en su instalación PHP de su "
1792
  "servidor una biblioteca de imágenes, ya sea GD o Imagick."
1793
 
1794
+ #: includes/global/common.php:898
1795
  msgid "No image URL specified for cropping."
1796
  msgstr "No sé ha especificado ninguna URL de imagen para recortar."
1797
 
1798
+ #: includes/global/common.php:917
1799
  msgid "No file could be found for the image URL specified."
1800
  msgstr "No se pudo encontrar el archivo de la URL de imagen especificada."
1801
 
1802
+ #: includes/global/common.php:925 includes/global/common.php:937
1803
  msgid ""
1804
  "The dimensions of the original image could not be retrieved for cropping."
1805
  msgstr ""
1841
  msgid "No Envira galleries found in trash."
1842
  msgstr "No se han encontrado galerías Envira en la papelera."
1843
 
1844
+ #: includes/global/shortcode.php:800
1845
  msgid "The requested content cannot be loaded.<br/>Please try again later.</p>"
1846
  msgstr ""
1847
  "El contenido solicitado no se puede cargar. <br/> Por favor, inténtelo de "
1848
  "nuevo más tarde. </ P>"
1849
 
1850
+ #: includes/global/shortcode.php:801 includes/global/shortcode.php:1360
1851
  msgid "Close"
1852
  msgstr "Cerrar"
1853
 
1854
+ #: includes/global/shortcode.php:802 includes/global/shortcode.php:1350
1855
  msgid "Next"
1856
  msgstr "Siguiente"
1857
 
1858
+ #: includes/global/shortcode.php:803 includes/global/shortcode.php:1346
1859
  msgid "Previous"
1860
  msgstr "Anterior"
1861
 
1871
  msgid "Gallery ID #%s"
1872
  msgstr "ID de galería #%s"
1873
 
1874
+ #. Plugin Name of the plugin/theme
1875
+ msgid "Envira Gallery Lite"
1876
+ msgstr "Envira Gallery Lite"
1877
+
1878
  #. Plugin URI of the plugin/theme
1879
+ #. Author URI of the plugin/theme
1880
  msgid "http://enviragallery.com"
1881
  msgstr "http://enviragallery.com"
1882
 
1883
  #. Description of the plugin/theme
1884
+ msgid ""
1885
+ "Envira Gallery is best responsive WordPress gallery plugin. This is the lite "
1886
+ "version."
1887
  msgstr ""
1888
  "Envira Gallery is el mejor plugin de galería de Wordpress de diseño "
1889
+ "adaptable. Está es la versión lite."
1890
 
1891
  #. Author of the plugin/theme
1892
  msgid "Thomas Griffin"
1893
  msgstr "Thomas Griffin"
1894
 
1895
+ #~ msgid ""
1896
+ #~ "In order to get access to Addons, you need to verify your license key for "
1897
+ #~ "Envira Gallery."
1898
+ #~ msgstr ""
1899
+ #~ "Para tener acceso a Complementos, es necesario verificar su clave de "
1900
+ #~ "licencia de Envira Gallery."
1901
+
1902
+ #~ msgid ""
1903
+ #~ "<strong>Missing addons that you think you should be able to see?</strong> "
1904
+ #~ "Try clicking the button below to refresh the addon data."
1905
+ #~ msgstr ""
1906
+ #~ "<strong>¿Faltan complementos que piensa que debería poder ver?</strong> "
1907
+ #~ "Intente hacer clic en el botón de abajo para actualizar la información "
1908
+ #~ "sobre los complementos."
1909
+
1910
+ #~ msgid "Search Results"
1911
+ #~ msgstr "Resultados de búsqueda"
1912
+
1913
+ #~ msgid "No add-ons were found with those search terms."
1914
+ #~ msgstr "No se han encontrado complementos con estos términos de búsqueda."
1915
+
1916
+ #~ msgid "Gallery Options"
1917
+ #~ msgstr "Opciones de la galería."
1918
+
1919
+ #~ msgid "http://thomasgriffinmedia.com"
1920
+ #~ msgstr "http://thomasgriffinmedia.com"
1921
 
1922
  #~ msgid "Choose Your Gallery"
1923
  #~ msgstr "Seleccione su galería"
languages/envira-gallery.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the Envira Gallery Lite package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Envira Gallery Lite 1.5.0.8\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/envira-gallery\n"
7
- "POT-Creation-Date: 2016-08-04 19:21:08+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -215,153 +215,153 @@ msgstr ""
215
  msgid "Your license key for Envira Gallery is invalid. The key no longer exists or the user associated with the key has been deleted. Please use a different key to continue receiving automatic updates."
216
  msgstr ""
217
 
218
- #: includes/admin/media-view.php:101 includes/admin/media-view.php:102
219
- #: includes/admin/media-view.php:504 includes/admin/media-view.php:505
220
  msgid "Search"
221
  msgstr ""
222
 
223
- #: includes/admin/media-view.php:154 includes/admin/media-view.php:481
224
  msgid "Helpful Tips"
225
  msgstr ""
226
 
227
- #: includes/admin/media-view.php:155
228
  msgid "Choosing Your Gallery"
229
  msgstr ""
230
 
231
- #: includes/admin/media-view.php:157
232
  msgid "To choose your gallery, simply click on one of the boxes to the left. Ctrl / cmd and click to select multiple Galleries. The \"Insert Gallery\" button will be activated once you have selected a gallery."
233
  msgstr ""
234
 
235
- #: includes/admin/media-view.php:159
236
  msgid "Inserting Your Gallery"
237
  msgstr ""
238
 
239
- #: includes/admin/media-view.php:161
240
  msgid "To insert your gallery into the editor, click on the \"Insert Gallery\" button below."
241
  msgstr ""
242
 
243
- #: includes/admin/media-view.php:165
244
  msgid "Insert Options"
245
  msgstr ""
246
 
247
- #: includes/admin/media-view.php:169
248
  msgid "Display Title"
249
  msgstr ""
250
 
251
- #: includes/admin/media-view.php:171 includes/global/common.php:723
252
  msgid "No"
253
  msgstr ""
254
 
255
- #: includes/admin/media-view.php:175
256
  msgid "Yes, as Heading H%s"
257
  msgstr ""
258
 
259
- #: includes/admin/media-view.php:182
260
  msgid "Prepends each inserted Gallery with the Gallery Title."
261
  msgstr ""
262
 
263
- #: includes/admin/media-view.php:216
264
  msgid "Edit previous media item"
265
  msgstr ""
266
 
267
- #: includes/admin/media-view.php:217
268
  msgid "Edit next media item"
269
  msgstr ""
270
 
271
- #: includes/admin/media-view.php:220
272
  msgid "Edit Metadata"
273
  msgstr ""
274
 
275
- #: includes/admin/media-view.php:240 includes/admin/media-view.php:374
276
- #: includes/admin/table.php:167 includes/global/common.php:171
277
  #: includes/global/widget.php:153
278
  msgid "Title"
279
  msgstr ""
280
 
281
- #: includes/admin/media-view.php:243 includes/admin/media-view.php:377
282
  msgid "Image titles can take any type of HTML. You can adjust the position of the titles in the main Lightbox settings."
283
  msgstr ""
284
 
285
- #: includes/admin/media-view.php:252 includes/admin/media-view.php:383
286
- #: includes/global/common.php:175
287
  msgid "Caption"
288
  msgstr ""
289
 
290
- #: includes/admin/media-view.php:266 includes/admin/media-view.php:397
291
  msgid "Captions can take any type of HTML, and are displayed when an image is clicked."
292
  msgstr ""
293
 
294
- #: includes/admin/media-view.php:275 includes/admin/media-view.php:403
295
  msgid "Alt Text"
296
  msgstr ""
297
 
298
- #: includes/admin/media-view.php:278 includes/admin/media-view.php:406
299
  msgid "Very important for SEO, the Alt Text describes the image."
300
  msgstr ""
301
 
302
- #: includes/admin/media-view.php:284 includes/admin/media-view.php:412
303
- #: includes/global/common.php:183
304
  msgid "URL"
305
  msgstr ""
306
 
307
- #: includes/admin/media-view.php:288 includes/admin/media-view.php:416
308
  msgid "Media File"
309
  msgstr ""
310
 
311
- #: includes/admin/media-view.php:289 includes/admin/media-view.php:417
312
  msgid "Attachment Page"
313
  msgstr ""
314
 
315
- #: includes/admin/media-view.php:293 includes/admin/media-view.php:421
316
  msgid "Enter a hyperlink if you wish to link this image to somewhere other than its full size image."
317
  msgstr ""
318
 
319
- #: includes/admin/media-view.php:302 includes/admin/media-view.php:427
320
  msgid "Open URL in New Window?"
321
  msgstr ""
322
 
323
- #: includes/admin/media-view.php:305 includes/admin/media-view.php:430
324
  msgid "Opens your image links in a new browser window / tab."
325
  msgstr ""
326
 
327
- #: includes/admin/media-view.php:316
328
  msgid "Want Captions and more options?"
329
  msgstr ""
330
 
331
- #: includes/admin/media-view.php:317
332
  msgid "By upgrading to Envira Pro, you can get access to numerous other features, including: HTML captions, open links in new windows, WooCommerce product integration and so much more!"
333
  msgstr ""
334
 
335
- #: includes/admin/media-view.php:319 includes/admin/metaboxes.php:776
336
- #: includes/admin/metaboxes.php:1072 includes/admin/metaboxes.php:1388
337
- #: includes/admin/metaboxes.php:1643 includes/admin/metaboxes.php:1685
338
- #: includes/admin/metaboxes.php:1707 includes/admin/metaboxes.php:1729
339
- #: includes/admin/metaboxes.php:1751 includes/admin/metaboxes.php:1773
340
  msgid "Click here to Upgrade"
341
  msgstr ""
342
 
343
- #: includes/admin/media-view.php:336 includes/admin/media-view.php:337
344
- #: includes/admin/media-view.php:442
345
  msgid "Save Metadata"
346
  msgstr ""
347
 
348
- #: includes/admin/media-view.php:343 includes/admin/media-view.php:448
349
  msgid "Saved."
350
  msgstr ""
351
 
352
- #: includes/admin/media-view.php:358
353
  msgid "Bulk Edit"
354
  msgstr ""
355
 
356
- #: includes/admin/media-view.php:441
357
  msgid "Save Metadata to Items"
358
  msgstr ""
359
 
360
- #: includes/admin/media-view.php:483
361
  msgid "Select the Gallery to move the selected images to by clicking on one of the boxes to the left."
362
  msgstr ""
363
 
364
- #: includes/admin/media-view.php:486
365
  msgid "Once done, click the Move button, and the selected images will be moved to the chosen Gallery."
366
  msgstr ""
367
 
@@ -447,7 +447,7 @@ msgstr ""
447
  msgid "Envira Gallery Code"
448
  msgstr ""
449
 
450
- #: includes/admin/metaboxes.php:586 includes/global/common.php:253
451
  msgid "Default"
452
  msgstr ""
453
 
@@ -463,7 +463,7 @@ msgstr ""
463
  msgid "Lightbox"
464
  msgstr ""
465
 
466
- #: includes/admin/metaboxes.php:606 includes/admin/metaboxes.php:1661
467
  msgid "Mobile"
468
  msgstr ""
469
 
@@ -476,20 +476,20 @@ msgid "Currently in your Gallery"
476
  msgstr ""
477
 
478
  #: includes/admin/metaboxes.php:707 includes/admin/metaboxes.php:800
479
- #: includes/admin/metaboxes.php:1096 includes/admin/metaboxes.php:1411
480
- #: includes/admin/metaboxes.php:1549
481
  msgid "Need some help?"
482
  msgstr ""
483
 
484
  #: includes/admin/metaboxes.php:709 includes/admin/metaboxes.php:802
485
- #: includes/admin/metaboxes.php:1098 includes/admin/metaboxes.php:1413
486
- #: includes/admin/metaboxes.php:1551
487
  msgid "Read the Documentation"
488
  msgstr ""
489
 
490
  #: includes/admin/metaboxes.php:713 includes/admin/metaboxes.php:806
491
- #: includes/admin/metaboxes.php:1102 includes/admin/metaboxes.php:1417
492
- #: includes/admin/metaboxes.php:1555
493
  msgid "Watch a Video"
494
  msgstr ""
495
 
@@ -533,7 +533,7 @@ msgstr ""
533
  msgid "The settings below adjust the basic configuration options for the gallery."
534
  msgstr ""
535
 
536
- #: includes/admin/metaboxes.php:814 includes/admin/metaboxes.php:1425
537
  msgid "Number of Gallery Columns"
538
  msgstr ""
539
 
@@ -541,495 +541,508 @@ msgstr ""
541
  msgid "Determines the number of columns in the gallery. Automatic will attempt to fill each row as much as possible before moving on to the next row."
542
  msgstr ""
543
 
544
- #: includes/admin/metaboxes.php:827 includes/admin/table.php:305
545
- #: includes/admin/table.php:382
546
- msgid "Gallery Theme"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
547
  msgstr ""
548
 
549
- #: includes/admin/metaboxes.php:835
550
  msgid "Sets the theme for the gallery display."
551
  msgstr ""
552
 
553
- #: includes/admin/metaboxes.php:845
554
  msgid "Display Gallery Description?"
555
  msgstr ""
556
 
557
- #: includes/admin/metaboxes.php:857
558
  msgid "Choose to display a description above or below this gallery's images."
559
  msgstr ""
560
 
561
- #: includes/admin/metaboxes.php:864
562
  msgid "Gallery Description"
563
  msgstr ""
564
 
565
- #: includes/admin/metaboxes.php:879
566
  msgid "The description to display for this gallery."
567
  msgstr ""
568
 
569
- #: includes/admin/metaboxes.php:888 includes/admin/table.php:314
570
- #: includes/admin/table.php:393
571
- msgid "Column Gutter Width"
572
  msgstr ""
573
 
574
- #: includes/admin/metaboxes.php:891 includes/admin/metaboxes.php:900
575
- #: includes/admin/metaboxes.php:998 includes/admin/metaboxes.php:1345
576
- #: includes/admin/metaboxes.php:1354 includes/admin/metaboxes.php:1452
577
- msgid "px"
578
  msgstr ""
579
 
580
- #: includes/admin/metaboxes.php:892
581
  msgid "Sets the space between the columns (defaults to 10)."
582
  msgstr ""
583
 
584
- #: includes/admin/metaboxes.php:897 includes/admin/table.php:319
585
  #: includes/admin/table.php:398
586
  msgid "Margin Below Each Image"
587
  msgstr ""
588
 
589
- #: includes/admin/metaboxes.php:901
590
  msgid "Sets the space below each item in the gallery."
591
  msgstr ""
592
 
593
- #: includes/admin/metaboxes.php:911
594
  msgid "Sorting"
595
  msgstr ""
596
 
597
- #: includes/admin/metaboxes.php:923
598
  msgid "Choose to sort the images in a different order than displayed on the Images tab."
599
  msgstr ""
600
 
601
- #: includes/admin/metaboxes.php:928
602
  msgid "Direction"
603
  msgstr ""
604
 
605
- #: includes/admin/metaboxes.php:949 includes/admin/metaboxes.php:1140
606
  msgid "Image Size"
607
  msgstr ""
608
 
609
- #: includes/admin/metaboxes.php:961
610
  msgid "Define the maximum image size for the Gallery view. Default will use the below Image Dimensions; Random will allow you to choose one or more WordPress image sizes, which will be used for the gallery output."
611
  msgstr ""
612
 
613
- #: includes/admin/metaboxes.php:970
614
  msgid "Random Image Sizes"
615
  msgstr ""
616
 
617
- #: includes/admin/metaboxes.php:986
618
  msgid "Define the WordPress registered image sizes to include when randomly assigning an image size to each image in your Gallery."
619
  msgstr ""
620
 
621
- #: includes/admin/metaboxes.php:995 includes/admin/table.php:325
622
  #: includes/admin/table.php:403
623
  msgid "Image Dimensions"
624
  msgstr ""
625
 
626
- #: includes/admin/metaboxes.php:999
627
  msgid "You should adjust these dimensions based on the number of columns in your gallery. This does not affect the full size lightbox images."
628
  msgstr ""
629
 
630
- #: includes/admin/metaboxes.php:1004
631
  msgid "Crop Images?"
632
  msgstr ""
633
 
634
- #: includes/admin/metaboxes.php:1008
635
  msgid "If enabled, forces images to exactly match the sizes defined above for Image Dimensions and Mobile Dimensions."
636
  msgstr ""
637
 
638
- #: includes/admin/metaboxes.php:1009
639
  msgid "If disabled, images will be resized to maintain their aspect ratio."
640
  msgstr ""
641
 
642
- #: includes/admin/metaboxes.php:1019
643
  msgid "Set Dimensions on Images?"
644
  msgstr ""
645
 
646
- #: includes/admin/metaboxes.php:1023
647
  msgid "Enables or disables the width and height attributes on the img element. Only needs to be enabled if you need to meet Google Pagespeeds requirements."
648
  msgstr ""
649
 
650
- #: includes/admin/metaboxes.php:1028
651
  msgid "Enable Isotope?"
652
  msgstr ""
653
 
654
- #: includes/admin/metaboxes.php:1032
655
  msgid "Enables or disables isotope/masonry layout support for the main gallery images."
656
  msgstr ""
657
 
658
- #: includes/admin/metaboxes.php:1038
659
  msgid "Enable CSS Animations?"
660
  msgstr ""
661
 
662
- #: includes/admin/metaboxes.php:1042
663
  msgid "Enables CSS animations when loading the main gallery images."
664
  msgstr ""
665
 
666
- #: includes/admin/metaboxes.php:1048
667
  msgid "Image Opacity"
668
  msgstr ""
669
 
670
- #: includes/admin/metaboxes.php:1052
671
  msgid "The opacity to display images at when loading the main gallery images using CSS animations (between 1 and 100%)."
672
  msgstr ""
673
 
674
- #: includes/admin/metaboxes.php:1069
675
  msgid "Want to do even more with your gallery display?"
676
  msgstr ""
677
 
678
- #: includes/admin/metaboxes.php:1070
679
  msgid "By upgrading to Envira Pro, you can get access to numerous other gallery display features, including: custom image tagging and filtering, mobile specific image assets for blazing fast load times, dedicated and unique gallery URLs, custom gallery themes, gallery thumbnail support and so much more!"
680
  msgstr ""
681
 
682
- #: includes/admin/metaboxes.php:1092
683
  msgid "Lightbox Settings"
684
  msgstr ""
685
 
686
- #: includes/admin/metaboxes.php:1094
687
  msgid "The settings below adjust the lightbox output."
688
  msgstr ""
689
 
690
- #: includes/admin/metaboxes.php:1111 includes/admin/metaboxes.php:1472
691
  msgid "Enable Lightbox?"
692
  msgstr ""
693
 
694
- #: includes/admin/metaboxes.php:1115
695
  msgid "Enables or disables the gallery lightbox."
696
  msgstr ""
697
 
698
- #: includes/admin/metaboxes.php:1126
699
  msgid "Gallery Lightbox Theme"
700
  msgstr ""
701
 
702
- #: includes/admin/metaboxes.php:1134
703
  msgid "Sets the theme for the gallery lightbox display."
704
  msgstr ""
705
 
706
- #: includes/admin/metaboxes.php:1148
707
  msgid "Define the maximum image size for the Lightbox view. Default will display the original, full size image."
708
  msgstr ""
709
 
710
- #: includes/admin/metaboxes.php:1154
711
  msgid "Caption Position"
712
  msgstr ""
713
 
714
- #: includes/admin/metaboxes.php:1162
715
  msgid "Sets the display of the lightbox image's caption."
716
  msgstr ""
717
 
718
- #: includes/admin/metaboxes.php:1171 includes/admin/metaboxes.php:1499
719
  msgid "Enable Gallery Arrows?"
720
  msgstr ""
721
 
722
- #: includes/admin/metaboxes.php:1175
723
  msgid "Enables or disables the gallery lightbox navigation arrows."
724
  msgstr ""
725
 
726
- #: includes/admin/metaboxes.php:1180
727
  msgid "Gallery Arrow Position"
728
  msgstr ""
729
 
730
- #: includes/admin/metaboxes.php:1188
731
  msgid "Sets the position of the gallery lightbox navigation arrows."
732
  msgstr ""
733
 
734
- #: includes/admin/metaboxes.php:1193
735
  msgid "Enable Keyboard Navigation?"
736
  msgstr ""
737
 
738
- #: includes/admin/metaboxes.php:1197
739
  msgid "Enables or disables keyboard navigation in the gallery lightbox."
740
  msgstr ""
741
 
742
- #: includes/admin/metaboxes.php:1202
743
  msgid "Enable Mousewheel Navigation?"
744
  msgstr ""
745
 
746
- #: includes/admin/metaboxes.php:1206
747
  msgid "Enables or disables mousewheel navigation in the gallery."
748
  msgstr ""
749
 
750
- #: includes/admin/metaboxes.php:1211 includes/admin/metaboxes.php:1508
751
  msgid "Enable Gallery Toolbar?"
752
  msgstr ""
753
 
754
- #: includes/admin/metaboxes.php:1215
755
  msgid "Enables or disables the gallery lightbox toolbar."
756
  msgstr ""
757
 
758
- #: includes/admin/metaboxes.php:1220
759
  msgid "Display Gallery Title in Toolbar?"
760
  msgstr ""
761
 
762
- #: includes/admin/metaboxes.php:1224
763
  msgid "Display the gallery title in the lightbox toolbar."
764
  msgstr ""
765
 
766
- #: includes/admin/metaboxes.php:1229
767
  msgid "Gallery Toolbar Position"
768
  msgstr ""
769
 
770
- #: includes/admin/metaboxes.php:1237
771
  msgid "Sets the position of the lightbox toolbar."
772
  msgstr ""
773
 
774
- #: includes/admin/metaboxes.php:1242
775
  msgid "Keep Aspect Ratio?"
776
  msgstr ""
777
 
778
- #: includes/admin/metaboxes.php:1246
779
  msgid "If enabled, images will always resize based on the original aspect ratio."
780
  msgstr ""
781
 
782
- #: includes/admin/metaboxes.php:1251
783
  msgid "Loop Gallery Navigation?"
784
  msgstr ""
785
 
786
- #: includes/admin/metaboxes.php:1255
787
  msgid "Enables or disables infinite navigation cycling of the lightbox gallery."
788
  msgstr ""
789
 
790
- #: includes/admin/metaboxes.php:1260
791
  msgid "Lightbox Open/Close Effect"
792
  msgstr ""
793
 
794
- #: includes/admin/metaboxes.php:1280
795
  msgid "Type of transition when opening and closing the lightbox."
796
  msgstr ""
797
 
798
- #: includes/admin/metaboxes.php:1285
799
  msgid "Lightbox Transition Effect"
800
  msgstr ""
801
 
802
- #: includes/admin/metaboxes.php:1305
803
  msgid "Type of transition between images in the lightbox view."
804
  msgstr ""
805
 
806
- #: includes/admin/metaboxes.php:1310
807
  msgid "HTML5 Output?"
808
  msgstr ""
809
 
810
- #: includes/admin/metaboxes.php:1314
811
  msgid "If enabled, uses data-envirabox-gallery instead of rel attributes for W3C HTML5 validation."
812
  msgstr ""
813
 
814
- #: includes/admin/metaboxes.php:1328
815
  msgid "The settings below adjust the thumbnail views for the gallery lightbox display."
816
  msgstr ""
817
 
818
- #: includes/admin/metaboxes.php:1333 includes/admin/metaboxes.php:1517
819
  msgid "Enable Gallery Thumbnails?"
820
  msgstr ""
821
 
822
- #: includes/admin/metaboxes.php:1337
823
  msgid "Enables or disables the gallery lightbox thumbnails."
824
  msgstr ""
825
 
826
- #: includes/admin/metaboxes.php:1342
827
  msgid "Gallery Thumbnails Width"
828
  msgstr ""
829
 
830
- #: includes/admin/metaboxes.php:1346
831
  msgid "Sets the width of each lightbox thumbnail."
832
  msgstr ""
833
 
834
- #: includes/admin/metaboxes.php:1351
835
  msgid "Gallery Thumbnails Height"
836
  msgstr ""
837
 
838
- #: includes/admin/metaboxes.php:1355
839
  msgid "Sets the height of each lightbox thumbnail."
840
  msgstr ""
841
 
842
- #: includes/admin/metaboxes.php:1360
843
  msgid "Gallery Thumbnails Position"
844
  msgstr ""
845
 
846
- #: includes/admin/metaboxes.php:1368
847
  msgid "Sets the position of the lightbox thumbnails."
848
  msgstr ""
849
 
850
- #: includes/admin/metaboxes.php:1385
851
  msgid "Want even more fine tuned control over your lightbox display?"
852
  msgstr ""
853
 
854
- #: includes/admin/metaboxes.php:1386
855
  msgid "By upgrading to Envira Pro, you can get access to numerous other lightbox features, including: custom lightbox titles, enable/disable lightbox controls (arrow, keyboard and mousehweel navigation), custom lightbox transition effects, native fullscreen support, gallery deeplinking, image protection, lightbox supersize effects, lightbox slideshows and so much more!"
856
  msgstr ""
857
 
858
- #: includes/admin/metaboxes.php:1408
859
  msgid "Mobile Gallery Settings"
860
  msgstr ""
861
 
862
- #: includes/admin/metaboxes.php:1410
863
  msgid "The settings below adjust configuration options for the Gallery when viewed on a mobile device."
864
  msgstr ""
865
 
866
- #: includes/admin/metaboxes.php:1433
867
  msgid "Determines the number of columns in the gallery on mobile devices. Automatic will attempt to fill each row as much as possible before moving on to the next row."
868
  msgstr ""
869
 
870
- #: includes/admin/metaboxes.php:1439
871
  msgid "Create Mobile Gallery Images?"
872
  msgstr ""
873
 
874
- #: includes/admin/metaboxes.php:1443
875
  msgid "Enables or disables creating specific images for mobile devices."
876
  msgstr ""
877
 
878
- #: includes/admin/metaboxes.php:1449
879
  msgid "Mobile Dimensions"
880
  msgstr ""
881
 
882
- #: includes/admin/metaboxes.php:1453
883
  msgid "These will be the sizes used for images displayed on mobile devices."
884
  msgstr ""
885
 
886
- #: includes/admin/metaboxes.php:1463
887
  msgid "Mobile Lightbox Settings"
888
  msgstr ""
889
 
890
- #: includes/admin/metaboxes.php:1465
891
  msgid "The settings below adjust configuration options for the Lightbox when viewed on a mobile device."
892
  msgstr ""
893
 
894
- #: includes/admin/metaboxes.php:1476
895
  msgid "Enables or disables the gallery lightbox on mobile devices."
896
  msgstr ""
897
 
898
- #: includes/admin/metaboxes.php:1481
899
  msgid "Enable Gallery Touchwipe?"
900
  msgstr ""
901
 
902
- #: includes/admin/metaboxes.php:1485
903
  msgid "Enables or disables touchwipe support for the gallery lightbox on mobile devices."
904
  msgstr ""
905
 
906
- #: includes/admin/metaboxes.php:1490
907
  msgid "Close Lightbox on Swipe Up?"
908
  msgstr ""
909
 
910
- #: includes/admin/metaboxes.php:1494
911
  msgid "Enables or disables closing the Lightbox when the user swipes up on mobile devices."
912
  msgstr ""
913
 
914
- #: includes/admin/metaboxes.php:1503
915
  msgid "Enables or disables the gallery lightbox navigation arrows on mobile devices."
916
  msgstr ""
917
 
918
- #: includes/admin/metaboxes.php:1512
919
  msgid "Enables or disables the gallery lightbox toolbar on mobile devices."
920
  msgstr ""
921
 
922
- #: includes/admin/metaboxes.php:1521
923
  msgid "Enables or disables the gallery lightbox thumbnails on mobile devices."
924
  msgstr ""
925
 
926
- #: includes/admin/metaboxes.php:1545
927
  msgid "Miscellaneous Settings"
928
  msgstr ""
929
 
930
- #: includes/admin/metaboxes.php:1547
931
  msgid "The settings below adjust miscellaneous options for the Gallery."
932
  msgstr ""
933
 
934
- #: includes/admin/metaboxes.php:1563
935
  msgid "Gallery Title"
936
  msgstr ""
937
 
938
- #: includes/admin/metaboxes.php:1567
939
  msgid "Internal gallery title for identification in the admin."
940
  msgstr ""
941
 
942
- #: includes/admin/metaboxes.php:1572
943
  msgid "Gallery Slug"
944
  msgstr ""
945
 
946
- #: includes/admin/metaboxes.php:1576
947
  msgid "<strong>Unique</strong> internal gallery slug for identification and advanced gallery queries."
948
  msgstr ""
949
 
950
- #: includes/admin/metaboxes.php:1581
951
  msgid "Custom Gallery Classes"
952
  msgstr ""
953
 
954
- #: includes/admin/metaboxes.php:1584
955
  msgid "Enter custom gallery CSS classes here, one per line."
956
  msgstr ""
957
 
958
- #: includes/admin/metaboxes.php:1585
959
  msgid "Adds custom CSS classes to this gallery. Enter one class per line."
960
  msgstr ""
961
 
962
- #: includes/admin/metaboxes.php:1594
963
  msgid "Import/Export Gallery"
964
  msgstr ""
965
 
966
- #: includes/admin/metaboxes.php:1607
967
  msgid "Import Gallery"
968
  msgstr ""
969
 
970
- #: includes/admin/metaboxes.php:1614
971
  msgid "Export Gallery"
972
  msgstr ""
973
 
974
- #: includes/admin/metaboxes.php:1624
975
  msgid "Enable RTL Support?"
976
  msgstr ""
977
 
978
- #: includes/admin/metaboxes.php:1628
979
  msgid "Enables or disables RTL support in Envira for right-to-left languages."
980
  msgstr ""
981
 
982
- #: includes/admin/metaboxes.php:1640 includes/admin/metaboxes.php:1682
983
- #: includes/admin/metaboxes.php:1704 includes/admin/metaboxes.php:1726
984
- #: includes/admin/metaboxes.php:1748 includes/admin/metaboxes.php:1770
985
  msgid "Want to take your galleries further?"
986
  msgstr ""
987
 
988
- #: includes/admin/metaboxes.php:1641
989
  msgid "By upgrading to Envira Pro, you can get access to numerous other features, including: a fully-integrated import/export module for your galleries, custom CSS controls for each gallery and so much more!"
990
  msgstr ""
991
 
992
- #: includes/admin/metaboxes.php:1662
993
  msgid "Videos"
994
  msgstr ""
995
 
996
- #: includes/admin/metaboxes.php:1663
997
  msgid "Social"
998
  msgstr ""
999
 
1000
- #: includes/admin/metaboxes.php:1664
1001
  msgid "Tags"
1002
  msgstr ""
1003
 
1004
- #: includes/admin/metaboxes.php:1665
1005
  msgid "Pagination"
1006
  msgstr ""
1007
 
1008
- #: includes/admin/metaboxes.php:1683
1009
  msgid "By upgrading to Envira Pro, you can get access to mobile-specific settings, including mobile image sizes, number of columns, mobile-specific lightbox options and so much more!"
1010
  msgstr ""
1011
 
1012
- #: includes/admin/metaboxes.php:1705
1013
  msgid "By upgrading to Envira Pro, you can add Videos to your Envira Galleries from YouTube, Vimeo, Wistia, and your own self-hosted videos!"
1014
  msgstr ""
1015
 
1016
- #: includes/admin/metaboxes.php:1727
1017
  msgid "By upgrading to Envira Pro, you can add social sharing buttons to your Gallery images and Lightbox images. With support for Facebook, Twitter, Google+ and Pinterest why not check it out?"
1018
  msgstr ""
1019
 
1020
- #: includes/admin/metaboxes.php:1749
1021
  msgid "By upgrading to Envira Pro, you can add Tags to your Gallery images, allow users to filter your Gallery by tag and so much more!"
1022
  msgstr ""
1023
 
1024
- #: includes/admin/metaboxes.php:1771
1025
  msgid "By upgrading to Envira Pro, you can split your Gallery across multiple pages with pagination, load paginated images via AJAX, lazy loading and more!"
1026
  msgstr ""
1027
 
1028
- #: includes/admin/metaboxes.php:2051
1029
  msgid "Remove Image from Gallery?"
1030
  msgstr ""
1031
 
1032
- #: includes/admin/metaboxes.php:2052
1033
  msgid "Modify Image"
1034
  msgstr ""
1035
 
@@ -1294,123 +1307,127 @@ msgstr ""
1294
  msgid "Six Columns (6)"
1295
  msgstr ""
1296
 
1297
- #: includes/global/common.php:107 includes/global/common.php:228
1298
  msgid "Base"
1299
  msgstr ""
1300
 
1301
- #: includes/global/common.php:127
 
 
 
 
1302
  msgid "Do not display"
1303
  msgstr ""
1304
 
1305
- #: includes/global/common.php:131
1306
  msgid "Display above galleries"
1307
  msgstr ""
1308
 
1309
- #: includes/global/common.php:135
1310
  msgid "Display below galleries"
1311
  msgstr ""
1312
 
1313
- #: includes/global/common.php:155
1314
  msgid "No Sorting"
1315
  msgstr ""
1316
 
1317
- #: includes/global/common.php:159 includes/global/common.php:288
1318
  msgid "Random"
1319
  msgstr ""
1320
 
1321
- #: includes/global/common.php:163
1322
  msgid "Published Date"
1323
  msgstr ""
1324
 
1325
- #: includes/global/common.php:167
1326
  msgid "Filename"
1327
  msgstr ""
1328
 
1329
- #: includes/global/common.php:179
1330
  msgid "Alt"
1331
  msgstr ""
1332
 
1333
- #: includes/global/common.php:203
1334
  msgid "Ascending (A-Z)"
1335
  msgstr ""
1336
 
1337
- #: includes/global/common.php:207
1338
  msgid "Descending (Z-A)"
1339
  msgstr ""
1340
 
1341
- #: includes/global/common.php:308
1342
  msgid "Float"
1343
  msgstr ""
1344
 
1345
- #: includes/global/common.php:312
1346
  msgid "Float (Wrapped)"
1347
  msgstr ""
1348
 
1349
- #: includes/global/common.php:316 includes/global/common.php:344
1350
  msgid "Inside"
1351
  msgstr ""
1352
 
1353
- #: includes/global/common.php:320 includes/global/common.php:348
1354
  msgid "Outside"
1355
  msgstr ""
1356
 
1357
- #: includes/global/common.php:324
1358
  msgid "Over"
1359
  msgstr ""
1360
 
1361
- #: includes/global/common.php:368
1362
  msgid "No Effect"
1363
  msgstr ""
1364
 
1365
- #: includes/global/common.php:372
1366
  msgid "Fade"
1367
  msgstr ""
1368
 
1369
- #: includes/global/common.php:376
1370
  msgid "Elastic"
1371
  msgstr ""
1372
 
1373
- #: includes/global/common.php:424
1374
  msgid "Swing"
1375
  msgstr ""
1376
 
1377
- #: includes/global/common.php:480 includes/global/common.php:504
1378
  msgid "Top"
1379
  msgstr ""
1380
 
1381
- #: includes/global/common.php:484 includes/global/common.php:508
1382
  msgid "Bottom"
1383
  msgstr ""
1384
 
1385
- #: includes/global/common.php:649
1386
  msgid "Image Files"
1387
  msgstr ""
1388
 
1389
- #: includes/global/common.php:699
1390
  msgid "Before Existing Images"
1391
  msgstr ""
1392
 
1393
- #: includes/global/common.php:703
1394
  msgid "After Existing Images"
1395
  msgstr ""
1396
 
1397
- #: includes/global/common.php:727
1398
  msgid "Yes"
1399
  msgstr ""
1400
 
1401
- #: includes/global/common.php:800
1402
  msgid "No image editor could be selected. Please verify with your webhost that you have either the GD or Imagick image library compiled with your PHP install on your server."
1403
  msgstr ""
1404
 
1405
- #: includes/global/common.php:903
1406
  msgid "No image URL specified for cropping."
1407
  msgstr ""
1408
 
1409
- #: includes/global/common.php:922
1410
  msgid "No file could be found for the image URL specified."
1411
  msgstr ""
1412
 
1413
- #: includes/global/common.php:930 includes/global/common.php:942
1414
  msgid "The dimensions of the original image could not be retrieved for cropping."
1415
  msgstr ""
1416
 
@@ -1450,19 +1467,19 @@ msgstr ""
1450
  msgid "No Envira galleries found in trash."
1451
  msgstr ""
1452
 
1453
- #: includes/global/shortcode.php:820
1454
  msgid "The requested content cannot be loaded.<br/>Please try again later.</p>"
1455
  msgstr ""
1456
 
1457
- #: includes/global/shortcode.php:821 includes/global/shortcode.php:1409
1458
  msgid "Close"
1459
  msgstr ""
1460
 
1461
- #: includes/global/shortcode.php:822 includes/global/shortcode.php:1399
1462
  msgid "Next"
1463
  msgstr ""
1464
 
1465
- #: includes/global/shortcode.php:823 includes/global/shortcode.php:1395
1466
  msgid "Previous"
1467
  msgstr ""
1468
 
2
  # This file is distributed under the same license as the Envira Gallery Lite package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Envira Gallery Lite 1.5.1\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/envira-gallery\n"
7
+ "POT-Creation-Date: 2016-08-26 15:47:26+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
215
  msgid "Your license key for Envira Gallery is invalid. The key no longer exists or the user associated with the key has been deleted. Please use a different key to continue receiving automatic updates."
216
  msgstr ""
217
 
218
+ #: includes/admin/media-view.php:111 includes/admin/media-view.php:112
219
+ #: includes/admin/media-view.php:514 includes/admin/media-view.php:515
220
  msgid "Search"
221
  msgstr ""
222
 
223
+ #: includes/admin/media-view.php:164 includes/admin/media-view.php:491
224
  msgid "Helpful Tips"
225
  msgstr ""
226
 
227
+ #: includes/admin/media-view.php:165
228
  msgid "Choosing Your Gallery"
229
  msgstr ""
230
 
231
+ #: includes/admin/media-view.php:167
232
  msgid "To choose your gallery, simply click on one of the boxes to the left. Ctrl / cmd and click to select multiple Galleries. The \"Insert Gallery\" button will be activated once you have selected a gallery."
233
  msgstr ""
234
 
235
+ #: includes/admin/media-view.php:169
236
  msgid "Inserting Your Gallery"
237
  msgstr ""
238
 
239
+ #: includes/admin/media-view.php:171
240
  msgid "To insert your gallery into the editor, click on the \"Insert Gallery\" button below."
241
  msgstr ""
242
 
243
+ #: includes/admin/media-view.php:175
244
  msgid "Insert Options"
245
  msgstr ""
246
 
247
+ #: includes/admin/media-view.php:179
248
  msgid "Display Title"
249
  msgstr ""
250
 
251
+ #: includes/admin/media-view.php:181 includes/global/common.php:746
252
  msgid "No"
253
  msgstr ""
254
 
255
+ #: includes/admin/media-view.php:185
256
  msgid "Yes, as Heading H%s"
257
  msgstr ""
258
 
259
+ #: includes/admin/media-view.php:192
260
  msgid "Prepends each inserted Gallery with the Gallery Title."
261
  msgstr ""
262
 
263
+ #: includes/admin/media-view.php:226
264
  msgid "Edit previous media item"
265
  msgstr ""
266
 
267
+ #: includes/admin/media-view.php:227
268
  msgid "Edit next media item"
269
  msgstr ""
270
 
271
+ #: includes/admin/media-view.php:230
272
  msgid "Edit Metadata"
273
  msgstr ""
274
 
275
+ #: includes/admin/media-view.php:250 includes/admin/media-view.php:384
276
+ #: includes/admin/table.php:167 includes/global/common.php:192
277
  #: includes/global/widget.php:153
278
  msgid "Title"
279
  msgstr ""
280
 
281
+ #: includes/admin/media-view.php:253 includes/admin/media-view.php:387
282
  msgid "Image titles can take any type of HTML. You can adjust the position of the titles in the main Lightbox settings."
283
  msgstr ""
284
 
285
+ #: includes/admin/media-view.php:262 includes/admin/media-view.php:393
286
+ #: includes/global/common.php:196
287
  msgid "Caption"
288
  msgstr ""
289
 
290
+ #: includes/admin/media-view.php:276 includes/admin/media-view.php:407
291
  msgid "Captions can take any type of HTML, and are displayed when an image is clicked."
292
  msgstr ""
293
 
294
+ #: includes/admin/media-view.php:285 includes/admin/media-view.php:413
295
  msgid "Alt Text"
296
  msgstr ""
297
 
298
+ #: includes/admin/media-view.php:288 includes/admin/media-view.php:416
299
  msgid "Very important for SEO, the Alt Text describes the image."
300
  msgstr ""
301
 
302
+ #: includes/admin/media-view.php:294 includes/admin/media-view.php:422
303
+ #: includes/global/common.php:204
304
  msgid "URL"
305
  msgstr ""
306
 
307
+ #: includes/admin/media-view.php:298 includes/admin/media-view.php:426
308
  msgid "Media File"
309
  msgstr ""
310
 
311
+ #: includes/admin/media-view.php:299 includes/admin/media-view.php:427
312
  msgid "Attachment Page"
313
  msgstr ""
314
 
315
+ #: includes/admin/media-view.php:303 includes/admin/media-view.php:431
316
  msgid "Enter a hyperlink if you wish to link this image to somewhere other than its full size image."
317
  msgstr ""
318
 
319
+ #: includes/admin/media-view.php:312 includes/admin/media-view.php:437
320
  msgid "Open URL in New Window?"
321
  msgstr ""
322
 
323
+ #: includes/admin/media-view.php:315 includes/admin/media-view.php:440
324
  msgid "Opens your image links in a new browser window / tab."
325
  msgstr ""
326
 
327
+ #: includes/admin/media-view.php:326
328
  msgid "Want Captions and more options?"
329
  msgstr ""
330
 
331
+ #: includes/admin/media-view.php:327
332
  msgid "By upgrading to Envira Pro, you can get access to numerous other features, including: HTML captions, open links in new windows, WooCommerce product integration and so much more!"
333
  msgstr ""
334
 
335
+ #: includes/admin/media-view.php:329 includes/admin/metaboxes.php:776
336
+ #: includes/admin/metaboxes.php:1114 includes/admin/metaboxes.php:1430
337
+ #: includes/admin/metaboxes.php:1685 includes/admin/metaboxes.php:1727
338
+ #: includes/admin/metaboxes.php:1749 includes/admin/metaboxes.php:1771
339
+ #: includes/admin/metaboxes.php:1793 includes/admin/metaboxes.php:1815
340
  msgid "Click here to Upgrade"
341
  msgstr ""
342
 
343
+ #: includes/admin/media-view.php:346 includes/admin/media-view.php:347
344
+ #: includes/admin/media-view.php:452
345
  msgid "Save Metadata"
346
  msgstr ""
347
 
348
+ #: includes/admin/media-view.php:353 includes/admin/media-view.php:458
349
  msgid "Saved."
350
  msgstr ""
351
 
352
+ #: includes/admin/media-view.php:368
353
  msgid "Bulk Edit"
354
  msgstr ""
355
 
356
+ #: includes/admin/media-view.php:451
357
  msgid "Save Metadata to Items"
358
  msgstr ""
359
 
360
+ #: includes/admin/media-view.php:493
361
  msgid "Select the Gallery to move the selected images to by clicking on one of the boxes to the left."
362
  msgstr ""
363
 
364
+ #: includes/admin/media-view.php:496
365
  msgid "Once done, click the Move button, and the selected images will be moved to the chosen Gallery."
366
  msgstr ""
367
 
447
  msgid "Envira Gallery Code"
448
  msgstr ""
449
 
450
+ #: includes/admin/metaboxes.php:586 includes/global/common.php:274
451
  msgid "Default"
452
  msgstr ""
453
 
463
  msgid "Lightbox"
464
  msgstr ""
465
 
466
+ #: includes/admin/metaboxes.php:606 includes/admin/metaboxes.php:1703
467
  msgid "Mobile"
468
  msgstr ""
469
 
476
  msgstr ""
477
 
478
  #: includes/admin/metaboxes.php:707 includes/admin/metaboxes.php:800
479
+ #: includes/admin/metaboxes.php:1138 includes/admin/metaboxes.php:1453
480
+ #: includes/admin/metaboxes.php:1591
481
  msgid "Need some help?"
482
  msgstr ""
483
 
484
  #: includes/admin/metaboxes.php:709 includes/admin/metaboxes.php:802
485
+ #: includes/admin/metaboxes.php:1140 includes/admin/metaboxes.php:1455
486
+ #: includes/admin/metaboxes.php:1593
487
  msgid "Read the Documentation"
488
  msgstr ""
489
 
490
  #: includes/admin/metaboxes.php:713 includes/admin/metaboxes.php:806
491
+ #: includes/admin/metaboxes.php:1144 includes/admin/metaboxes.php:1459
492
+ #: includes/admin/metaboxes.php:1597
493
  msgid "Watch a Video"
494
  msgstr ""
495
 
533
  msgid "The settings below adjust the basic configuration options for the gallery."
534
  msgstr ""
535
 
536
+ #: includes/admin/metaboxes.php:814 includes/admin/metaboxes.php:1467
537
  msgid "Number of Gallery Columns"
538
  msgstr ""
539
 
541
  msgid "Determines the number of columns in the gallery. Automatic will attempt to fill each row as much as possible before moving on to the next row."
542
  msgstr ""
543
 
544
+ #: includes/admin/metaboxes.php:833
545
+ msgid "Automatic Layout: Row Height"
546
+ msgstr ""
547
+
548
+ #: includes/admin/metaboxes.php:836 includes/admin/metaboxes.php:932
549
+ #: includes/admin/metaboxes.php:941 includes/admin/metaboxes.php:1039
550
+ #: includes/admin/metaboxes.php:1387 includes/admin/metaboxes.php:1396
551
+ #: includes/admin/metaboxes.php:1494
552
+ msgid "px"
553
+ msgstr ""
554
+
555
+ #: includes/admin/metaboxes.php:837
556
+ msgid "Determines how high (in pixels) each row will be. 150px is default. "
557
+ msgstr ""
558
+
559
+ #: includes/admin/metaboxes.php:842
560
+ msgid "Automatic Layout: Gallery Theme"
561
  msgstr ""
562
 
563
+ #: includes/admin/metaboxes.php:850 includes/admin/metaboxes.php:922
564
  msgid "Sets the theme for the gallery display."
565
  msgstr ""
566
 
567
+ #: includes/admin/metaboxes.php:865
568
  msgid "Display Gallery Description?"
569
  msgstr ""
570
 
571
+ #: includes/admin/metaboxes.php:877
572
  msgid "Choose to display a description above or below this gallery's images."
573
  msgstr ""
574
 
575
+ #: includes/admin/metaboxes.php:884
576
  msgid "Gallery Description"
577
  msgstr ""
578
 
579
+ #: includes/admin/metaboxes.php:899
580
  msgid "The description to display for this gallery."
581
  msgstr ""
582
 
583
+ #: includes/admin/metaboxes.php:914 includes/admin/table.php:305
584
+ #: includes/admin/table.php:382
585
+ msgid "Gallery Theme"
586
  msgstr ""
587
 
588
+ #: includes/admin/metaboxes.php:929 includes/admin/table.php:314
589
+ #: includes/admin/table.php:393
590
+ msgid "Column Gutter Width"
 
591
  msgstr ""
592
 
593
+ #: includes/admin/metaboxes.php:933
594
  msgid "Sets the space between the columns (defaults to 10)."
595
  msgstr ""
596
 
597
+ #: includes/admin/metaboxes.php:938 includes/admin/table.php:319
598
  #: includes/admin/table.php:398
599
  msgid "Margin Below Each Image"
600
  msgstr ""
601
 
602
+ #: includes/admin/metaboxes.php:942
603
  msgid "Sets the space below each item in the gallery."
604
  msgstr ""
605
 
606
+ #: includes/admin/metaboxes.php:952
607
  msgid "Sorting"
608
  msgstr ""
609
 
610
+ #: includes/admin/metaboxes.php:964
611
  msgid "Choose to sort the images in a different order than displayed on the Images tab."
612
  msgstr ""
613
 
614
+ #: includes/admin/metaboxes.php:969
615
  msgid "Direction"
616
  msgstr ""
617
 
618
+ #: includes/admin/metaboxes.php:990 includes/admin/metaboxes.php:1182
619
  msgid "Image Size"
620
  msgstr ""
621
 
622
+ #: includes/admin/metaboxes.php:1002
623
  msgid "Define the maximum image size for the Gallery view. Default will use the below Image Dimensions; Random will allow you to choose one or more WordPress image sizes, which will be used for the gallery output."
624
  msgstr ""
625
 
626
+ #: includes/admin/metaboxes.php:1011
627
  msgid "Random Image Sizes"
628
  msgstr ""
629
 
630
+ #: includes/admin/metaboxes.php:1027
631
  msgid "Define the WordPress registered image sizes to include when randomly assigning an image size to each image in your Gallery."
632
  msgstr ""
633
 
634
+ #: includes/admin/metaboxes.php:1036 includes/admin/table.php:325
635
  #: includes/admin/table.php:403
636
  msgid "Image Dimensions"
637
  msgstr ""
638
 
639
+ #: includes/admin/metaboxes.php:1040
640
  msgid "You should adjust these dimensions based on the number of columns in your gallery. This does not affect the full size lightbox images."
641
  msgstr ""
642
 
643
+ #: includes/admin/metaboxes.php:1045
644
  msgid "Crop Images?"
645
  msgstr ""
646
 
647
+ #: includes/admin/metaboxes.php:1049
648
  msgid "If enabled, forces images to exactly match the sizes defined above for Image Dimensions and Mobile Dimensions."
649
  msgstr ""
650
 
651
+ #: includes/admin/metaboxes.php:1050
652
  msgid "If disabled, images will be resized to maintain their aspect ratio."
653
  msgstr ""
654
 
655
+ #: includes/admin/metaboxes.php:1060
656
  msgid "Set Dimensions on Images?"
657
  msgstr ""
658
 
659
+ #: includes/admin/metaboxes.php:1064
660
  msgid "Enables or disables the width and height attributes on the img element. Only needs to be enabled if you need to meet Google Pagespeeds requirements."
661
  msgstr ""
662
 
663
+ #: includes/admin/metaboxes.php:1069
664
  msgid "Enable Isotope?"
665
  msgstr ""
666
 
667
+ #: includes/admin/metaboxes.php:1073
668
  msgid "Enables or disables isotope/masonry layout support for the main gallery images."
669
  msgstr ""
670
 
671
+ #: includes/admin/metaboxes.php:1079
672
  msgid "Enable CSS Animations?"
673
  msgstr ""
674
 
675
+ #: includes/admin/metaboxes.php:1083
676
  msgid "Enables CSS animations when loading the main gallery images."
677
  msgstr ""
678
 
679
+ #: includes/admin/metaboxes.php:1089
680
  msgid "Image Opacity"
681
  msgstr ""
682
 
683
+ #: includes/admin/metaboxes.php:1093
684
  msgid "The opacity to display images at when loading the main gallery images using CSS animations (between 1 and 100%)."
685
  msgstr ""
686
 
687
+ #: includes/admin/metaboxes.php:1111
688
  msgid "Want to do even more with your gallery display?"
689
  msgstr ""
690
 
691
+ #: includes/admin/metaboxes.php:1112
692
  msgid "By upgrading to Envira Pro, you can get access to numerous other gallery display features, including: custom image tagging and filtering, mobile specific image assets for blazing fast load times, dedicated and unique gallery URLs, custom gallery themes, gallery thumbnail support and so much more!"
693
  msgstr ""
694
 
695
+ #: includes/admin/metaboxes.php:1134
696
  msgid "Lightbox Settings"
697
  msgstr ""
698
 
699
+ #: includes/admin/metaboxes.php:1136
700
  msgid "The settings below adjust the lightbox output."
701
  msgstr ""
702
 
703
+ #: includes/admin/metaboxes.php:1153 includes/admin/metaboxes.php:1514
704
  msgid "Enable Lightbox?"
705
  msgstr ""
706
 
707
+ #: includes/admin/metaboxes.php:1157
708
  msgid "Enables or disables the gallery lightbox."
709
  msgstr ""
710
 
711
+ #: includes/admin/metaboxes.php:1168
712
  msgid "Gallery Lightbox Theme"
713
  msgstr ""
714
 
715
+ #: includes/admin/metaboxes.php:1176
716
  msgid "Sets the theme for the gallery lightbox display."
717
  msgstr ""
718
 
719
+ #: includes/admin/metaboxes.php:1190
720
  msgid "Define the maximum image size for the Lightbox view. Default will display the original, full size image."
721
  msgstr ""
722
 
723
+ #: includes/admin/metaboxes.php:1196
724
  msgid "Caption Position"
725
  msgstr ""
726
 
727
+ #: includes/admin/metaboxes.php:1204
728
  msgid "Sets the display of the lightbox image's caption."
729
  msgstr ""
730
 
731
+ #: includes/admin/metaboxes.php:1213 includes/admin/metaboxes.php:1541
732
  msgid "Enable Gallery Arrows?"
733
  msgstr ""
734
 
735
+ #: includes/admin/metaboxes.php:1217
736
  msgid "Enables or disables the gallery lightbox navigation arrows."
737
  msgstr ""
738
 
739
+ #: includes/admin/metaboxes.php:1222
740
  msgid "Gallery Arrow Position"
741
  msgstr ""
742
 
743
+ #: includes/admin/metaboxes.php:1230
744
  msgid "Sets the position of the gallery lightbox navigation arrows."
745
  msgstr ""
746
 
747
+ #: includes/admin/metaboxes.php:1235
748
  msgid "Enable Keyboard Navigation?"
749
  msgstr ""
750
 
751
+ #: includes/admin/metaboxes.php:1239
752
  msgid "Enables or disables keyboard navigation in the gallery lightbox."
753
  msgstr ""
754
 
755
+ #: includes/admin/metaboxes.php:1244
756
  msgid "Enable Mousewheel Navigation?"
757
  msgstr ""
758
 
759
+ #: includes/admin/metaboxes.php:1248
760
  msgid "Enables or disables mousewheel navigation in the gallery."
761
  msgstr ""
762
 
763
+ #: includes/admin/metaboxes.php:1253 includes/admin/metaboxes.php:1550
764
  msgid "Enable Gallery Toolbar?"
765
  msgstr ""
766
 
767
+ #: includes/admin/metaboxes.php:1257
768
  msgid "Enables or disables the gallery lightbox toolbar."
769
  msgstr ""
770
 
771
+ #: includes/admin/metaboxes.php:1262
772
  msgid "Display Gallery Title in Toolbar?"
773
  msgstr ""
774
 
775
+ #: includes/admin/metaboxes.php:1266
776
  msgid "Display the gallery title in the lightbox toolbar."
777
  msgstr ""
778
 
779
+ #: includes/admin/metaboxes.php:1271
780
  msgid "Gallery Toolbar Position"
781
  msgstr ""
782
 
783
+ #: includes/admin/metaboxes.php:1279
784
  msgid "Sets the position of the lightbox toolbar."
785
  msgstr ""
786
 
787
+ #: includes/admin/metaboxes.php:1284
788
  msgid "Keep Aspect Ratio?"
789
  msgstr ""
790
 
791
+ #: includes/admin/metaboxes.php:1288
792
  msgid "If enabled, images will always resize based on the original aspect ratio."
793
  msgstr ""
794
 
795
+ #: includes/admin/metaboxes.php:1293
796
  msgid "Loop Gallery Navigation?"
797
  msgstr ""
798
 
799
+ #: includes/admin/metaboxes.php:1297
800
  msgid "Enables or disables infinite navigation cycling of the lightbox gallery."
801
  msgstr ""
802
 
803
+ #: includes/admin/metaboxes.php:1302
804
  msgid "Lightbox Open/Close Effect"
805
  msgstr ""
806
 
807
+ #: includes/admin/metaboxes.php:1322
808
  msgid "Type of transition when opening and closing the lightbox."
809
  msgstr ""
810
 
811
+ #: includes/admin/metaboxes.php:1327
812
  msgid "Lightbox Transition Effect"
813
  msgstr ""
814
 
815
+ #: includes/admin/metaboxes.php:1347
816
  msgid "Type of transition between images in the lightbox view."
817
  msgstr ""
818
 
819
+ #: includes/admin/metaboxes.php:1352
820
  msgid "HTML5 Output?"
821
  msgstr ""
822
 
823
+ #: includes/admin/metaboxes.php:1356
824
  msgid "If enabled, uses data-envirabox-gallery instead of rel attributes for W3C HTML5 validation."
825
  msgstr ""
826
 
827
+ #: includes/admin/metaboxes.php:1370
828
  msgid "The settings below adjust the thumbnail views for the gallery lightbox display."
829
  msgstr ""
830
 
831
+ #: includes/admin/metaboxes.php:1375 includes/admin/metaboxes.php:1559
832
  msgid "Enable Gallery Thumbnails?"
833
  msgstr ""
834
 
835
+ #: includes/admin/metaboxes.php:1379
836
  msgid "Enables or disables the gallery lightbox thumbnails."
837
  msgstr ""
838
 
839
+ #: includes/admin/metaboxes.php:1384
840
  msgid "Gallery Thumbnails Width"
841
  msgstr ""
842
 
843
+ #: includes/admin/metaboxes.php:1388
844
  msgid "Sets the width of each lightbox thumbnail."
845
  msgstr ""
846
 
847
+ #: includes/admin/metaboxes.php:1393
848
  msgid "Gallery Thumbnails Height"
849
  msgstr ""
850
 
851
+ #: includes/admin/metaboxes.php:1397
852
  msgid "Sets the height of each lightbox thumbnail."
853
  msgstr ""
854
 
855
+ #: includes/admin/metaboxes.php:1402
856
  msgid "Gallery Thumbnails Position"
857
  msgstr ""
858
 
859
+ #: includes/admin/metaboxes.php:1410
860
  msgid "Sets the position of the lightbox thumbnails."
861
  msgstr ""
862
 
863
+ #: includes/admin/metaboxes.php:1427
864
  msgid "Want even more fine tuned control over your lightbox display?"
865
  msgstr ""
866
 
867
+ #: includes/admin/metaboxes.php:1428
868
  msgid "By upgrading to Envira Pro, you can get access to numerous other lightbox features, including: custom lightbox titles, enable/disable lightbox controls (arrow, keyboard and mousehweel navigation), custom lightbox transition effects, native fullscreen support, gallery deeplinking, image protection, lightbox supersize effects, lightbox slideshows and so much more!"
869
  msgstr ""
870
 
871
+ #: includes/admin/metaboxes.php:1450
872
  msgid "Mobile Gallery Settings"
873
  msgstr ""
874
 
875
+ #: includes/admin/metaboxes.php:1452
876
  msgid "The settings below adjust configuration options for the Gallery when viewed on a mobile device."
877
  msgstr ""
878
 
879
+ #: includes/admin/metaboxes.php:1475
880
  msgid "Determines the number of columns in the gallery on mobile devices. Automatic will attempt to fill each row as much as possible before moving on to the next row."
881
  msgstr ""
882
 
883
+ #: includes/admin/metaboxes.php:1481
884
  msgid "Create Mobile Gallery Images?"
885
  msgstr ""
886
 
887
+ #: includes/admin/metaboxes.php:1485
888
  msgid "Enables or disables creating specific images for mobile devices."
889
  msgstr ""
890
 
891
+ #: includes/admin/metaboxes.php:1491
892
  msgid "Mobile Dimensions"
893
  msgstr ""
894
 
895
+ #: includes/admin/metaboxes.php:1495
896
  msgid "These will be the sizes used for images displayed on mobile devices."
897
  msgstr ""
898
 
899
+ #: includes/admin/metaboxes.php:1505
900
  msgid "Mobile Lightbox Settings"
901
  msgstr ""
902
 
903
+ #: includes/admin/metaboxes.php:1507
904
  msgid "The settings below adjust configuration options for the Lightbox when viewed on a mobile device."
905
  msgstr ""
906
 
907
+ #: includes/admin/metaboxes.php:1518
908
  msgid "Enables or disables the gallery lightbox on mobile devices."
909
  msgstr ""
910
 
911
+ #: includes/admin/metaboxes.php:1523
912
  msgid "Enable Gallery Touchwipe?"
913
  msgstr ""
914
 
915
+ #: includes/admin/metaboxes.php:1527
916
  msgid "Enables or disables touchwipe support for the gallery lightbox on mobile devices."
917
  msgstr ""
918
 
919
+ #: includes/admin/metaboxes.php:1532
920
  msgid "Close Lightbox on Swipe Up?"
921
  msgstr ""
922
 
923
+ #: includes/admin/metaboxes.php:1536
924
  msgid "Enables or disables closing the Lightbox when the user swipes up on mobile devices."
925
  msgstr ""
926
 
927
+ #: includes/admin/metaboxes.php:1545
928
  msgid "Enables or disables the gallery lightbox navigation arrows on mobile devices."
929
  msgstr ""
930
 
931
+ #: includes/admin/metaboxes.php:1554
932
  msgid "Enables or disables the gallery lightbox toolbar on mobile devices."
933
  msgstr ""
934
 
935
+ #: includes/admin/metaboxes.php:1563
936
  msgid "Enables or disables the gallery lightbox thumbnails on mobile devices."
937
  msgstr ""
938
 
939
+ #: includes/admin/metaboxes.php:1587
940
  msgid "Miscellaneous Settings"
941
  msgstr ""
942
 
943
+ #: includes/admin/metaboxes.php:1589
944
  msgid "The settings below adjust miscellaneous options for the Gallery."
945
  msgstr ""
946
 
947
+ #: includes/admin/metaboxes.php:1605
948
  msgid "Gallery Title"
949
  msgstr ""
950
 
951
+ #: includes/admin/metaboxes.php:1609
952
  msgid "Internal gallery title for identification in the admin."
953
  msgstr ""
954
 
955
+ #: includes/admin/metaboxes.php:1614
956
  msgid "Gallery Slug"
957
  msgstr ""
958
 
959
+ #: includes/admin/metaboxes.php:1618
960
  msgid "<strong>Unique</strong> internal gallery slug for identification and advanced gallery queries."
961
  msgstr ""
962
 
963
+ #: includes/admin/metaboxes.php:1623
964
  msgid "Custom Gallery Classes"
965
  msgstr ""
966
 
967
+ #: includes/admin/metaboxes.php:1626
968
  msgid "Enter custom gallery CSS classes here, one per line."
969
  msgstr ""
970
 
971
+ #: includes/admin/metaboxes.php:1627
972
  msgid "Adds custom CSS classes to this gallery. Enter one class per line."
973
  msgstr ""
974
 
975
+ #: includes/admin/metaboxes.php:1636
976
  msgid "Import/Export Gallery"
977
  msgstr ""
978
 
979
+ #: includes/admin/metaboxes.php:1649
980
  msgid "Import Gallery"
981
  msgstr ""
982
 
983
+ #: includes/admin/metaboxes.php:1656
984
  msgid "Export Gallery"
985
  msgstr ""
986
 
987
+ #: includes/admin/metaboxes.php:1666
988
  msgid "Enable RTL Support?"
989
  msgstr ""
990
 
991
+ #: includes/admin/metaboxes.php:1670
992
  msgid "Enables or disables RTL support in Envira for right-to-left languages."
993
  msgstr ""
994
 
995
+ #: includes/admin/metaboxes.php:1682 includes/admin/metaboxes.php:1724
996
+ #: includes/admin/metaboxes.php:1746 includes/admin/metaboxes.php:1768
997
+ #: includes/admin/metaboxes.php:1790 includes/admin/metaboxes.php:1812
998
  msgid "Want to take your galleries further?"
999
  msgstr ""
1000
 
1001
+ #: includes/admin/metaboxes.php:1683
1002
  msgid "By upgrading to Envira Pro, you can get access to numerous other features, including: a fully-integrated import/export module for your galleries, custom CSS controls for each gallery and so much more!"
1003
  msgstr ""
1004
 
1005
+ #: includes/admin/metaboxes.php:1704
1006
  msgid "Videos"
1007
  msgstr ""
1008
 
1009
+ #: includes/admin/metaboxes.php:1705
1010
  msgid "Social"
1011
  msgstr ""
1012
 
1013
+ #: includes/admin/metaboxes.php:1706
1014
  msgid "Tags"
1015
  msgstr ""
1016
 
1017
+ #: includes/admin/metaboxes.php:1707
1018
  msgid "Pagination"
1019
  msgstr ""
1020
 
1021
+ #: includes/admin/metaboxes.php:1725
1022
  msgid "By upgrading to Envira Pro, you can get access to mobile-specific settings, including mobile image sizes, number of columns, mobile-specific lightbox options and so much more!"
1023
  msgstr ""
1024
 
1025
+ #: includes/admin/metaboxes.php:1747
1026
  msgid "By upgrading to Envira Pro, you can add Videos to your Envira Galleries from YouTube, Vimeo, Wistia, and your own self-hosted videos!"
1027
  msgstr ""
1028
 
1029
+ #: includes/admin/metaboxes.php:1769
1030
  msgid "By upgrading to Envira Pro, you can add social sharing buttons to your Gallery images and Lightbox images. With support for Facebook, Twitter, Google+ and Pinterest why not check it out?"
1031
  msgstr ""
1032
 
1033
+ #: includes/admin/metaboxes.php:1791
1034
  msgid "By upgrading to Envira Pro, you can add Tags to your Gallery images, allow users to filter your Gallery by tag and so much more!"
1035
  msgstr ""
1036
 
1037
+ #: includes/admin/metaboxes.php:1813
1038
  msgid "By upgrading to Envira Pro, you can split your Gallery across multiple pages with pagination, load paginated images via AJAX, lazy loading and more!"
1039
  msgstr ""
1040
 
1041
+ #: includes/admin/metaboxes.php:2098
1042
  msgid "Remove Image from Gallery?"
1043
  msgstr ""
1044
 
1045
+ #: includes/admin/metaboxes.php:2099
1046
  msgid "Modify Image"
1047
  msgstr ""
1048
 
1307
  msgid "Six Columns (6)"
1308
  msgstr ""
1309
 
1310
+ #: includes/global/common.php:107 includes/global/common.php:249
1311
  msgid "Base"
1312
  msgstr ""
1313
 
1314
+ #: includes/global/common.php:128
1315
+ msgid "Normal"
1316
+ msgstr ""
1317
+
1318
+ #: includes/global/common.php:148
1319
  msgid "Do not display"
1320
  msgstr ""
1321
 
1322
+ #: includes/global/common.php:152
1323
  msgid "Display above galleries"
1324
  msgstr ""
1325
 
1326
+ #: includes/global/common.php:156
1327
  msgid "Display below galleries"
1328
  msgstr ""
1329
 
1330
+ #: includes/global/common.php:176
1331
  msgid "No Sorting"
1332
  msgstr ""
1333
 
1334
+ #: includes/global/common.php:180 includes/global/common.php:309
1335
  msgid "Random"
1336
  msgstr ""
1337
 
1338
+ #: includes/global/common.php:184
1339
  msgid "Published Date"
1340
  msgstr ""
1341
 
1342
+ #: includes/global/common.php:188
1343
  msgid "Filename"
1344
  msgstr ""
1345
 
1346
+ #: includes/global/common.php:200
1347
  msgid "Alt"
1348
  msgstr ""
1349
 
1350
+ #: includes/global/common.php:224
1351
  msgid "Ascending (A-Z)"
1352
  msgstr ""
1353
 
1354
+ #: includes/global/common.php:228
1355
  msgid "Descending (Z-A)"
1356
  msgstr ""
1357
 
1358
+ #: includes/global/common.php:329
1359
  msgid "Float"
1360
  msgstr ""
1361
 
1362
+ #: includes/global/common.php:333
1363
  msgid "Float (Wrapped)"
1364
  msgstr ""
1365
 
1366
+ #: includes/global/common.php:337 includes/global/common.php:365
1367
  msgid "Inside"
1368
  msgstr ""
1369
 
1370
+ #: includes/global/common.php:341 includes/global/common.php:369
1371
  msgid "Outside"
1372
  msgstr ""
1373
 
1374
+ #: includes/global/common.php:345
1375
  msgid "Over"
1376
  msgstr ""
1377
 
1378
+ #: includes/global/common.php:389
1379
  msgid "No Effect"
1380
  msgstr ""
1381
 
1382
+ #: includes/global/common.php:393
1383
  msgid "Fade"
1384
  msgstr ""
1385
 
1386
+ #: includes/global/common.php:397
1387
  msgid "Elastic"
1388
  msgstr ""
1389
 
1390
+ #: includes/global/common.php:445
1391
  msgid "Swing"
1392
  msgstr ""
1393
 
1394
+ #: includes/global/common.php:501 includes/global/common.php:525
1395
  msgid "Top"
1396
  msgstr ""
1397
 
1398
+ #: includes/global/common.php:505 includes/global/common.php:529
1399
  msgid "Bottom"
1400
  msgstr ""
1401
 
1402
+ #: includes/global/common.php:672
1403
  msgid "Image Files"
1404
  msgstr ""
1405
 
1406
+ #: includes/global/common.php:722
1407
  msgid "Before Existing Images"
1408
  msgstr ""
1409
 
1410
+ #: includes/global/common.php:726
1411
  msgid "After Existing Images"
1412
  msgstr ""
1413
 
1414
+ #: includes/global/common.php:750
1415
  msgid "Yes"
1416
  msgstr ""
1417
 
1418
+ #: includes/global/common.php:830
1419
  msgid "No image editor could be selected. Please verify with your webhost that you have either the GD or Imagick image library compiled with your PHP install on your server."
1420
  msgstr ""
1421
 
1422
+ #: includes/global/common.php:933
1423
  msgid "No image URL specified for cropping."
1424
  msgstr ""
1425
 
1426
+ #: includes/global/common.php:952
1427
  msgid "No file could be found for the image URL specified."
1428
  msgstr ""
1429
 
1430
+ #: includes/global/common.php:960 includes/global/common.php:972
1431
  msgid "The dimensions of the original image could not be retrieved for cropping."
1432
  msgstr ""
1433
 
1467
  msgid "No Envira galleries found in trash."
1468
  msgstr ""
1469
 
1470
+ #: includes/global/shortcode.php:868
1471
  msgid "The requested content cannot be loaded.<br/>Please try again later.</p>"
1472
  msgstr ""
1473
 
1474
+ #: includes/global/shortcode.php:869 includes/global/shortcode.php:1514
1475
  msgid "Close"
1476
  msgstr ""
1477
 
1478
+ #: includes/global/shortcode.php:870 includes/global/shortcode.php:1504
1479
  msgid "Next"
1480
  msgstr ""
1481
 
1482
+ #: includes/global/shortcode.php:871 includes/global/shortcode.php:1500
1483
  msgid "Previous"
1484
  msgstr ""
1485
 
readme.txt CHANGED
@@ -185,6 +185,15 @@ Also, I'm an <a href="https://thomasgriffin.io" rel="me" title="WordPress Develo
185
 
186
  == Changelog ==
187
 
 
 
 
 
 
 
 
 
 
188
  = 1.5.0.7 =
189
  * Fix: Addressing "unexpected end of input" JS Error.
190
 
185
 
186
  == Changelog ==
187
 
188
+ = 1.5.1 =
189
+ * Added: A justified layout replaces the old "automatic" layout setting for galleries. See documentation on enviragallery.com for additional information.</li>
190
+ * Updated: Spanish translation.</li>
191
+ * Fix: Removing "Insert From Url" option for galleries.</li>
192
+ * Fix: Gallery display follows settings properly when WPML is used in certain cirucmstances.</li>
193
+
194
+ = 1.5.0.8 =
195
+ * Fix: Fix: Close button in lightbox admin bar should not jump position with longer gallery titles.
196
+
197
  = 1.5.0.7 =
198
  * Fix: Addressing "unexpected end of input" JS Error.
199