title: jQuery.Popup is not a constructor & Query is not defined(anonymous function)
body: <p>I've come to the tail end of a module I'm creating for Magento 2 but I'm having trouble getting it to render on the screen. This code has worked on other sites in the past but there seems to be an issue stopping this one from working. The issue seems to be with my code "var popup = new jQuery.Popup(poOptions);" note being recognized as a constructor.</p>
  
  <p>I read through a few similar posts (like this one <a href="https://stackoverflow.com/questions/43392341/wow-is-not-a-constructor">WOW is not a constructor</a>) but I can't seem to figure out what the issue is still</p>
  
  <p>The jquery plugin I'm utilizing originates from <a href="https://github.com/Toddish/Popup" rel="nofollow noreferrer">https://github.com/Toddish/Popup</a>, on our website page here <a href="https://76a8q06e6vrsbggs.mojostratus.io/catalog/product/view/id/44/s/2018-official-joules-vest/category/5/" rel="nofollow noreferrer">https://76a8q06e6vrsbggs.mojostratus.io/catalog/product/view/id/44/s/2018-official-joules-vest/category/5/</a></p>
  
  <p>The idea is you add some custom text in the field labeled "personalize", click the preview button, and a window opens up showing the custom text you had on the item. The link the code constructs works fine, its the actual popup that renders the image that is the issue. I'm adding the code that seems relevant to the situation, hope someone can help me out here this has been a headscratcher especially since it works a lot of times, but <strong>if you refresh enough it breaks and I don't understand why</strong>.
  Can anyone out there help me figure this out?  </p>
  
  <p><strong>EDIT:</strong> I removed an additional jQuery Library call that seemed to be triggering some errors, having said that, it's still inconsistently working because sometimes I get the "(index):2025 Uncaught ReferenceError: jQuery is not defined" error.</p>
  
  <pre><code> &lt;script type="text/javascript"&gt;
          var liquifireArguments = [];
          /*-------------------------------
              POPUP.JS
              Simple Popup plugin for jQuery
              @author Todd Francis
              @version 2.2.3
          -------------------------------*/
  
          ;(function($, window){
  
              'use strict';
  
              /**
               * Popup jQuery method
               *
               * @param  {Object} settings
               * @return {Object}
               */
              $.fn.popup = function(settings){
  
                  var selector = this.selector,
                      popup = new $.Popup(settings);
  
                  $(document)
                      .on('click.popup', selector, function(e){
  
                          var content = settings &amp;&amp; settings.content
                              ? settings.content
                              : $(this).attr('href');
  
                          e.preventDefault();
  
                          popup.open(content, undefined, this);
  
                      });
  
                  return this.each(function(){
  
  
                      $(this)
                          .data('popup', popup);
  
                  });
  
              };
  
              /**
               * Main Popup Class
               *
               * @param {Object} settings
               */
              $.Popup = function(settings)
              {
  
                  var p = this,
                      defaults = {
  
                          // Markup
                          backClass : 'popup_back',
                          backOpacity : 0.7,
                          containerClass : 'popup_cont',
                          closeContent : '&lt;div class="popup_close"&gt;&amp;times;&lt;/div&gt;',
                          markup : '&lt;div class="popup"&gt;&lt;div class="popup_content"/&gt;&lt;/div&gt;',
                          contentClass : 'popup_content',
                          preloaderContent : '&lt;p class="preloader"&gt;&amp;nbsp;&lt;/p&gt;',
                          activeClass : 'popup_active',
                          hideFlash : false,
                          speed : 200,
                          popupPlaceholderClass : 'popup_placeholder',
                          keepInlineChanges :  true,
  
                          // Content
                          modal : false,
                          content : null,
                          type : 'auto',
                          width : null,
                          height : null,
  
                          // Params
                          typeParam : 'pt',
                          widthParam : 'pw',
                          heightParam : 'ph',
  
                          // Callbacks
                          beforeOpen : function(type){},
                          afterOpen : function(){},
                          beforeClose : function(){},
                          afterClose : function(){},
                          error : function(){},
                          show : function($popup, $back){
  
                              var plugin = this;
  
                              // Center the popup
                              plugin.center();
  
                              // Animate in
                              $popup
                                  .animate({opacity : 1}, plugin.o.speed, function(){
                                      // Call the open callback
                                      plugin.o.afterOpen.call(plugin);
                                  });
  
                          },
                          replaced : function($popup, $back){
  
                              // Center the popup and call the open callback
                              this
                                  .center()
                                  .o.afterOpen.call(this);
  
                          },
                          hide : function($popup, $back){
  
                              if( $popup !== undefined ){
  
                                  // Fade the popup out
                                  $popup.animate({opacity : 0}, this.o.speed);
  
                              }
  
                          },
                          types : {
                              inline : function(content, callback){
  
                                  var $content = $(content);
  
                                  $content
                                      .addClass(p.o.popupPlaceholderClass);
  
                                  // If we don't want to keep any inline changes,
                                  // get a fresh copy now
                                  if( !p.o.keepInlineChanges ){
                                      cachedContent = $content.html();
                                  }
  
                                  callback.call(this, $content.children());
  
                              },
                              image : function(content, callback){
  
                                  var plugin = this;
                                  var mw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0)-100;
                                  var mh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0)-100;
  
                                  var $image = $('&lt;img /&gt;')
                                      .one('load', function(){
  
                                          var img = this;
  
                                          // Timeout for Webkit
                                          // As the width/height of the image is 0 initially
                                          setTimeout(function(){
  
                                              callback.call(plugin, img);
  
                                          }, 0);
  
                                      })
                                      .one('error', function(){
  
                                          p.o.error.call(p, content, 'image');
  
                                      })
                                      .attr('src', content)
                                      .css('max-width',mw)
                                      .css('max-height',mh)
                                      .each(function() {
  
                                          if( this.complete ){
  
                                              $(this).trigger('load');
  
                                          }
  
                                      });
  
                              },
                              external : function(content, callback){
  
                                  var $frame = $('&lt;iframe /&gt;')
                                      .attr({
                                          src : content,
                                          frameborder : 0,
                                          width : p.width,
                                          height : p.height
                                      });
  
                                  callback.call(this, $frame);
  
                              },
                              html                    : function(content, callback){
  
                                  callback.call(this, content);
  
                              },
                              jQuery                  : function(content, callback){
  
                                  callback.call(this, content.html());
  
                              },
                              'function'              : function(content, callback){
  
                                  callback.call(this, content.call(p));
  
                              },
                              ajax                    : function(content, callback){
  
                                  $.ajax({
                                      url : content,
                                      success : function(data){
                                          callback.call(this, data);
                                      },
                                      error : function(data){
                                          p.o.error.call(p, content, 'ajax');
                                      }
                                  });
  
                              }
                          }
                      },
                      imageTypes = ['png', 'jpg', 'gif'],
                      type,
                      cachedContent,
                      $back,
                      $pCont,
                      $close,
                      $preloader,
                      $p;
  
                  p.ele = undefined;
  
                  p.o = $.extend(true, {}, defaults, settings);
  
                  /**
                   * Opens a new popup window
                   *
                   * @param  {string} content
                   * @param  {string} popupType
                   * @param  {Object} ele
                   * @return {void}
                   */
                  p.open = function(content, popupType, ele){
  
                      // Get the content
                      content = ( content === undefined || content === '#' )
                          ? p.o.content
                          : content;
  
                      // If no content is set
                      if( content === null ){
  
                          p.o.error.call(p, content, type);
                          return false;
  
                      }
  
                      // Was an element passed in?
                      if( ele !== undefined ){
  
                          // Remove current active class
                          if( p.ele &amp;&amp; p.o.activeClass ){
  
                              $(p.ele).removeClass(p.o.activeClass);
  
                          }
  
                          // Record the element
                          p.ele = ele;
  
                          // Add an active class
                          if( p.ele &amp;&amp; p.o.activeClass ){
  
                              $(p.ele).addClass(p.o.activeClass);
  
                          }
  
                      }
  
                      // If we're not open already
                      if( $back === undefined ){
  
                          // Create back and fade in
                          $back = $('&lt;div class="'+p.o.backClass+'"/&gt;')
                              .appendTo($('body'))
                              .css('opacity', 0)
                              .animate({
                                  opacity : p.o.backOpacity
                              }, p.o.speed);
  
                          // If modal isn't specified, bind click event
                          if( !p.o.modal ){
  
                              $back.one('click.popup', function(){
                                  p.close();
                              });
  
                          }
  
                          // Should we hide the flash?
                          if( p.o.hideFlash ){
  
                              $('object, embed').css('visibility', 'hidden');
  
                          }
  
                          // Preloader
                          if( p.o.preloaderContent ){
  
                              $preloader = $(p.o.preloaderContent)
                                  .appendTo($('body'));
  
                          }
  
                      }
  
                      // Get the popupType
                      popupType = getValue([popupType, p.o.type]);
  
                      // If it's at auto, guess a real type
                      popupType = ( popupType === 'auto' )
                          ? guessType(content)
                          : popupType;
  
                      // Cache the type to use globally
                      type = popupType;
  
                      // Do we have a width set?
                      p.width = ( p.o.width )
                          ? p.o.width
                          : null;
  
                      // Do we have a height set?
                      p.height = ( p.o.height )
                          ? p.o.height
                          : null;
  
                      // If it's not inline, jQuery or a function
                      // it might have params, and they are top priority
                      if( $.inArray(popupType, ['inline', 'jQuery', 'function']) === -1 ){
  
                          var paramType = getParameterByName(p.o.typeParam, content),
                              paramWidth = getParameterByName(p.o.widthParam, content),
                              paramHeight = getParameterByName(p.o.heightParam, content);
  
                          // Do we have an overriding paramter?
                          popupType = ( paramType !== null )
                              ? paramType
                              : popupType;
  
                          // Do we have an overriding width?
                          p.width = ( paramWidth !== null )
                              ? paramWidth
                              : p.width;
  
                          // Do we have an overriding height?
                          p.height = ( paramHeight !== null )
                              ? paramHeight
                              : p.height;
                      }
  
                      // Callback
                      p.o.beforeOpen.call(p, popupType);
  
                      // Show the content based
                      if( p.o.types[popupType] ){
  
                          p.o.types[popupType].call(p, content, showContent);
  
                      }else{
  
                          p.o.types.ajax.call(p, content, showContent);
  
                      }
  
                  };
  
                  /**
                   * Return the correct value to be used
                   *
                   * @param  {array} items
                   * @return {mixed}
                   */
                  function getValue(items){
  
                      var finalValue;
  
                      $.each(items, function(i, value){
  
                          if( value ){
                              finalValue = value;
                              return false;
                          }
  
                      });
  
                      return finalValue;
  
                  }
  
                  /**
                   * Guess the type of content to show
                   *
                   * @param  {string|Object|function} content
                   * @return {string}
                   */
                  function guessType(content){
  
                      if( typeof content === 'function' ){
  
                          return 'function';
  
                      } else if( content instanceof $ ){
  
                          return 'jQuery';
  
                      } else if( content.substr(0, 1) === '#' || content.substr(0, 1) === '.' ){
  
                          return 'inline';
  
                      } else if( $.inArray(content.substr(content.length - 3), imageTypes) !== -1 ) {
  
                          return 'image';
  
                      } else if( content.substr(0, 4) === 'http' ) {
  
                          return 'external';
  
                      }else{
  
                          return 'ajax';
  
                      }
  
                  }
  
                  /**
                   * Shows the content
                   *
                   * @param  {string} content
                   * @return {void}
                   */
                  function showContent(content){
  
                      // Do we have a preloader?
                      if( $preloader ){
  
                          // If so, hide!
                          $preloader.fadeOut('fast', function(){
  
                              $(this).remove();
  
                          });
  
                      }
  
                      // Presume we're replacing
                      var replacing = true;
  
                      // If we're not open already
                      if( $pCont === undefined ){
  
                          // We're not replacing!
                          replacing = false;
  
                          // Create the container
                          $pCont = $('&lt;div class="'+p.o.containerClass+'"&gt;');
  
                          // Add in the popup markup
                          $p = $(p.o.markup)
                              .appendTo($pCont);
  
                          // Add in the close button
                          $close = $(p.o.closeContent)
                              .one('click', function(){
  
                                  p.close();
  
                              })
                              .appendTo($pCont);
  
                          // Bind the resize event
                          $(window).resize(p.center);
  
                          // Append the container to the body
                          // and set the opacity
                          $pCont
                              .appendTo($('body'))
                              .css('opacity', 0);
  
                      }
  
                      // Get the actual content element
                      var $pContent = $('.'+p.o.contentClass, $pCont);
  
                      // Do we have a set width/height?
                      if( p.width ){
  
                          $pContent.css('width', p.width, 10);
  
                      }else{
  
                          $pContent.css('width', '');
                          var mw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0)-100;
                          $pContent.css('max-width', mw);
                      }
  
                      if( p.height ){
  
                          $pContent.css('height', p.height, 10);
  
                      }else{
  
                          $pContent.css('height', '');
                          var mh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0)-100;
                          $pContent.css('max-height', mh);
  
                      }
  
                      // Put the content in place!
                      if( $p.hasClass(p.o.contentClass) ){
  
                          $p
                              .html(content);
  
                      }else{
  
                          $p
                              .find('.'+p.o.contentClass)
                              .html(content);
  
                      }
  
                      // Callbacks!
                      if( !replacing ){
  
                          p.o.show.call(p, $pCont, $back);
  
                      }else{
  
                          p.o.replaced.call(p, $pCont, $back);
  
                      }
  
                  }
  
                  /**
                   * Close the popup
                   *
                   * @return {Object}
                   */
                  p.close = function(){
  
                      p.o.beforeClose.call(p);
  
                      // If we got some inline content, cache it
                      // so we can put it back
                      if(
                          type === 'inline' &amp;&amp;
                          p.o.keepInlineChanges
                      ){
                          cachedContent = $('.'+p.o.contentClass).html();
                      }
  
                      if( $back !== undefined ){
  
                          // Fade out the back
                          $back.animate({opacity : 0}, p.o.speed, function(){
  
                              // Clean up after ourselves
                              p.cleanUp();
  
                          });
  
                      }
  
                      // Call the hide callback
                      p.o.hide.call(p, $pCont, $back);
  
                      return p;
  
                  };
  
                  /**
                   * Clean up the popup
                   *
                   * @return {Object}
                   */
                  p.cleanUp = function(){
  
                      $back
                          .add($pCont)
                          .remove();
  
                      $pCont = $back = undefined;
  
                      // Unbind the resize event
                      $(window).unbind('resize', p.center);
  
                      // Did we hide the flash?
                      if( p.o.hideFlash ){
  
                          $('object, embed').css('visibility', 'visible');
  
                      }
  
                      // Remove active class if we can
                      if( p.ele &amp;&amp; p.o.activeClass ){
  
                          $(p.ele).removeClass(p.o.activeClass);
  
                      }
  
                      var $popupPlaceholder = $('.'+p.o.popupPlaceholderClass);
  
                      // If we got inline content
                      // put it back
                      if(
                          type == 'inline' &amp;&amp;
                          $popupPlaceholder.length
                      ){
                          $popupPlaceholder
                              .html(cachedContent)
                              .removeClass(p.o.popupPlaceholderClass);
                      }
  
                      type = null;
  
                      // Call the afterClose callback
                      p.o.afterClose.call(p);
  
                      return p;
  
                  };
  
                  /**
                   * Centers the popup
                   *
                   * @return {Object}
                   */
                  p.center = function(){
  
                      $pCont.css(p.getCenter());
  
                      // Only need force for IE6
                      $back.css({
                          height : document.documentElement.clientHeight
                      });
  
                      return p;
  
                  };
  
                  /**
                   * Get the center co-ordinates
                   *
                   * Returns the top/left co-ordinates to
                   * put the popup in the center
                   *
                   * @return {Object} top/left keys
                   */
                  p.getCenter = function(){
  
                      var pW = $pCont.children().outerWidth(true),
                          pH = $pCont.children().outerHeight(true),
                          wW = document.documentElement.clientWidth,
                          wH = document.documentElement.clientHeight;
  
                      return {
                          top : wH * 0.5 - pH * 0.5,
                          left : wW * 0.5 - pW * 0.5
                      };
  
                  };
  
                  /**
                   * Get parameters by name
                   * @param  {string} name
                   * @return {null|string} null if not found
                   */
                  function getParameterByName(name, url){
  
                      var match = new RegExp('[?&amp;]'+name+'=([^&amp;]*)')
                          .exec(url);
  
                      return match &amp;&amp; decodeURIComponent(match[1].replace(/\+/g, ' '));
  
                  }
  
              };
  
          }(jQuery, window));
      &lt;/script&gt;
  </code></pre>
  
  <p></p>
  
  <pre><code>        /*optionId = InputId Of Personalization field*/
  
          var personalizedField = document.getElementsByClassName('product-custom-option')[0].id;
          //!TODO: String/VAR TO ARRAY
          // console.log('personalizedField: ' + personalizedField);
  
          arguments = {optionId:personalizedField, argument:'&lt;?= $liquifire_argument ?&gt;'};
          // console.log("arguments: " + arguments);
          liquifireArguments.push(arguments);
  
          jQuery( document ).ready(function(){
              function lpiEncode(str) {
                  var encoded = str;
                  encoded = encoded.replace(/&amp;/g, "U0026amp;");
                  encoded = encoded.replace(/'/g, "U0027");
                  encoded = encoded.replace(/\(/g, "U0026lp;");
                  encoded = encoded.replace(/\)/g, "U0026rp;");
                  encoded = encoded.replace(/\[/g, "U005B");
                  encoded = encoded.replace(/\]/g, "U005D");
                  encoded = encoded.replace(/\`/g, "U0060");
                  encoded = encoded.replace(/\+/g, "%2b");
                  return encoded;
              }
              jQuery('#product-options-wrapper').append('&lt;div class="lp-box"&gt;&lt;button type="button" title="Preview" class="button" id="liquifire-preview"&gt;&lt;span&gt;&lt;span&gt;Preview&lt;/span&gt;&lt;/span&gt;&lt;/button&gt;&lt;/div&gt;');
              jQuery('#liquifire-preview').click(function(){
                  //jQuery('.mousetrap').addClass('liquidpixels');
                  var liquifireUrl = 'https://urm.liquifire.com/urm';
                  var liquifireChain = '&lt;?= $image_chain ?&gt;';
                  var imageUrl = liquifireUrl + '?';
                  // console.log("liquifireUrl: " + liquifireUrl);
                  // console.log("liquifireChain: " + liquifireChain);
                  // console.log("imageUrl: " + imageUrl);
  
                  jQuery.each(liquifireArguments, function(){
                      optionValue = document.getElementById(this.optionId).value;
                      if( optionValue !== ''){
                          var argument = this.argument;
  
                          if(liquifireArguments.indexOf(this) === 0){
                              imageUrl += 'set=';
                          }else{
                              imageUrl += ',';
                          }
                          // Add variable and value
                          imageUrl += argument + '[' + lpiEncode(optionValue) + ']';
                      }
                  });
  
                  if(document.getElementById('select_label_color')) {
                      lpcolor = document.getElementById('select_label_color').textContent.toLowerCase();
                      if( lpcolor !== ''){
                          imageUrl += ',selColor[' + lpcolor + '.jpg]';
                      }
                  }
  
                  // Zoom Url
                  zoomUrl = imageUrl + '&amp;call=url[file:' + liquifireChain + ']&amp;scale=size[1000]&amp;sink';
                  // console.log('zoomUrl: '+ zoomUrl);
  
                  // Add image chain
                  imageUrl += '&amp;call=url[file:' + liquifireChain + ']&amp;scale=size[900]&amp;sink';
                  // console.log('imageUrl: '+ imageUrl);
  
                  var poOptions = { type : 'image' };
                  var popup = new jQuery.Popup(poOptions);
  
  
  
                  popup.open(zoomUrl);
              });
  
          });
  
  
      &lt;/script&gt;
  </code></pre>