<commit_before>function fetchUploads() {

    (function ($) {
        var tempScrollTop = $(window).scrollTop();
        $(".uploads").remove();
        var url = '/api/status';

        $.ajax(
            {
                url: url,
                async: false,

                success: function (json) {
                    $.each(json, function () {
                        var oneGB = 1024 * 1024 * 1024;
                        var oneMB = 1024 * 1024;
                        var oneKB = 1024;

                        var speed;
                        var completed;
                        var remaining = this.totalSize - this.uploadedSize;

                        if (this.speed > oneGB)
                            speed = (this.speed / oneGB).toFixed(1) + ' GBps';
                        else if (this.speed > oneMB)
                            speed = (this.speed / oneMB).toFixed(1) + ' MBps';
                        else if (this.speed > oneKB)
                            speed = (this.speed / oneKB).toFixed(1) + ' KBps';
                        else
                            speed = this.speed + " Bps";

                        if (this.uploadedSize > oneGB)
                            completed = (this.uploadedSize / oneGB).toFixed(1) + ' GB';
                        else if (this.uploadedSize > oneMB)
                            completed = (this.uploadedSize / oneMB).toFixed(1) + ' MB';
                        else if (this.uploadedSize > oneKB)
                            completed = (this.uploadedSize / oneKB).toFixed(1) + ' KB';
                        else
                            completed = this.uploadedSize + " B";

                        if (remaining > oneGB)
                            remaining = (remaining / oneGB).toFixed(1) + ' GB';
                        else if (remaining > oneMB)
                            remaining = (remaining / oneMB).toFixed(1) + ' MB';
                        else if (remaining > oneKB)
                            remaining = (remaining / oneKB).toFixed(1) + ' KB';
                        else
                            remaining = remaining + " B";

                        var completedPercentage = (this.uploadedSize / this.totalSize * 100).toFixed(1);

                        var background = '';

                        if (completedPercentage == 100)
                            background = 'bg-success';

                        var upload = '
' +
                            '
' +
                            '
' +
                            '
Name: ' + this.fileName + '
' +
                            '
 Status: ' + this.uploadStatus + '
' +
                            '
 Speed: ' + speed + '
' +
                            '
 Completed: ' + completed + '
' +
                            '
 Remaining: ' + remaining + '
' +
                            '
' +
                            '
' +
                            '
' + completedPercentage + '%
' +
                            '
' +
                            '
' +
                            '
' +
                            '
' +
                            '
';

                        $('.push').before(upload);
                        $(window).resize();
                    });
                },
                error: function (xhr) {
                    alert("An error occured: " + xhr.status + " " + xhr.statusText);
                }
            });
        $(window).scrollTop(tempScrollTop);
    })(jQuery);

}

jQuery(document).ready(function ($) {
    $(function () {
        setInterval(function () {
            fetchUploads();
        }, 1000);
    });
});<commit_msg>add code to handle when upload status is failed<commit_after>function fetchUploads() {

    (function ($) {
        var tempScrollTop = $(window).scrollTop();
        $(".uploads").remove();
        var url = '/api/status';

        $.ajax(
            {
                url: url,
                async: false,

                success: function (json) {
                    $.each(json, function () {
                        var oneGB = 1024 * 1024 * 1024;
                        var oneMB = 1024 * 1024;
                        var oneKB = 1024;

                        var speed;
                        var completed;
                        var remaining = this.totalSize - this.uploadedSize;

                        if (this.speed > oneGB)
                            speed = (this.speed / oneGB).toFixed(1) + ' GBps';
                        else if (this.speed > oneMB)
                            speed = (this.speed / oneMB).toFixed(1) + ' MBps';
                        else if (this.speed > oneKB)
                            speed = (this.speed / oneKB).toFixed(1) + ' KBps';
                        else
                            speed = this.speed + " Bps";

                        if (this.uploadedSize > oneGB)
                            completed = (this.uploadedSize / oneGB).toFixed(1) + ' GB';
                        else if (this.uploadedSize > oneMB)
                            completed = (this.uploadedSize / oneMB).toFixed(1) + ' MB';
                        else if (this.uploadedSize > oneKB)
                            completed = (this.uploadedSize / oneKB).toFixed(1) + ' KB';
                        else
                            completed = this.uploadedSize + " B";

                        if (remaining > oneGB)
                            remaining = (remaining / oneGB).toFixed(1) + ' GB';
                        else if (remaining > oneMB)
                            remaining = (remaining / oneMB).toFixed(1) + ' MB';
                        else if (remaining > oneKB)
                            remaining = (remaining / oneKB).toFixed(1) + ' KB';
                        else
                            remaining = remaining + " B";

                        var completedPercentage = (this.uploadedSize / this.totalSize * 100).toFixed(1);

                        var background = '';
                        var upload;

                        if(this.uploadStatus == failed)
                        {
                        	background = 'bg-danger';
                        	upload = '
' +
                            '
' +
                            '
' +
                            '
Name: ' + this.fileName + '
' +
                            '
 Status: ' + this.uploadStatus + '
' +
                            '
 Status: ' + this.errorMessage + '
' +
                            '
' +
                            '
' +
                            '
' + completedPercentage + '%
' +
                            '
' +
                            '
' +
                            '
' +
                            '
' +
                            '
';
                        }
                        else
                        {
                            if (completedPercentage == 100)
                                background = 'bg-success';

                        	upload = '
' +
                            '
' +
                            '
' +
                            '
Name: ' + this.fileName + '
' +
                            '
 Status: ' + this.uploadStatus + '
' +
                            '
 Speed: ' + speed + '
' +
                            '
 Completed: ' + completed + '
' +
                            '
 Remaining: ' + remaining + '
' +
                            '
' +
                            '
' +
                            '
' + completedPercentage + '%
' +
                            '
' +
                            '
' +
                            '
' +
                            '
' +
                            '
';

                        }

                        $('.push').before(upload);
                    });
                },
                error: function (xhr) {
                    alert("An error occured: " + xhr.status + " " + xhr.statusText);
                }
            });
        $(window).scrollTop(tempScrollTop);
    })(jQuery);

}

jQuery(document).ready(function ($) {
    $(function () {
        setInterval(function () {
            fetchUploads();
        }, 1000);
    });
});<|endoftext|>


<commit_before>angular.module( 'ngCurtain', [] )

.directive( 'ctnCurtains', function( $window, $document, $location ) {
  return {
    restrict: 'EA',
    transclude: true,
    replace: true,
    template: '

',
    scope: true,
    controller: function ( $scope, $element ) {
      $scope.window = angular.element( $window );
      var sections = $scope.sections = [];
      var windowHeight;
      var bodyHeight;
      var currentSectionIdx;
      var body = $document.find( 'body' );

      // FIXME: only works on webkit
      var scrollEl = body;

      /**
       * Used by the child ctnSection elements to register themselves as
       * sections within this curtain.
       */
      this.addSection = function ( section ) {
        sections.push( section );
      };

      /**
       * Change the current section.
       */
      this.setCurrent = $scope.setCurrent = function ( idx ) {
        if ( ! angular.isDefined( idx ) ) {
          var path = $location.path();
          angular.forEach( sections, function forEachSectionCheckLocation ( section, index ) {
            if ( section.path === path ) {
              currentSectionIdx = index;
            }
          });
        } else {
          currentSectionIdx = idx;
        }

        var currSection = sections[ currentSectionIdx ];

        angular.forEach( sections, function forEachRemoveCurrent ( section ) {
          section.isCurrent = false;
          section.isHidden = true;
        });

        currSection.isCurrent = true;
        currSection.isHidden = false;
        $location.path( currSection.path );

        if ( sections.length > currentSectionIdx + 1 ) {
          sections[ currentSectionIdx + 1 ].isHidden = false;
        }
      };

      /**
       * Based on the height of the window and the height of each section, set
       * the height of all sections.
       */
      $scope.configureSections = function configureSections () {
        var height, zidx, levelHeight = 0;
        windowHeight = $scope.window.prop( 'innerHeight' );
        bodyHeight = 0;

        angular.forEach( sections, function forEachSection ( section, index ) {

          /**
           * Covers are always the height of the window, whereas all other
           * sections are at a minimum the height of the window.
           */
          if ( section.isCover ) {
            height = windowHeight;
          } else {
            height = section.getHeight();
            height = height <= windowHeight ? windowHeight : height;
          }

          // set the current top position of the curtain
          section.levelHeight = levelHeight;

          // set the positions and make it so!
          section.height = height;
          section.zIndex = 999 - index;
          section.setPosition();

          // increase the body height
          bodyHeight += parseInt( section.height, 10 );

          // increment the current top position by this one's height
          levelHeight += section.height;

        });

        // set the calculated body height so there's something to scroll
        body.css( 'height', bodyHeight + 'px' );
      };

      /**
       * Handle the scrolling.
       */
      $scope.handleScroll = function handleScroll () {
        var documentTop = body.prop( 'scrollTop' );
        var currSection = sections[ currentSectionIdx ];
        var currSectionPos = currSection.levelHeight;
        var currSectionHeight = currSection.height;

        /**
         * If we're scrolling up to a new section...
         */
        if ( documentTop < currSectionPos && currentSectionIdx > 0 ) {
          currSection.translate( 0 );
          $scope.setCurrent( currentSectionIdx - 1 );
        }
        /**
         * If we're scrolling within the current section...
         */
        else if ( documentTop < ( currSectionPos + currSectionHeight ) ) {
          currSection.translate( -(documentTop - currSectionPos) );
        }
       /**
        * If we're scrolling down to a new section...
        */
        else {
          $scope.setCurrent( currentSectionIdx + 1 );
        }
      };

    },
    link: function link ( scope, element, attrs ) {
      scope.configureSections();
      scope.setCurrent();

      scope.window.bind( 'resize', function () { scope.$apply( scope.configureSections ); } );
      scope.window.bind( 'scroll', function () { scope.$apply( scope.handleScroll ); } );
    }
  };
})

.directive( 'ctnCurtain', function() {
  return {
    restrict: 'EA',
    transclude: true,
    replace: true,
    template: '

',
    scope: true,
    require: '^ctnCurtains',
    controller: function ( $scope, $element ) {

      $scope.setPosition = function setPosition () {
        if ( $scope.isCover ) {
          $element.css({
            minHeight: $scope.height + 'px',
            zIndex: $scope.zIndex
          });
        } else {
          $element.css({
            height: $scope.height + 'px',
            zIndex: $scope.zIndex
          });
        }
      };

      $scope.translate = function translate ( top ) {
        var prop = 'translateY('+top+'px) translateZ(0)';
        $element.css({
          transform: prop,
          '-webkit-transform': prop
        });
      };

      $scope.getHeight = function () {
        return $element.prop( 'offsetHeight' );
      };
    },
    link: function( scope, element, attrs, ctnCurtainsCtrl ) {
      ctnCurtainsCtrl.addSection( scope );
      scope.isCover = scope.$eval( attrs.ctnCover );
      scope.path = '/' + attrs.ctnCurtain;
    }
  };
})

;

<commit_msg>fix(*): prev curtain position was wrong by path<commit_after>angular.module( 'ngCurtain', [] )

.directive( 'ctnCurtains', function( $window, $document, $location ) {
  return {
    restrict: 'EA',
    transclude: true,
    replace: true,
    template: '

',
    scope: true,
    controller: function ( $scope, $element ) {
      $scope.window = angular.element( $window );
      var sections = $scope.sections = [];
      var windowHeight;
      var bodyHeight;
      var currentSectionIdx;
      var body = $document.find( 'body' );
      $scope.locationChangeFromScroll = false;

      // FIXME: only works on webkit
      var scrollEl = body;

      /**
       * Used by the child ctnSection elements to register themselves as
       * sections within this curtain.
       */
      this.addSection = function ( section ) {
        sections.push( section );
      };

      /**
       * Change the current section.
       */
      this.setCurrent = $scope.setCurrent = function ( idx ) {
        currentSectionIdx = idx || 0;

        var currSection = sections[ currentSectionIdx ];

        angular.forEach( sections, function forEachRemoveCurrent ( section ) {
          section.isCurrent = false;
          section.isHidden = true;
        });

        currSection.isCurrent = true;
        currSection.isHidden = false;
        $location.path( currSection.path );

        if ( sections.length > currentSectionIdx + 1 ) {
          sections[ currentSectionIdx + 1 ].isHidden = false;
        }
      };

      $scope.scrollTo = function scrollTo () {
        var path = $location.path();
        angular.forEach( sections, function forEachSectionCheckLocation ( section, index ) {
          if ( section.path === path ) {
            currentSectionIdx = index;
          }
        });
        currentSectionIdx = currentSectionIdx || 0;

        $scope.setCurrent( currentSectionIdx );
        body.prop( 'scrollTop', sections[ currentSectionIdx ].levelHeight );

        angular.forEach( sections, function forEachSectionCheckLocation ( section, index ) {
          if ( index < currentSectionIdx ) {
            section.translate( -(section.height) );
          }
        });
      };

      /**
       * Based on the height of the window and the height of each section, set
       * the height of all sections.
       */
      $scope.configureSections = function configureSections () {
        var height, zidx, levelHeight = 0;
        windowHeight = $scope.window.prop( 'innerHeight' );
        bodyHeight = 0;

        angular.forEach( sections, function forEachSection ( section, index ) {

          /**
           * Covers are always the height of the window, whereas all other
           * sections are at a minimum the height of the window.
           */
          if ( section.isCover ) {
            height = windowHeight;
          } else {
            height = section.getHeight();
            height = height <= windowHeight ? windowHeight : height;
          }

          // set the current top position of the curtain
          section.levelHeight = levelHeight;

          // set the positions and make it so!
          section.height = height;
          section.zIndex = 999 - index;
          section.setPosition();

          // increase the body height
          bodyHeight += parseInt( section.height, 10 );

          // increment the current top position by this one's height
          levelHeight += parseInt( section.height, 10 );

        });

        // set the calculated body height so there's something to scroll
        body.css( 'height', bodyHeight + 'px' );
      };

      /**
       * Handle the scrolling.
       */
      $scope.handleScroll = function handleScroll () {
        var documentTop = body.prop( 'scrollTop' );
        var currSection = sections[ currentSectionIdx ];
        var currSectionPos = currSection.levelHeight;
        var currSectionHeight = currSection.height;

        /**
         * If we're scrolling up to a new section...
         */
        if ( documentTop < currSectionPos && currentSectionIdx > 0 ) {
          currSection.translate( 0 );
          $scope.locationChangeFromScroll = true;
          $scope.setCurrent( currentSectionIdx - 1 );
        }
        /**
         * If we're scrolling within the current section...
         */
        else if ( documentTop < ( currSectionPos + currSectionHeight ) ) {
          currSection.translate( -(documentTop - currSectionPos) );
        }
       /**
        * If we're scrolling down to a new section...
        */
        else {
          $scope.locationChangeFromScroll = true;
          $scope.setCurrent( currentSectionIdx + 1 );
        }
      };

    },
    link: function link ( scope, element, attrs ) {
      scope.configureSections();
      scope.scrollTo();

      scope.window.bind( 'resize', function () { scope.$apply( scope.configureSections ); } );
      scope.window.bind( 'scroll', function () { scope.$apply( scope.handleScroll ); } );

      scope.$on( '$locationChangeSuccess', function locationChangeSuccessHandler ( path ) {
        if ( ! scope.locationChangeFromScroll ) {
          scope.scrollTo( path );
        }

        scope.locationChangeFromScroll = false;
      });
    }
  };
})

.directive( 'ctnCurtain', function() {
  return {
    restrict: 'EA',
    transclude: true,
    replace: true,
    template: '

',
    scope: true,
    require: '^ctnCurtains',
    controller: function ( $scope, $element ) {

      $scope.setPosition = function setPosition () {
        if ( $scope.isCover ) {
          $element.css({
            height: $scope.height + 'px',
            zIndex: $scope.zIndex
          });
        } else {
          $element.css({
            minHeight: $scope.height + 'px',
            zIndex: $scope.zIndex
          });
        }
      };

      $scope.translate = function translate ( top ) {
        var prop = 'translateY('+top+'px) translateZ(0)';
        $element.css({
          transform: prop,
          '-webkit-transform': prop
        });
      };

      $scope.getHeight = function () {
        return $element.prop( 'offsetHeight' );
      };
    },
    link: function( scope, element, attrs, ctnCurtainsCtrl ) {
      ctnCurtainsCtrl.addSection( scope );
      scope.isCover = scope.$eval( attrs.ctnCover );
      scope.path = '/' + attrs.ctnCurtain;
    }
  };
})

;

<|endoftext|>


<commit_before>/**
 * Determines if a date is in the past
 * @method dateHasPassed
 * @param  {Date} date
 * @param  {Object} options
 * @return {Boolean} Returns boolean result
 * @example {{#dateHasPassed date}}
 *   // Do Something
 * {{/dateHasPassed}}
 */
module.exports.dateHasPassed = function dateHasPassed(date, options) {

  var today = new Date().toISOString();
  var date = new Date(date).toISOString();

  if (today > date) {
    return options.fn(this);
  } else {
    return options.inverse(this);
  }
};

// Alias 'dateHasPast'
module.exports.dateHasPast = module.exports.dateHasPassed;
<commit_msg>check for dateHasPassed helper<commit_after>/**
 * Determines if a date is in the past
 * @method dateHasPassed
 * @param  {Date} date
 * @param  {Object} options
 * @return {Boolean} Returns boolean result
 * @example {{#dateHasPassed date}}
 *   // Do Something
 * {{/dateHasPassed}}
 */
module.exports.dateHasPassed = function dateHasPassed(date, options) {

  if (!date) {
    console.warn('[dateHasPassed] date argument should not be missing');
    return;
  }

  var today = new Date().toISOString();
  var date = new Date(date).toISOString();

  if (today > date) {
    return options.fn(this);
  } else {
    return options.inverse(this);
  }
};

// Alias 'dateHasPast'
module.exports.dateHasPast = module.exports.dateHasPassed;
<|endoftext|>


<commit_before>(function(window, angular, undefined){
  'use strict';

  var module = angular.module('nsPopover', []);
  var $el = angular.element;
  var isDef = angular.isDefined;
  var $popovers = [];
  var globalId = 0;

  module.provider('nsPopover', function () {
    var defaults = {
      template: '',
      theme: 'ns-popover-list-theme',
      plain: 'false',
      trigger: 'click',
      triggerPrevent: true,
      angularEvent: '',
      scopeEvent: '',
      container: 'body',
      placement: 'bottom|left',
      timeout: 1.5,
      hideOnInsideClick: false,
      hideOnOutsideClick: true,
      hideOnButtonClick: true,
      mouseRelative: '',
      popupDelay: 0
    };

    this.setDefaults = function(newDefaults) {
      angular.extend(defaults, newDefaults);
    };

    this.$get = function() {
      getDefaults: function() {
        return defaults;
      }
    };
  });

  module.directive('nsPopover', ['nsPopover','$rootScope','$timeout','$templateCache','$q','$http','$compile','$document','$parse',
    function(nsPopover, $rootScope, $timeout, $templateCache, $q, $http, $compile, $document, $parse) {
      return {
        restrict: 'A',
        scope: true,
        link: function(scope, elm, attrs) {
          var defaults = nsPopover.getDefaults();

          var options = {
            template: attrs.nsPopoverTemplate || defaults.template,
            theme: attrs.nsPopoverTheme || defaults.theme,
            plain: toBoolean(attrs.nsPopoverPlain || defaults.plain),
            trigger: attrs.nsPopoverTrigger || defaults.trigger,
            triggerPrevent: attrs.nsPopoverTriggerPrevent || defaults.triggerPrevent,
            angularEvent: attrs.nsPopoverAngularEvent || defaults.angularEvent,
            scopeEvent: attrs.nsPopoverScopeEvent || defaults.scopeEvent,
            container: attrs.nsPopoverContainer || defaults.container,
            placement: attrs.nsPopoverPlacement || defaults.placement,
            timeout: attrs.nsPopoverTimeout || defaults.timeout,
            hideOnInsideClick: toBoolean(attrs.nsPopoverHideOnInsideClick || defaults.hideOnInsideClick),
            hideOnOutsideClick: toBoolean(attrs.nsPopoverHideOnOutsideClick || defaults.hideOnOutsideClick),
            hideOnButtonClick: toBoolean(attrs.nsPopoverHideOnButtonClick || defaults.hideOnButtonClick),
            mouseRelative: attrs.nsPopoverMouseRelative,
            popupDelay: attrs.nsPopoverPopupDelay || defaults.popupDelay,
            group: attrs.nsPopoverGroup
          };

          if (options.mouseRelative) {
            options.mouseRelativeX = options.mouseRelative.indexOf('x') !== -1;
            options.mouseRelativeY = options.mouseRelative.indexOf('y') !== -1;
          }

          var displayer_ = {
            id_: undefined,

            /**
             * Set the display property of the popover to 'block' after |delay| milliseconds.
             *
             * @param delay {Number}  The time (in seconds) to wait before set the display property.
             * @param e {Event}  The event which caused the popover to be shown.
             */
            display: function(delay, e) {
              // Disable popover if ns-popover value is false
              if ($parse(attrs.nsPopover)(scope) === false) {
                return;
              }

              $timeout.cancel(displayer_.id_);

              if (!isDef(delay)) {
                delay = 0;
              }

              // hide any popovers being displayed
              if (options.group) {
                $rootScope.$broadcast('ns:popover:hide', options.group);
              }

              displayer_.id_ = $timeout(function() {
                $popover.isOpen = true;
                $popover.css('display', 'block');

                // position the popover accordingly to the defined placement around the
                // |elm|.
                var elmRect = getBoundingClientRect(elm[0]);

                // If the mouse-relative options is specified we need to adjust the
                // element client rect to the current mouse coordinates.
                if (options.mouseRelative) {
                  elmRect = adjustRect(elmRect, options.mouseRelativeX, options.mouseRelativeY, e);
                }

                move($popover, placement_, align_, elmRect, $triangle);

                if (options.hideOnInsideClick) {
                  // Hide the popover without delay on the popover click events.
                  $popover.on('click', insideClickHandler);
                }
                if (options.hideOnOutsideClick) {
                  // Hide the popover without delay on outside click events.
                  $document.on('click', outsideClickHandler);
                }
                if (options.hideOnButtonClick) {
                  // Hide the popover without delay on the button click events.
                  elm.on('click', buttonClickHandler);
                }
              }, delay*1000);
            },

            cancel: function() {
              $timeout.cancel(displayer_.id_);
            }
          };

          var hider_ = {
            id_: undefined,

            /**
             * Set the display property of the popover to 'none' after |delay| milliseconds.
             *
             * @param delay {Number}  The time (in seconds) to wait before set the display property.
             */
            hide: function(delay) {
              $timeout.cancel(hider_.id_);

              // delay the hiding operation for 1.5s by default.
              if (!isDef(delay)) {
                delay = 1.5;
              }

              hider_.id_ = $timeout(function() {
                $popover.off('click', insideClickHandler);
                $document.off('click', outsideClickHandler);
                elm.off('click', buttonClickHandler);
                $popover.isOpen = false;
                displayer_.cancel();
                $popover.css('display', 'none');
              }, delay*1000);
            },

            cancel: function() {
              $timeout.cancel(hider_.id_);
            }
          };

          var $container = $document.find(options.container);
          if (!$container.length) {
            $container = $document.find('body');
          }

          var $triangle;
          var placement_;
          var align_;

          globalId += 1;

          var $popover = $el('

');
          $popovers.push($popover);

          var match = options.placement
            .match(/^(top|bottom|left|right)$|((top|bottom)\|(center|left|right)+)|((left|right)\|(center|top|bottom)+)/);

          if (!match) {
            throw new Error('"' + options.placement + '" is not a valid placement or has a invalid combination of placements.');
          }

          placement_ = match[6] || match[3] || match[1];
          align_ = match[7] || match[4] || match[2] || 'center';

          $q.when(loadTemplate(options.template, options.plain)).then(function(template) {
            template = angular.isString(template) ?
              template :
              template.data && angular.isString(template.data) ?
                template.data :
                '';

            $popover.html(template);

            if (options.theme) {
              $popover.addClass(options.theme);
            }

            // Add classes that identifies the placement and alignment of the popver
            // which allows the customization of the popover based on its position.
            $popover
              .addClass('ns-popover-' + placement_ + '-placement')
              .addClass('ns-popover-' + align_ + '-align');

            $compile($popover)(scope);

            scope.$on('$destroy', function() {
              $popover.remove();
            });

            scope.hidePopover = function() {
              hider_.hide(0);
            };

            scope.$on('ns:popover:hide', function(ev, group) {
              if (options.group === group) {
                  scope.hidePopover();
              }
            });

            $popover
              .css('position', 'absolute')
              .css('display', 'none');

            // When the tooltip style is used we need to position the triangle in the
            // center of the triggering element. We try first to find the elements that
            // has the |triangle| class using the find method, hoping that the full jquery
            // library is in use.
            $triangle = $popover.find('.triangle');

            // If the element is not found through the use of its class we will assume
            // that the full jquery library is not in use and will try to find the
            // triangle by inspecting each child of the |popover|.
            if (!$triangle.length) {
              var children = $popover.children();
              for(var i = 0; i < children.length; ++i) {
                var triangle = $el(children[i]);
                if (triangle.hasClass('triangle')) {
                  $triangle = triangle;
                  break;
                }
              }
            }

            $container.append($popover);
          });

          if (options.angularEvent) {
            $rootScope.$on(options.angularEvent, function() {
              hider_.cancel();
              displayer_.display(options.popupDelay);
            });
          } else if (options.scopeEvent) {
            scope.$on(options.scopeEvent, function() {
              hider_.cancel();
              displayer_.display($popover, options.popupDelay);
            });
          } else {
            elm.on(options.trigger, function(e) {
              if (false !== options.triggerPrevent) {
                e.preventDefault();
              }
              hider_.cancel();
              displayer_.display(options.popupDelay, e);
            });
          }

          elm
            .on('mouseout', function() {
              hider_.hide(options.timeout);
            })
            .on('mouseover', function() {
              hider_.cancel();
            });

          $popover
            .on('mouseout', function(e) {
              hider_.hide(options.timeout);
            })
            .on('mouseover', function() {
              hider_.cancel();
            });

          /**
           * Move the popover to the |placement| position of the object located on the |rect|.
           *
           * @param popover {Object} The popover object to be moved.
           * @param placement {String} The relative position to move the popover - top | bottom | left | right.
           * @param align {String} The way the popover should be aligned - center | left | right.
           * @param rect {ClientRect} The ClientRect of the object to move the popover around.
           * @param triangle {Object} The element that contains the popover's triangle. This can be null.
           */
          function move(popover, placement, align, rect, triangle) {
            var popoverRect = getBoundingClientRect(popover[0]);
            var top, left;

            var positionX = function() {
              if (align === 'center') {
                return Math.round(rect.left + rect.width/2 - popoverRect.width/2);
              } else if(align === 'right') {
                return rect.right - popoverRect.width;
              }
              return rect.left;
            };

            var positionY = function() {
              if (align === 'center') {
                return Math.round(rect.top + rect.height/2 - popoverRect.height/2);
              } else if(align === 'bottom') {
                return rect.bottom - popoverRect.height;
              }
              return rect.top;
            };

            if (placement === 'top') {
              top = rect.top - popoverRect.height;
              left = positionX();
            } else if (placement === 'right') {
              top = positionY();
              left = rect.right;
            } else if (placement === 'bottom') {
              top = rect.bottom;
              left = positionX();
            } else if (placement === 'left') {
              top = positionY();
              left = rect.left - popoverRect.width;
            }

            popover
              .css('top', top.toString() + 'px')
              .css('left', left.toString() + 'px');

            if (triangle) {
              if (placement === 'top' || placement === 'bottom') {
                left = rect.left + rect.width / 2 - left;
                triangle.css('left', left.toString() + 'px');
              } else {
                top = rect.top + rect.height / 2 - top;
                triangle.css('top', top.toString()  + 'px');
              }
            }
          }

          /**
           * Adjust a rect accordingly to the given x and y mouse positions.
           *
           * @param rect {ClientRect} The rect to be adjusted.
           */
          function adjustRect(rect, adjustX, adjustY, ev) {
            // if pageX or pageY is defined we need to lock the popover to the given
            // x and y position.
            // clone the rect, so we can manipulate its properties.
            var localRect = {
              bottom: rect.bottom,
              height: rect.height,
              left: rect.left,
              right: rect.right,
              top: rect.top,
              width: rect.width
            };

            if (adjustX) {
              localRect.left = ev.pageX;
              localRect.right = ev.pageX;
              localRect.width = 0;
            }

            if (adjustY) {
              localRect.top = ev.pageY;
              localRect.bottom = ev.pageY;
              localRect.height = 0;
            }

            return localRect;
          }

          function getBoundingClientRect(elm) {
            var w = window;
            var doc = document.documentElement || document.body.parentNode || document.body;
            var x = (isDef(w.pageXOffset)) ? w.pageXOffset : doc.scrollLeft;
            var y = (isDef(w.pageYOffset)) ? w.pageYOffset : doc.scrollTop;
            var rect = elm.getBoundingClientRect();

            // ClientRect class is immutable, so we need to return a modified copy
            // of it when the window has been scrolled.
            if (x || y) {
              return {
                bottom:rect.bottom+y,
                left:rect.left + x,
                right:rect.right + x,
                top:rect.top + y,
                height:rect.height,
                width:rect.width
              };
            }
            return rect;
          }

          function toBoolean(value) {
            if (value && value.length !== 0) {
              var v = ("" + value).toLowerCase();
              value = (v == 'true');
            } else {
              value = false;
            }
            return value;
          }

          /**
           * Load the given template in the cache if it is not already loaded.
           *
           * @param template The URI of the template to be loaded.
           * @returns {String} A promise that the template will be loaded.
           * @remarks If the template is null or undefined a empty string will be returned.
           */
          function loadTemplate(template, plain) {
            if (!template) {
              return '';
            }

            if (angular.isString(template) && plain) {
              return template;
            }

            return $templateCache.get(template) || $http.get(template, { cache : true });
          }

          function insideClickHandler() {
            if ($popover.isOpen) {
              hider_.hide(0);
            }
          }

          function outsideClickHandler(e) {
            if ($popover.isOpen && e.target !== elm[0]) {
              var id = $popover[0].id;
              if (!isInPopover(e.target)) {
                hider_.hide(0);
              }
            }

            function isInPopover(el) {
              if (el.id === id) {
                return true;
              }

              var parent = angular.element(el).parent()[0];

              if (!parent) {
                return false;
              }

              if (parent.id === id) {
                return true;
              }
              else {
                return isInPopover(parent);
              }
            }
          }

          function buttonClickHandler() {
            if ($popover.isOpen) {
              hider_.hide(0);
            }
          }
        }
      };
    }
  ]);
})(window, window.angular);
<commit_msg>Revert "Fixing provider"<commit_after>(function(window, angular, undefined){
  'use strict';

  var module = angular.module('nsPopover', []);
  var $el = angular.element;
  var isDef = angular.isDefined;
  var $popovers = [];
  var globalId = 0;

  module.provider('nsPopover', function () {
    var defaults = {
      template: '',
      theme: 'ns-popover-list-theme',
      plain: 'false',
      trigger: 'click',
      triggerPrevent: true,
      angularEvent: '',
      scopeEvent: '',
      container: 'body',
      placement: 'bottom|left',
      timeout: 1.5,
      hideOnInsideClick: false,
      hideOnOutsideClick: true,
      hideOnButtonClick: true,
      mouseRelative: '',
      popupDelay: 0
    };

    this.$get = function () {
      return {
        getDefaults: function () {
          return defaults;
        }
      };
    };
  });

  module.directive('nsPopover', ['nsPopover','$rootScope','$timeout','$templateCache','$q','$http','$compile','$document','$parse',
    function(nsPopover, $rootScope, $timeout, $templateCache, $q, $http, $compile, $document, $parse) {
      return {
        restrict: 'A',
        scope: true,
        link: function(scope, elm, attrs) {
          var defaults = nsPopover.getDefaults();

          var options = {
            template: attrs.nsPopoverTemplate || defaults.template,
            theme: attrs.nsPopoverTheme || defaults.theme,
            plain: toBoolean(attrs.nsPopoverPlain || defaults.plain),
            trigger: attrs.nsPopoverTrigger || defaults.trigger,
            triggerPrevent: attrs.nsPopoverTriggerPrevent || defaults.triggerPrevent,
            angularEvent: attrs.nsPopoverAngularEvent || defaults.angularEvent,
            scopeEvent: attrs.nsPopoverScopeEvent || defaults.scopeEvent,
            container: attrs.nsPopoverContainer || defaults.container,
            placement: attrs.nsPopoverPlacement || defaults.placement,
            timeout: attrs.nsPopoverTimeout || defaults.timeout,
            hideOnInsideClick: toBoolean(attrs.nsPopoverHideOnInsideClick || defaults.hideOnInsideClick),
            hideOnOutsideClick: toBoolean(attrs.nsPopoverHideOnOutsideClick || defaults.hideOnOutsideClick),
            hideOnButtonClick: toBoolean(attrs.nsPopoverHideOnButtonClick || defaults.hideOnButtonClick),
            mouseRelative: attrs.nsPopoverMouseRelative,
            popupDelay: attrs.nsPopoverPopupDelay || defaults.popupDelay,
            group: attrs.nsPopoverGroup
          };

          if (options.mouseRelative) {
            options.mouseRelativeX = options.mouseRelative.indexOf('x') !== -1;
            options.mouseRelativeY = options.mouseRelative.indexOf('y') !== -1;
          }

          var displayer_ = {
            id_: undefined,

            /**
             * Set the display property of the popover to 'block' after |delay| milliseconds.
             *
             * @param delay {Number}  The time (in seconds) to wait before set the display property.
             * @param e {Event}  The event which caused the popover to be shown.
             */
            display: function(delay, e) {
              // Disable popover if ns-popover value is false
              if ($parse(attrs.nsPopover)(scope) === false) {
                return;
              }

              $timeout.cancel(displayer_.id_);

              if (!isDef(delay)) {
                delay = 0;
              }

              // hide any popovers being displayed
              if (options.group) {
                $rootScope.$broadcast('ns:popover:hide', options.group);
              }

              displayer_.id_ = $timeout(function() {
                $popover.isOpen = true;
                $popover.css('display', 'block');

                // position the popover accordingly to the defined placement around the
                // |elm|.
                var elmRect = getBoundingClientRect(elm[0]);

                // If the mouse-relative options is specified we need to adjust the
                // element client rect to the current mouse coordinates.
                if (options.mouseRelative) {
                  elmRect = adjustRect(elmRect, options.mouseRelativeX, options.mouseRelativeY, e);
                }

                move($popover, placement_, align_, elmRect, $triangle);

                if (options.hideOnInsideClick) {
                  // Hide the popover without delay on the popover click events.
                  $popover.on('click', insideClickHandler);
                }
                if (options.hideOnOutsideClick) {
                  // Hide the popover without delay on outside click events.
                  $document.on('click', outsideClickHandler);
                }
                if (options.hideOnButtonClick) {
                  // Hide the popover without delay on the button click events.
                  elm.on('click', buttonClickHandler);
                }
              }, delay*1000);
            },

            cancel: function() {
              $timeout.cancel(displayer_.id_);
            }
          };

          var hider_ = {
            id_: undefined,

            /**
             * Set the display property of the popover to 'none' after |delay| milliseconds.
             *
             * @param delay {Number}  The time (in seconds) to wait before set the display property.
             */
            hide: function(delay) {
              $timeout.cancel(hider_.id_);

              // delay the hiding operation for 1.5s by default.
              if (!isDef(delay)) {
                delay = 1.5;
              }

              hider_.id_ = $timeout(function() {
                $popover.off('click', insideClickHandler);
                $document.off('click', outsideClickHandler);
                elm.off('click', buttonClickHandler);
                $popover.isOpen = false;
                displayer_.cancel();
                $popover.css('display', 'none');
              }, delay*1000);
            },

            cancel: function() {
              $timeout.cancel(hider_.id_);
            }
          };

          var $container = $document.find(options.container);
          if (!$container.length) {
            $container = $document.find('body');
          }

          var $triangle;
          var placement_;
          var align_;

          globalId += 1;

          var $popover = $el('

');
          $popovers.push($popover);

          var match = options.placement
            .match(/^(top|bottom|left|right)$|((top|bottom)\|(center|left|right)+)|((left|right)\|(center|top|bottom)+)/);

          if (!match) {
            throw new Error('"' + options.placement + '" is not a valid placement or has a invalid combination of placements.');
          }

          placement_ = match[6] || match[3] || match[1];
          align_ = match[7] || match[4] || match[2] || 'center';

          $q.when(loadTemplate(options.template, options.plain)).then(function(template) {
            template = angular.isString(template) ?
              template :
              template.data && angular.isString(template.data) ?
                template.data :
                '';

            $popover.html(template);

            if (options.theme) {
              $popover.addClass(options.theme);
            }

            // Add classes that identifies the placement and alignment of the popver
            // which allows the customization of the popover based on its position.
            $popover
              .addClass('ns-popover-' + placement_ + '-placement')
              .addClass('ns-popover-' + align_ + '-align');

            $compile($popover)(scope);

            scope.$on('$destroy', function() {
              $popover.remove();
            });

            scope.hidePopover = function() {
              hider_.hide(0);
            };

            scope.$on('ns:popover:hide', function(ev, group) {
              if (options.group === group) {
                  scope.hidePopover();
              }
            });

            $popover
              .css('position', 'absolute')
              .css('display', 'none');

            // When the tooltip style is used we need to position the triangle in the
            // center of the triggering element. We try first to find the elements that
            // has the |triangle| class using the find method, hoping that the full jquery
            // library is in use.
            $triangle = $popover.find('.triangle');

            // If the element is not found through the use of its class we will assume
            // that the full jquery library is not in use and will try to find the
            // triangle by inspecting each child of the |popover|.
            if (!$triangle.length) {
              var children = $popover.children();
              for(var i = 0; i < children.length; ++i) {
                var triangle = $el(children[i]);
                if (triangle.hasClass('triangle')) {
                  $triangle = triangle;
                  break;
                }
              }
            }

            $container.append($popover);
          });

          if (options.angularEvent) {
            $rootScope.$on(options.angularEvent, function() {
              hider_.cancel();
              displayer_.display(options.popupDelay);
            });
          } else if (options.scopeEvent) {
            scope.$on(options.scopeEvent, function() {
              hider_.cancel();
              displayer_.display($popover, options.popupDelay);
            });
          } else {
            elm.on(options.trigger, function(e) {
              if (false !== options.triggerPrevent) {
                e.preventDefault();
              }
              hider_.cancel();
              displayer_.display(options.popupDelay, e);
            });
          }

          elm
            .on('mouseout', function() {
              hider_.hide(options.timeout);
            })
            .on('mouseover', function() {
              hider_.cancel();
            });

          $popover
            .on('mouseout', function(e) {
              hider_.hide(options.timeout);
            })
            .on('mouseover', function() {
              hider_.cancel();
            });

          /**
           * Move the popover to the |placement| position of the object located on the |rect|.
           *
           * @param popover {Object} The popover object to be moved.
           * @param placement {String} The relative position to move the popover - top | bottom | left | right.
           * @param align {String} The way the popover should be aligned - center | left | right.
           * @param rect {ClientRect} The ClientRect of the object to move the popover around.
           * @param triangle {Object} The element that contains the popover's triangle. This can be null.
           */
          function move(popover, placement, align, rect, triangle) {
            var popoverRect = getBoundingClientRect(popover[0]);
            var top, left;

            var positionX = function() {
              if (align === 'center') {
                return Math.round(rect.left + rect.width/2 - popoverRect.width/2);
              } else if(align === 'right') {
                return rect.right - popoverRect.width;
              }
              return rect.left;
            };

            var positionY = function() {
              if (align === 'center') {
                return Math.round(rect.top + rect.height/2 - popoverRect.height/2);
              } else if(align === 'bottom') {
                return rect.bottom - popoverRect.height;
              }
              return rect.top;
            };

            if (placement === 'top') {
              top = rect.top - popoverRect.height;
              left = positionX();
            } else if (placement === 'right') {
              top = positionY();
              left = rect.right;
            } else if (placement === 'bottom') {
              top = rect.bottom;
              left = positionX();
            } else if (placement === 'left') {
              top = positionY();
              left = rect.left - popoverRect.width;
            }

            popover
              .css('top', top.toString() + 'px')
              .css('left', left.toString() + 'px');

            if (triangle) {
              if (placement === 'top' || placement === 'bottom') {
                left = rect.left + rect.width / 2 - left;
                triangle.css('left', left.toString() + 'px');
              } else {
                top = rect.top + rect.height / 2 - top;
                triangle.css('top', top.toString()  + 'px');
              }
            }
          }

          /**
           * Adjust a rect accordingly to the given x and y mouse positions.
           *
           * @param rect {ClientRect} The rect to be adjusted.
           */
          function adjustRect(rect, adjustX, adjustY, ev) {
            // if pageX or pageY is defined we need to lock the popover to the given
            // x and y position.
            // clone the rect, so we can manipulate its properties.
            var localRect = {
              bottom: rect.bottom,
              height: rect.height,
              left: rect.left,
              right: rect.right,
              top: rect.top,
              width: rect.width
            };

            if (adjustX) {
              localRect.left = ev.pageX;
              localRect.right = ev.pageX;
              localRect.width = 0;
            }

            if (adjustY) {
              localRect.top = ev.pageY;
              localRect.bottom = ev.pageY;
              localRect.height = 0;
            }

            return localRect;
          }

          function getBoundingClientRect(elm) {
            var w = window;
            var doc = document.documentElement || document.body.parentNode || document.body;
            var x = (isDef(w.pageXOffset)) ? w.pageXOffset : doc.scrollLeft;
            var y = (isDef(w.pageYOffset)) ? w.pageYOffset : doc.scrollTop;
            var rect = elm.getBoundingClientRect();

            // ClientRect class is immutable, so we need to return a modified copy
            // of it when the window has been scrolled.
            if (x || y) {
              return {
                bottom:rect.bottom+y,
                left:rect.left + x,
                right:rect.right + x,
                top:rect.top + y,
                height:rect.height,
                width:rect.width
              };
            }
            return rect;
          }

          function toBoolean(value) {
            if (value && value.length !== 0) {
              var v = ("" + value).toLowerCase();
              value = (v == 'true');
            } else {
              value = false;
            }
            return value;
          }

          /**
           * Load the given template in the cache if it is not already loaded.
           *
           * @param template The URI of the template to be loaded.
           * @returns {String} A promise that the template will be loaded.
           * @remarks If the template is null or undefined a empty string will be returned.
           */
          function loadTemplate(template, plain) {
            if (!template) {
              return '';
            }

            if (angular.isString(template) && plain) {
              return template;
            }

            return $templateCache.get(template) || $http.get(template, { cache : true });
          }

          function insideClickHandler() {
            if ($popover.isOpen) {
              hider_.hide(0);
            }
          }

          function outsideClickHandler(e) {
            if ($popover.isOpen && e.target !== elm[0]) {
              var id = $popover[0].id;
              if (!isInPopover(e.target)) {
                hider_.hide(0);
              }
            }

            function isInPopover(el) {
              if (el.id === id) {
                return true;
              }

              var parent = angular.element(el).parent()[0];

              if (!parent) {
                return false;
              }

              if (parent.id === id) {
                return true;
              }
              else {
                return isInPopover(parent);
              }
            }
          }

          function buttonClickHandler() {
            if ($popover.isOpen) {
              hider_.hide(0);
            }
          }
        }
      };
    }
  ]);
})(window, window.angular);<|endoftext|>


<commit_before>const assert = require('assert')
const checkProps = require('./check-props')

const allowedProps = [
  'name',
  'data',
  'width', 'height',
  'pixelFormat', 'encoding',
  'flipY',
  'mipmap',
  'target',
  'min', 'mag',
  'wrap', 'wrapS', 'wrapT',
  'aniso',
  'premultiplayAlpha'
]

function createTexture (ctx, opts) {
  checkProps(allowedProps, opts)

  const gl = ctx.gl

  const texture = {
    class: 'texture',
    handle: gl.createTexture(),
    target: opts.target,
    width: 0,
    height: 0,
    _update: updateTexture2D,
    _dispose: function () {
      gl.deleteTexture(this.handle)
      this.handle = null
    }
  }

  updateTexture2D(ctx, texture, opts)

  return texture
}

function orValue (a, b) {
  return (a !== undefined) ? a : b
}

// opts = { src, width, height }
// opts = { data, width, height, pixelFormat, encoding, flipY }
function updateTexture2D (ctx, texture, opts) {
  // checkProps(allowedProps, opts)

  const gl = ctx.gl
  const PixelFormat = ctx.PixelFormat

  let data = null
  let width = opts.width
  let height = opts.height
  let lod = 0
  let flipY = orValue(opts.flipY, orValue(texture.flipY, false))
  let target = opts.target || texture.target
  let pixelFormat = opts.pixelFormat || texture.pixelFormat || ctx.PixelFormat.RGBA8
  let encoding = opts.encoding || texture.encoding || ctx.Encoding.Linear
  let min = opts.min || texture.min || gl.NEAREST
  let mag = opts.mag || texture.mag || gl.NEAREST
  let wrapS = opts.wrapS || texture.wrapS || opts.wrap || texture.wrap || gl.CLAMP_TO_EDGE
  let wrapT = opts.wrapT || texture.wrapT || opts.wrap || texture.wrap || gl.CLAMP_TO_EDGE
  let aniso = opts.aniso || texture.aniso || 0
  let premultiplayAlpha = orValue(opts.premultiplayAlpha, orValue(texture.premultiplayAlpha, false))
  let internalFormat
  let type
  let format

  gl.getExtension('WEBGL_depth_texture')
  gl.getExtension('EXT_shader_texture_lod')
  gl.getExtension('OES_texture_float')
  gl.getExtension('OES_texture_float_linear')
  gl.getExtension('OES_texture_half_float')
  gl.getExtension('OES_texture_half_float_linear')
  var anisoExt = gl.getExtension('EXT_texture_filter_anisotropic')

  const textureUnit = 0
  gl.activeTexture(gl.TEXTURE0 + textureUnit)
  gl.bindTexture(texture.target, texture.handle)
  ctx.state.activeTextures[textureUnit] = texture

  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY)
  gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplayAlpha)
  gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, mag)
  gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, min)
  gl.texParameteri(target, gl.TEXTURE_WRAP_S, wrapS)
  gl.texParameteri(target, gl.TEXTURE_WRAP_T, wrapT)
  if (anisoExt && aniso > 0) {
    gl.texParameterf(target, anisoExt.TEXTURE_MAX_ANISOTROPY_EXT, aniso)
  }

  // just an image
  // opts = HTMLImage

  // image with flags
  // opts = { data: HTMLImage, flipY: Boolean }

  // pixel data
  // opts = { data: Array, width: Number, height: Number, flipY: Boolean }

  // pixel data with flags
  // opts = { data: { data: Array, width: Number, height: Number }, flipY: Boolean },

  // array of images for cubemaps (and array textures in webgl2)
  // opts = { data: [ HTMLImage, ... ], width: Number, height: Number, flipY: Boolean }

  // array of pixel data for cubemaps (and array texture in webgl2)
  // opts = { data: [ { data: Array, width: Number, height: Number }, ..], flipY: Boolean }

  const img = opts.data ? opts.data : opts
  if (img && img.nodeName) {
    assert(img instanceof window.HTMLImageElement ||
      img instanceof window.HTMLCanvasElement,
      'Texture2D.update opts has to be Image, Canvas or Video element')
    // TODO: add support for HTMLVideoElement with videoWidth and videoHeight
    width = img.width
    height = img.height
    internalFormat = gl.RGBA
    format = gl.RGBA
    type = gl.UNSIGNED_BYTE
    gl.texImage2D(target, lod, internalFormat, format, type, img)
    texture.width = width
    texture.height = height
  } else if (typeof opts === 'object') {
    assert(!data || Array.isArray(opts.data) ||
      opts.data instanceof Uint8Array ||
      opts.data instanceof Float32Array,
      'Texture2D.update opts.data has to be null or an Array, Uint8Array or Float32Array')

    data = opts.data ? (opts.data.data || opts.data) : null

    if (!opts.width && data && data.width) width = data.width
    if (!opts.height && data && data.height) width = data.height

    assert(!data || ((width !== undefined) && (height !== undefined)),
      'Texture2D.update opts.width and opts.height are required when providing opts.data')

    if (pixelFormat === PixelFormat.Depth) {
      format = gl.DEPTH_COMPONENT
      internalFormat = gl.DEPTH_COMPONENT
      type = gl.UNSIGNED_SHORT
    } else if (pixelFormat === PixelFormat.RGBA8) {
      format = gl.RGBA
      internalFormat = gl.RGBA
      type = gl.UNSIGNED_BYTE
    } else if (pixelFormat === PixelFormat.RGBA32F) {
      format = gl.RGBA
      internalFormat = gl.RGBA
      type = gl.FLOAT
    } else if (pixelFormat === PixelFormat.RGBA16F) {
      format = gl.RGBA
      internalFormat = gl.RGBA
      type = gl.HALF_FLOAT
    } else if (pixelFormat === PixelFormat.R32F) {
      format = gl.ALPHA
      internalFormat = gl.ALPHA
      type = gl.FLOAT
    } else if (pixelFormat) {
      assert.fail(`Unknown texture pixel format: ${opts.format}`)
    }

    if (target === gl.TEXTURE_2D) {
      if (Array.isArray(data)) {
        if (type === gl.UNSIGNED_BYTE) {
          data = new Uint8Array(data)
        } else if (type === gl.FLOAT) {
          data = new Float32Array(data)
        } else if (type === gl.HALF_FLOAT) {
          data = new Float32Array(data)
        } else {
          assert.fail(`Unknown texture data type: ${type}`)
        }
      }
      if (width && height) {
        gl.texImage2D(target, lod, internalFormat, width, height, 0, format, type, data)
        texture.width = width
        texture.height = height
      }
    } else if (target === gl.TEXTURE_CUBE_MAP) {
      assert(!data || (Array.isArray(data) && data.length === 6), 'TextureCube requires data for 6 faces')
      for (let i = 0; i < 6; i++) {
        let faceData = data ? (data[i].data || data[i]) : null
        const faceTarget = gl.TEXTURE_CUBE_MAP_POSITIVE_X + i
        if (Array.isArray(faceData)) {
          if (type === gl.UNSIGNED_BYTE) {
            faceData = new Uint8Array(faceData)
          } else if (type === gl.FLOAT) {
            faceData = new Float32Array(data)
          } else {
            assert.fail(`Unknown texture data type: ${type}`)
          }
          gl.texImage2D(faceTarget, lod, internalFormat, width, height, 0, format, type, faceData)
        } else if (faceData && faceData.nodeName) {
          gl.texImage2D(faceTarget, lod, internalFormat, format, type, faceData)
        } else {
          gl.texImage2D(faceTarget, lod, internalFormat, width, height, 0, format, type, faceData)
        }
        texture.width = width
        texture.height = height
      }
    }
  } else {
    // TODO: should i assert of throw new Error(msg)?
    assert.fail('Texture2D.update opts has to be a HTMLElement or Object')
  }

  if (opts.mipmap) {
    gl.generateMipmap(texture.target)
  }

  texture.target = target
  texture.pixelFormat = pixelFormat
  texture.encoding = encoding
  texture.min = min
  texture.mag = mag
  texture.wrapS = wrapS
  texture.wrapT = wrapT
  texture.format = format
  texture.flipY = flipY
  texture.internalFormat = internalFormat
  texture.type = type
  texture.info = ''
  texture.info += Object.keys(ctx.PixelFormat).find((key) => ctx.PixelFormat[key] === pixelFormat)
  texture.info += '_'
  texture.info += Object.keys(ctx.Encoding).find((key) => ctx.Encoding[key] === encoding)

  return texture
}

module.exports = createTexture
<commit_msg>Add video as texture support<commit_after>const assert = require('assert')
const checkProps = require('./check-props')

const allowedProps = [
  'name',
  'data',
  'width', 'height',
  'pixelFormat', 'encoding',
  'flipY',
  'mipmap',
  'target',
  'min', 'mag',
  'wrap', 'wrapS', 'wrapT',
  'aniso',
  'premultiplayAlpha'
]

function createTexture (ctx, opts) {
  checkProps(allowedProps, opts)

  const gl = ctx.gl

  const texture = {
    class: 'texture',
    handle: gl.createTexture(),
    target: opts.target,
    width: 0,
    height: 0,
    _update: updateTexture2D,
    _dispose: function () {
      gl.deleteTexture(this.handle)
      this.handle = null
    }
  }

  updateTexture2D(ctx, texture, opts)

  return texture
}

function orValue (a, b) {
  return (a !== undefined) ? a : b
}

// opts = { src, width, height }
// opts = { data, width, height, pixelFormat, encoding, flipY }
function updateTexture2D (ctx, texture, opts) {
  // checkProps(allowedProps, opts)

  const gl = ctx.gl
  const PixelFormat = ctx.PixelFormat

  let data = null
  let width = opts.width
  let height = opts.height
  let lod = 0
  let flipY = orValue(opts.flipY, orValue(texture.flipY, false))
  let target = opts.target || texture.target
  let pixelFormat = opts.pixelFormat || texture.pixelFormat || ctx.PixelFormat.RGBA8
  let encoding = opts.encoding || texture.encoding || ctx.Encoding.Linear
  let min = opts.min || texture.min || gl.NEAREST
  let mag = opts.mag || texture.mag || gl.NEAREST
  let wrapS = opts.wrapS || texture.wrapS || opts.wrap || texture.wrap || gl.CLAMP_TO_EDGE
  let wrapT = opts.wrapT || texture.wrapT || opts.wrap || texture.wrap || gl.CLAMP_TO_EDGE
  let aniso = opts.aniso || texture.aniso || 0
  let premultiplayAlpha = orValue(opts.premultiplayAlpha, orValue(texture.premultiplayAlpha, false))
  let internalFormat
  let type
  let format

  gl.getExtension('WEBGL_depth_texture')
  gl.getExtension('EXT_shader_texture_lod')
  gl.getExtension('OES_texture_float')
  gl.getExtension('OES_texture_float_linear')
  gl.getExtension('OES_texture_half_float')
  gl.getExtension('OES_texture_half_float_linear')
  var anisoExt = gl.getExtension('EXT_texture_filter_anisotropic')

  const textureUnit = 0
  gl.activeTexture(gl.TEXTURE0 + textureUnit)
  gl.bindTexture(texture.target, texture.handle)
  ctx.state.activeTextures[textureUnit] = texture

  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY)
  gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplayAlpha)
  gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, mag)
  gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, min)
  gl.texParameteri(target, gl.TEXTURE_WRAP_S, wrapS)
  gl.texParameteri(target, gl.TEXTURE_WRAP_T, wrapT)
  if (anisoExt && aniso > 0) {
    gl.texParameterf(target, anisoExt.TEXTURE_MAX_ANISOTROPY_EXT, aniso)
  }

  // just an image
  // opts = HTMLImage

  // image with flags
  // opts = { data: HTMLImage, flipY: Boolean }

  // pixel data
  // opts = { data: Array, width: Number, height: Number, flipY: Boolean }

  // pixel data with flags
  // opts = { data: { data: Array, width: Number, height: Number }, flipY: Boolean },

  // array of images for cubemaps (and array textures in webgl2)
  // opts = { data: [ HTMLImage, ... ], width: Number, height: Number, flipY: Boolean }

  // array of pixel data for cubemaps (and array texture in webgl2)
  // opts = { data: [ { data: Array, width: Number, height: Number }, ..], flipY: Boolean }

  const img = opts.data ? opts.data : opts
  if (img && img.nodeName) {
    assert(img instanceof window.HTMLImageElement ||
      img instanceof window.HTMLVideoElement ||
      img instanceof window.HTMLCanvasElement,
      'Texture2D.update opts has to be Image, Canvas or Video element')
    width = img.width || img.videoHeight
    height = img.height || img.videoHeight
    internalFormat = gl.RGBA
    format = gl.RGBA
    type = gl.UNSIGNED_BYTE
    gl.texImage2D(target, lod, internalFormat, format, type, img)
    texture.width = width
    texture.height = height
  } else if (typeof opts === 'object') {
    assert(!data || Array.isArray(opts.data) ||
      opts.data instanceof Uint8Array ||
      opts.data instanceof Float32Array,
      'Texture2D.update opts.data has to be null or an Array, Uint8Array or Float32Array')

    data = opts.data ? (opts.data.data || opts.data) : null

    if (!opts.width && data && data.width) width = data.width
    if (!opts.height && data && data.height) width = data.height

    assert(!data || ((width !== undefined) && (height !== undefined)),
      'Texture2D.update opts.width and opts.height are required when providing opts.data')

    if (pixelFormat === PixelFormat.Depth) {
      format = gl.DEPTH_COMPONENT
      internalFormat = gl.DEPTH_COMPONENT
      type = gl.UNSIGNED_SHORT
    } else if (pixelFormat === PixelFormat.RGBA8) {
      format = gl.RGBA
      internalFormat = gl.RGBA
      type = gl.UNSIGNED_BYTE
    } else if (pixelFormat === PixelFormat.RGBA32F) {
      format = gl.RGBA
      internalFormat = gl.RGBA
      type = gl.FLOAT
    } else if (pixelFormat === PixelFormat.RGBA16F) {
      format = gl.RGBA
      internalFormat = gl.RGBA
      type = gl.HALF_FLOAT
    } else if (pixelFormat === PixelFormat.R32F) {
      format = gl.ALPHA
      internalFormat = gl.ALPHA
      type = gl.FLOAT
    } else if (pixelFormat) {
      assert.fail(`Unknown texture pixel format: ${opts.format}`)
    }

    if (target === gl.TEXTURE_2D) {
      if (Array.isArray(data)) {
        if (type === gl.UNSIGNED_BYTE) {
          data = new Uint8Array(data)
        } else if (type === gl.FLOAT) {
          data = new Float32Array(data)
        } else if (type === gl.HALF_FLOAT) {
          data = new Float32Array(data)
        } else {
          assert.fail(`Unknown texture data type: ${type}`)
        }
      }
      if (width && height) {
        gl.texImage2D(target, lod, internalFormat, width, height, 0, format, type, data)
        texture.width = width
        texture.height = height
      }
    } else if (target === gl.TEXTURE_CUBE_MAP) {
      assert(!data || (Array.isArray(data) && data.length === 6), 'TextureCube requires data for 6 faces')
      for (let i = 0; i < 6; i++) {
        let faceData = data ? (data[i].data || data[i]) : null
        const faceTarget = gl.TEXTURE_CUBE_MAP_POSITIVE_X + i
        if (Array.isArray(faceData)) {
          if (type === gl.UNSIGNED_BYTE) {
            faceData = new Uint8Array(faceData)
          } else if (type === gl.FLOAT) {
            faceData = new Float32Array(data)
          } else {
            assert.fail(`Unknown texture data type: ${type}`)
          }
          gl.texImage2D(faceTarget, lod, internalFormat, width, height, 0, format, type, faceData)
        } else if (faceData && faceData.nodeName) {
          gl.texImage2D(faceTarget, lod, internalFormat, format, type, faceData)
        } else {
          gl.texImage2D(faceTarget, lod, internalFormat, width, height, 0, format, type, faceData)
        }
        texture.width = width
        texture.height = height
      }
    }
  } else {
    // TODO: should i assert of throw new Error(msg)?
    assert.fail('Texture2D.update opts has to be a HTMLElement or Object')
  }

  if (opts.mipmap) {
    gl.generateMipmap(texture.target)
  }

  texture.target = target
  texture.pixelFormat = pixelFormat
  texture.encoding = encoding
  texture.min = min
  texture.mag = mag
  texture.wrapS = wrapS
  texture.wrapT = wrapT
  texture.format = format
  texture.flipY = flipY
  texture.internalFormat = internalFormat
  texture.type = type
  texture.info = ''
  texture.info += Object.keys(ctx.PixelFormat).find((key) => ctx.PixelFormat[key] === pixelFormat)
  texture.info += '_'
  texture.info += Object.keys(ctx.Encoding).find((key) => ctx.Encoding[key] === encoding)

  return texture
}

module.exports = createTexture
<|endoftext|>


<commit_before>var	socket = io();

socket.emit('getGroups', function(){
	// puts initial groups down
});

socket.emit('getAnnouncements', function(){
	// puts initial announcements down
});

socket.on('groupMessage', function(user, group, message){
	// put down group message
});

socket.on('announcement', function(user, announcement){
	// put down annoucement
});

socket.on('newGroup', function(newGroup){
	// put down new group
});

socket.on('setStateUser', function(user, state){
	setStateUser(user, state);
});

//sends message to server
function sendMessage(user, group, messages){
	io.emit('groupMessage', user, group, messsage);
}

//sends announcement to server
function sendAnnouncement(user, announcement){
	io.emit('announcement', user, announcement);
}

function getNewUser(user, pass){
	return io.emit('newUser', user, pass, function(user){
		return user;
	});
}

function createNewGroup(user, groupName){
	io.emit('newGroup', user, groupName);
}

function getUsers(){
	io.emit('getUsers', function(userList){
		return userList;
	});
}

function setOnline(user){
	io.emit('setStatus', "online");
}

// Sets the state of a different user in the list.
function setStateUser(user, state) {
  var scope = angular.element($("#userList")).scope();
  scope.setStateUser(user, state);
  scope.$apply();
}

var app = angular.module('projectApp', []);

// Controller for updating the Userlist on the client side
app.controller('usersCtrl', function($scope) {
// Holds User list, including state, updated by server
    $scope.users = [
    	{
    		name: "Lars Memmington",
    		state: "Active"
    	},
    	{
    		name: "Zelaniaa",
    		state: "Disabled"
    	}
    ];
//Adds User to list
    $scope.addUser = function(user) {
      $scope.users.push(user);
    }
//Sets a user's state
    $scope.setStateUser = function(user, state) {
    	console.log('not implemented');
    }
//Generates the iconography for the user based on their state
    $scope.getColorFromState = function(state) {
    	switch(state){
    		case "Active":
    			return "green";
    		case "Disabled":
    			return "light grey";
    	}
    }

});

app.controller('messageCtrl', function($scope) {
	$scope.messages = [
		{
			username: "Zelanias",
			content: "This is a first testing of the message."
		},
		{
			username: "Jarodd",
			content: "Hey, Zelanius."
		}
	];
});
<commit_msg>Removed excessive spaces<commit_after>var	socket = io();

socket.emit('getGroups', function(){
	// puts initial groups down
});

socket.emit('getAnnouncements', function(){
	// puts initial announcements down
});

socket.on('groupMessage', function(user, group, message){
	// put down group message
});

socket.on('announcement', function(user, announcement){
	// put down annoucement
});

socket.on('newGroup', function(newGroup){
	// put down new group
});

socket.on('setStateUser', function(user, state){
	setStateUser(user, state);
});

//sends message to server
function sendMessage(user, group, messages){
	io.emit('groupMessage', user, group, messsage);
}

//sends announcement to server
function sendAnnouncement(user, announcement){
	io.emit('announcement', user, announcement);
}

// creates and returns a new user
function getNewUser(user, pass){
	return io.emit('newUser', user, pass, function(user){
		return user;
	});
}

function createNewGroup(user, groupName){
	io.emit('newGroup', user, groupName);
}

function getUsers(){
	io.emit('getUsers', function(userList){
		return userList;
	});
}

// Sets a user to the given status
function setOnline(user){
	io.emit('setStatus', "online");
}

// Sets the state of a different user in the list.
function setStateUser(user, state) {
  var scope = angular.element($("#userList")).scope();
  scope.setStateUser(user, state);
  scope.$apply();
}

var app = angular.module('projectApp', []);

// Controller for updating the Userlist on the client side
app.controller('usersCtrl', function($scope) {
// Holds User list, including state, updated by server
    $scope.users = [
    	{
    		name: "Lars Memmington",
    		state: "Active"
    	},
    	{
    		name: "Zelaniaa",
    		state: "Disabled"
    	}
    ];
//Adds User to list
    $scope.addUser = function(user) {
      $scope.users.push(user);
    }
//Sets a user's state
    $scope.setStateUser = function(user, state) {
    	console.log('not implemented');
    }
//Generates the iconography for the user based on their state
    $scope.getColorFromState = function(state) {
    	switch(state){
    		case "Active":
    			return "green";
    		case "Disabled":
    			return "light grey";
    	}
    }
});

app.controller('messageCtrl', function($scope) {
	$scope.messages = [
		{
			username: "Zelanias",
			content: "This is a first testing of the message."
		},
		{
			username: "Jarodd",
			content: "Hey, Zelanius."
		}
	];
});
<|endoftext|>


<commit_before>var matrix = {
	conf: {},
	canvas: false,
	controls: false,
	data: {},
	elements: [],
	init: function() {
		matrix.conf.width = $('#canvas').width();
		matrix.conf.height = $('#canvas').height();
		matrix.conf.ratio = matrix.conf.height / matrix.conf.width;
		matrix.canvas = Raphael('canvas', matrix.conf.width, matrix.conf.height);
		matrix.controls = $('#controls');

		/* iniitialize data */

		matrix.parse();
		matrix.ui();

	},
	redraw: function() {

		var compare = [];
		var year = 0;

		var drawdata = {
			data: {},
			tables: [],
			min: {},
			max: {},
			axid: {},
			year: $('#year').val()
		};

		$("select.table", matrix.controls).each(function(idx,e){
			drawdata.tables.push($(e).val());
		});

		if (drawdata.tables[0] === drawdata.tables[1]) {

			alert("FAIL");
			return;

		}

		drawdata.axid[drawdata.tables[0]] = "y";
		drawdata.axid[drawdata.tables[1]] = "x";

		$(drawdata.tables).each(function(idx,e){

			if (matrix.data.tables[e].years[drawdata.year] === undefined) {

				alert("FAIL!");
				return;

			}

			drawdata.min[drawdata.axid[e]] = matrix.data.tables[e].minValue;
			drawdata.max[drawdata.axid[e]] = matrix.data.tables[e].maxValue;

			var x = e;

			$(data.data[matrix.data.tables[e].years[drawdata.year]].data).each(function(idx,d){

				if (drawdata.data[d.geoIndex] === undefined) {

					drawdata.data[d.geoIndex] = {};

				}

				drawdata.data[d.geoIndex][drawdata.axid[e]] = d.value;

			});

		});

		// console.log(drawdata);

		/* clear paper */

		while (matrix.elements.length > 0) {

			matrix.elements.shift().remove();

		}

		/* axes drawing */

		var axwidth = (matrix.conf.width - 80);
		var axheight = (matrix.conf.height - 80);

		var yrange = (drawdata.max.y-drawdata.min.y);
		var xrange = (drawdata.max.x-drawdata.min.x);

		matrix.elements.push(Raphael.g.axis(40, (matrix.conf.height-40), axheight, drawdata.min.y, drawdata.max.y, yrange, 1, [], "t", 2, matrix.canvas).attr('stroke','#999999'));
		matrix.elements.push(Raphael.g.axis(40, (matrix.conf.height-40), axwidth, drawdata.min.x, drawdata.max.x, xrange, 0, [], "t", 2, matrix.canvas).attr('stroke','#999999'));

		/* data drawing */

		var item;

		for (var key in drawdata.data) {

			item = drawdata.data[key];

			if (item.x !== 0 && item.y !== 0) {

				item.drawx = (40+(axwidth*((item.x-drawdata.min.x)/xrange)));
				item.drawy = (matrix.conf.height-(40+(axheight*((item.y-drawdata.min.y)/yrange))));

				item.element = matrix.canvas.circle(item.drawx,item.drawy,5);

				item.element.attr('fill','#cccccc');
				item.element.attr('stroke','#999999');
				item.element.attr('title','x: '+item.x+', y: '+item.y);

				matrix.elements.push(item.element);

			}

		}

	},
	ui: function() {

		/* build controls ui */

		var ui_select = $('<select name="table[]" class="table" size="1"></select>');
		$(matrix.data.table_names).each(function(idx,e){
			ui_select.append('<option value="'+idx+'">'+e+'</option>');
		});

		ui_select_2 = ui_select.clone()

		var change = function() {
			matrix.controls.submit();
		}

		$(ui_select).change(function(){
			change();
		});

		$(ui_select_2).change(function(){
			change();
		});

		matrix.controls.append(ui_select_2);
		matrix.controls.append(ui_select);

		/* fixme: year slider */

		var year_select = $('<select name="year" id="year" size="1"><option value="1992">1992</option><option value="1993">1993</option><option value="1994">1994</option><option value="1995">1995</option><option value="1996">1996</option><option value="1997">1997</option><option value="1998">1998</option><option value="1999">1999</option><option value="2000">2000</option><option value="2001">2001</option><option value="2002">2002</option><option value="2003">2003</option><option value="2004">2004</option><option value="2005">2005</option><option value="2006">2006</option><option value="2007">2007</option><option value="2008">2008</option><option value="2009">2009</option><option value="2010">2010</option><option value="2011">2011</option></select>')

		$(year_select).change(function(){
			change();
		});

		matrix.controls.append(year_select);

		matrix.controls.append($('<input type="submit" value="Vergleichen" />'));

		matrix.controls.submit(function(x){
			matrix.redraw();
		});

	},
	parse: function() {

		/* geodaten */

		matrix.data.regions = [];
		var geo = data.geo[0].data;
		for (var i = 0; i < geo.length; i++) {
			matrix.data.regions.push(geo[i].geometry.coordinates);
		}

		/* datensätze */

		matrix.data.tables = [];
		var obj = {};
		matrix.data.table_index = -1;
		matrix.data.table_names = [];
		for (var i = 0; i < data.data.length; i++) {
			var name = data.data[i].options.tableName;
			var year = data.data[i].options.year;
			if (obj[name] === undefined) {
				matrix.data.table_index++;
				matrix.data.tables[matrix.data.table_index] = {
					tableName: name,
					years: [],
					minYear:  1e10,
					maxYear: -1e10,
					minValue: 1e10,
					maxValue: -1e10
				}
				obj[name] = matrix.data.table_index;
				matrix.data.table_names[matrix.data.table_index] = name;
			}
			var tl = matrix.data.tables[obj[name]];
			tl.years[year] = i;
			if (tl.minYear > year) tl.minYear = year;
			if (tl.maxYear < year) tl.maxYear = year;

			var d = data.data[i].data;
			for (var j = 0; j < d.length; j++) {
				var v = d[j].value;
				if (tl.minValue > v) tl.minValue = v;
				if (tl.maxValue < v) tl.maxValue = v;
			}

			if (data.data[i].options.minValue !== undefined) tl.minValue = data.data[i].options.minValue;
			if (data.data[i].options.maxValue !== undefined) tl.maxValue = data.data[i].options.maxValue;
		}

		/*

		for (var i = 0; i < matrix.data.tables.length; i++) {
			var t = matrix.data.tables[i];

			if (minYear > t.minYear) minYear = t.minYear;
			if (maxYear < t.maxYear) maxYear = t.maxYear;

			t.node = $('
'+t.tableName+'
');
			$('#datasets').append(t.node);
			t.node.click((function () {
				var id = i;
				return function () {
					selectTable(id);
				}
			})());
		}

		*/
	}
}

$(document).ready(function(){
	matrix.init();
});<commit_msg>make browser window resizable<commit_after>var matrix = {
	conf: {},
	canvas: false,
	controls: false,
	data: {},
	elements: [],
	init: function() {

		matrix.configure();

		/* iniitialize data */

		matrix.parse();
		matrix.ui();

	},
	configure: function() {
		matrix.conf.width = $('#canvas').width();
		matrix.conf.height = $('#canvas').height();
		matrix.conf.ratio = matrix.conf.height / matrix.conf.width;
		matrix.canvas = Raphael('canvas', matrix.conf.width, matrix.conf.height);
		matrix.controls = $('#controls');
	},
	reload: function() {
		matrix.configure();
		matrix.redraw();
	},
	redraw: function() {

		var compare = [];
		var year = 0;

		var drawdata = {
			data: {},
			tables: [],
			min: {},
			max: {},
			axid: {},
			year: $('#year').val()
		};

		$("select.table", matrix.controls).each(function(idx,e){
			drawdata.tables.push($(e).val());
		});

		if (drawdata.tables[0] === drawdata.tables[1]) {

			alert("FAIL");
			return;

		}

		drawdata.axid[drawdata.tables[0]] = "y";
		drawdata.axid[drawdata.tables[1]] = "x";

		$(drawdata.tables).each(function(idx,e){

			if (matrix.data.tables[e].years[drawdata.year] === undefined) {

				alert("FAIL!");
				return;

			}

			drawdata.min[drawdata.axid[e]] = matrix.data.tables[e].minValue;
			drawdata.max[drawdata.axid[e]] = matrix.data.tables[e].maxValue;

			var x = e;

			$(data.data[matrix.data.tables[e].years[drawdata.year]].data).each(function(idx,d){

				if (drawdata.data[d.geoIndex] === undefined) {

					drawdata.data[d.geoIndex] = {};

				}

				drawdata.data[d.geoIndex][drawdata.axid[e]] = d.value;

			});

		});

		// console.log(drawdata);

		/* clear paper */

		while (matrix.elements.length > 0) {

			matrix.elements.shift().remove();

		}

		/* axes drawing */

		var axwidth = (matrix.conf.width - 80);
		var axheight = (matrix.conf.height - 80);

		var yrange = (drawdata.max.y-drawdata.min.y);
		var xrange = (drawdata.max.x-drawdata.min.x);

		matrix.elements.push(Raphael.g.axis(40, (matrix.conf.height-40), axheight, drawdata.min.y, drawdata.max.y, yrange, 1, [], "t", 2, matrix.canvas).attr('stroke','#999999'));
		matrix.elements.push(Raphael.g.axis(40, (matrix.conf.height-40), axwidth, drawdata.min.x, drawdata.max.x, xrange, 0, [], "t", 2, matrix.canvas).attr('stroke','#999999'));

		/* data drawing */

		var item;

		for (var key in drawdata.data) {

			item = drawdata.data[key];

			if (item.x !== 0 && item.y !== 0) {

				item.drawx = (40+(axwidth*((item.x-drawdata.min.x)/xrange)));
				item.drawy = (matrix.conf.height-(40+(axheight*((item.y-drawdata.min.y)/yrange))));

				item.element = matrix.canvas.circle(item.drawx,item.drawy,5);

				item.element.attr('fill','#cccccc');
				item.element.attr('stroke','#999999');
				item.element.attr('title','x: '+item.x+', y: '+item.y);

				matrix.elements.push(item.element);

			}

		}

	},
	ui: function() {

		/* build controls ui */

		var ui_select = $('<select name="table[]" class="table" size="1"></select>');
		$(matrix.data.table_names).each(function(idx,e){
			ui_select.append('<option value="'+idx+'">'+e+'</option>');
		});

		ui_select_2 = ui_select.clone()

		var change = function() {
			matrix.controls.submit();
		}

		$(ui_select).change(function(){
			change();
		});

		$(ui_select_2).change(function(){
			change();
		});

		matrix.controls.append(ui_select_2);
		matrix.controls.append(ui_select);

		/* fixme: year slider */

		var year_select = $('<select name="year" id="year" size="1"><option value="1992">1992</option><option value="1993">1993</option><option value="1994">1994</option><option value="1995">1995</option><option value="1996">1996</option><option value="1997">1997</option><option value="1998">1998</option><option value="1999">1999</option><option value="2000">2000</option><option value="2001">2001</option><option value="2002">2002</option><option value="2003">2003</option><option value="2004">2004</option><option value="2005">2005</option><option value="2006">2006</option><option value="2007">2007</option><option value="2008">2008</option><option value="2009">2009</option><option value="2010">2010</option><option value="2011">2011</option></select>')

		$(year_select).change(function(){
			change();
		});

		matrix.controls.append(year_select);

		matrix.controls.append($('<input type="submit" value="Vergleichen" />'));

		matrix.controls.submit(function(x){
			matrix.redraw();
		});

	},
	parse: function() {

		/* geodaten */

		matrix.data.regions = [];
		var geo = data.geo[0].data;
		for (var i = 0; i < geo.length; i++) {
			matrix.data.regions.push(geo[i].geometry.coordinates);
		}

		/* datensätze */

		matrix.data.tables = [];
		var obj = {};
		matrix.data.table_index = -1;
		matrix.data.table_names = [];
		for (var i = 0; i < data.data.length; i++) {
			var name = data.data[i].options.tableName;
			var year = data.data[i].options.year;
			if (obj[name] === undefined) {
				matrix.data.table_index++;
				matrix.data.tables[matrix.data.table_index] = {
					tableName: name,
					years: [],
					minYear:  1e10,
					maxYear: -1e10,
					minValue: 1e10,
					maxValue: -1e10
				}
				obj[name] = matrix.data.table_index;
				matrix.data.table_names[matrix.data.table_index] = name;
			}
			var tl = matrix.data.tables[obj[name]];
			tl.years[year] = i;
			if (tl.minYear > year) tl.minYear = year;
			if (tl.maxYear < year) tl.maxYear = year;

			var d = data.data[i].data;
			for (var j = 0; j < d.length; j++) {
				var v = d[j].value;
				if (tl.minValue > v) tl.minValue = v;
				if (tl.maxValue < v) tl.maxValue = v;
			}

			if (data.data[i].options.minValue !== undefined) tl.minValue = data.data[i].options.minValue;
			if (data.data[i].options.maxValue !== undefined) tl.maxValue = data.data[i].options.maxValue;
		}

		/*

		for (var i = 0; i < matrix.data.tables.length; i++) {
			var t = matrix.data.tables[i];

			if (minYear > t.minYear) minYear = t.minYear;
			if (maxYear < t.maxYear) maxYear = t.maxYear;

			t.node = $('
'+t.tableName+'
');
			$('#datasets').append(t.node);
			t.node.click((function () {
				var id = i;
				return function () {
					selectTable(id);
				}
			})());
		}

		*/
	}
}

$(document).ready(function(){
	matrix.init();
});

$(window).resize(function(){
	matrix.reload();
});<|endoftext|>