<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">// BETA VERSION -- 6/30/17
// TODO: need to test all link and slideshow senarios
// TODO: when textOverImage is false cardItem needs to be flexed
// FIXME: slideshow loop + link all causes a problem with cloned items
// NOTE: refer to https://owlcarousel2.github.io/OwlCarousel2/docs/started-welcome.html for carousel options


extend(saffire, {
  widgets: {
    cardWidget: function(el, opts) {
      var $el = el;
      var widget = {};
      var defaults = {
        buyNowButton: {
          visible: true,
          text: 'BUY NOW'
        },
        cardWidgetLoaded: function(data, owl, hasData) {},
        contentType: 'application/json; charset=utf-8',
        currentWidgetModuleItemID: 0,
        dataType: 'json',
        itemsPerPanel: 1,
        hasImages: true,
        lazyLoadImages: true,
        imageIsBackground: true,
        link: [], // [], ['all'], ['image', 'title', 'description']
        maxItemsVisible: 4,
        moreButton: {
          visible: true,
          text: 'MORE &gt;'
        },
        scriptPath: "services/eventsservice.asmx",
        showDescription: false,
        slideshow: false,
        slideshowOptions: {
          loop: true,
          margin: 10,
          nav: true
        },
        textOverImage: true
      };

      opts = extend(defaults, opts);

      /**
       * Retreives data for the widget.
       * @protected
       */
      widget.data = saffire.utils.getWidgetData(opts);
      widget.data.then(function(res) {
        widget.items = res.Sponsors || res.Slides;
        (widget.items.length &lt; 1) ? widget.noData(res): widget.setup(res);
      });

      /**
       * Sets up the HTML for the Widget.
       * @public
       */
      widget.setup = function(data) {
        $el.addClass('loading');
        // convert image links to SSL if the page is encrypted
        PAGESSL ? convertSources() : null;

        // initialize an array to hold the card items
        widget.cards = [];

        // what needs to be links?
        var linkAll = opts.link.indexOf('all') &gt; -1;
        var linkImage = opts.link.indexOf('image') &gt; -1;
        var linkTitle = opts.link.indexOf('title') &gt; -1;
        var linkDescription = opts.link.indexOf('description') &gt; -1;

        // build widget content
        this.items.map(function(item, index) {
          if (((index + 1) &lt;= opts.maxItemsVisible) || opts.maxItemsVisible === 0) {

            var cardItem = new Element(item, 'card-widget-item', linkAll, 'div', '');
            var cardContent = new Element(item, 'card-content', (linkTitle &amp;&amp; linkDescription), 'div', '');
            var buttonWrap = new Element(item, 'buttonwrap', false, 'div', widget.buildButtons(item));
            var title = new Element(item, 'card-widget-title', (linkTitle &amp;&amp; !linkDescription), 'span', item.Title);

            // add contents to the text and button container
            cardContent.$html.append(title.$html);
            if (opts.showDescription) {
              var description = new Element(item, 'card-widget-description', (!linkTitle &amp;&amp; linkDescription), 'span', item.Description);
              cardContent.$html.append(description.$html);
            }
            cardContent.$html.append(buttonWrap.$html);

            // determine if the card has an image and how to attach it
            // TODO: lines 85 - 103 could be simplified
            if (opts.hasImages &amp;&amp; (item.ImageWithPath !== null)) {
                var image = new Element(item, 'image-container', linkImage, 'div', '');
                var imageAlternateText = "";

                if (item.ImageAlternateText !== null) {
                    imageAlternateText = (item.ImageAlternateText);
                }


              if (opts.imageIsBackground) {
                var imgPath = item.ImageWithPath;
                var cleanImgPath = imgPath.replace(/(?=[() ])/g, '\\');
                if (opts.lazyLoadImages) {
                  image.$html.addClass('lozad');
                  image.$html.attr('data-background-image', cleanImgPath);
                } else {
                  image.$html.attr('style', 'background-image:url(\'' + cleanImgPath + '\');');
                }
              } else {
                if (opts.lazyLoadImages) {
                  image.$html.append('&lt;img \
                    class="card-widget-image lozad" \
                    src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" \
                    data-src="'+ item.ImageWithPath +'" \
                  alt="' + imageAlternateText + '" \
                  &gt;');
                } else {
                    image.$html.append('&lt;img class="card-widget-image" src="' + item.ImageWithPath + '" alt="' + imageAlternateText + '"&gt;');
                }
              }

              if (opts.textOverImage) {
                image.$html.append(cardContent.$html);
                cardItem.$html.append(image.$html);
              } else {
                cardItem.$html.append(image.$html);
                cardItem.$html.append(cardContent.$html);
              }
            } else {
              cardItem.$html.append(cardContent.$html);
            }

            widget.cards.push(cardItem.$html);
            // $el.append(cardItem.$html);
          }
        });

        attachCards();

        // initialize widget
        // widget.initialize();
      }


      /**
       * Returns HTML buttons for the card
       * @protected
       */
      widget.buildButtons = function(data) {
        var target = data.URLOpenInANewWindow ? ' target="_blank"' : '';
        var buyButton = (opts.buyNowButton.visible &amp;&amp; data.PurchaseURL) ? '&lt;a class="buyNowButton" href="' + data.PurchaseURL + '" ' + target + '&gt;' + opts.buyNowButton.text + '&lt;/a&gt;' : '';
        var moreButton = (opts.moreButton.visible &amp;&amp; data.URL) ? '&lt;a class="moreButton" href="' + data.URL + '" ' + target + '&gt;' + opts.moreButton.text + '&lt;/a&gt;' : '';

        return buyButton + moreButton;
      }


      /**
       * Initialize slidshow if available and call loaded callback
       * @public
       */
      widget.initialize = function() {
        if (opts.slideshow) {
          $el.addClass('owl-carousel');
          widget.owl = $el.owlCarousel(opts.slideshowOptions);
        }
        opts.cardWidgetLoaded(widget, widget.owl, true); // callback if needed for the constructor
        $el.removeClass('loading');
        // lazyLoadStuff();
        var observer = lozad('.lozad', {
          rootMargin: '200px 0px', // syntax similar to that of CSS Margin
          threshold: 0.1 // ratio of element convergence
        });
        observer.observe();
      }

      /**
       * Attaches cards to the DOM
       * @protected
       */
      function attachCards() {

        if (opts.slideshow &amp;&amp; opts.itemsPerPanel &gt; 1) {
          var panels = [];
          var content = '';

          for (var i = 0; i &lt; widget.cards.length; i++) {
            var endOfArray = i === (widget.cards.length - 1);
            if ( (i !== 0) &amp;&amp; (i % opts.itemsPerPanel === 0)) {
              panels.push(new Element('', 'carousel-panel', false, 'div', content));
              content = widget.cards[i].prop('outerHTML');
              if (endOfArray) {
                panels.push(new Element('', 'carousel-panel', false, 'div', content));
              }
            } else {
              content += widget.cards[i].prop('outerHTML');
              if (endOfArray) {
                panels.push(new Element('', 'carousel-panel', false, 'div', content));
              }
            }
          }
          for (var i = 0; i &lt; panels.length; i++) {
            $el.append(panels[i].$html);
          }
        } else {
          for (var i = 0; i &lt; widget.cards.length; i++) {
            $el.append(widget.cards[i]);
          }
        }

        widget.initialize();
      }

      /**
       * Converts the image links in widget.items to be SSL call.
       * @protected
       */
      function convertSources() {
        for (var i = 0; i &lt; widget.items.length; i++) {
			if(widget.items[i].ImageWithPath){
				widget.items[i].ImageWithPath = widget.items[i].ImageWithPath.replace(/^http:\/\//i, 'https://');
			}
        }
      }

      /**
       * html object constructor
       * @protected
       */
      function Element(item, customClass, link, type, content) {
        if (link) {
          this.class = item.URL ? '' : 'void-link';
          this.url = item.URL || 'javascript:void(0);';
          this.target = item.URLOpenInANewWindow ? ' target="_blank"' : '';
          this.$html = $('&lt;a href="' + this.url + '" class="' + customClass + ' ' + this.class + '" ' + this.target + '&gt;' + content + '&lt;/a&gt;');
        } else {
          // TODO: This section could be simplified
          if (type === 'div') {
            this.$html = $('&lt;div class="' + customClass + '"&gt;' + content + '&lt;/div&gt;');
          } else if (type === 'span') {
            this.$html = $('&lt;span class="' + customClass + '"&gt;' + content + '&lt;/span&gt;');
          } else {
            this.$html = '';
            console.log("Element constructor recieved Invalid data");
            console.log(item, customClass, link, type, content);
          }
        }

      }



      /**
       * There weren't any images returned from the call
       * @protected
       */
      widget.noData = function(data) {
        var id = $el.attr('id');
        console.log("Service returned no data for " + id, data);
        $('body').addClass(id + '-no-data');
        opts.cardWidgetLoaded(widget, widget.owl, false);
      };

      /**
       * public API.
       * @public
       */
      return {
        data: widget.data,
        options: opts,
        owl: function() {
          return widget.owl;
        },
        reinitialize: function() {
          widget.initialize();
        }
      };

    }

  }
});
</pre></body></html>