<commit_before>
angular.module('os.administrative.user.dropdown', ['os.administrative.models'])
  .directive('osUsers', function($filter, AuthorizationService, User) {
    function loadUsers(scope, searchTerm, ctrl, queryParams) {
      var opts = angular.extend({searchString : searchTerm}, scope.filterOpts || {});
      if (queryParams) {
        angular.extend(opts, JSON.parse(queryParams));
      }

      ctrl.listLoaded = true;
      User.query(opts).then(
        function(result) {
          scope.users = result;
          loadSelectedUser(scope, result, ctrl);
        }
      );
    };

    function loadSelectedUser(scope, usersList, ctrl) {
      if (ctrl.onceLoaded) {
        return;
      }

      ctrl.onceLoaded = true;
      var selectProp = ctrl.attrs.selectProp;
      if (selectProp != 'id' || !scope.ngModel) {
        return;
      }

      var selectedUser = usersList.find(function(user) { return user[selectProp] == scope.ngModel; });
      if (selectedUser) {
        return;
      }

      User.getById(scope.ngModel).then(
        function(user) {
          usersList.push(user);
        }
      );
    }

    return {
      restrict: 'AE',

      scope: {
        ngModel: '=ngModel',
        placeholder: '@',
        filterOpts: '=',
        defaultList: '=',
        onSelect: '&'
      },

      replace: true,

      controller: function($scope, $element, $attrs) {
        var ctrl = this;

        if ($attrs.options) {
          $scope.users = ctrl.localList = JSON.parse($attrs.options);
          ctrl.listLoaded = true;

          $scope.searchUsers = function(searchTerm) {
            if (searchTerm) {
              $scope.users = $filter('filter')(ctrl.localList, searchTerm);
            } else {
              $scope.users = ctrl.localList;
            }
          }

          return;
        }

        $scope.searchUsers = function(searchTerm) {
          if (!searchTerm && $scope.defaultList) {
            $scope.users = $scope.defaultList;
            loadSelectedUser($scope, $scope.users, ctrl);
            return;
          }

          loadUsers($scope, searchTerm, ctrl, $attrs.queryParams);
        };

        $scope.$watch('filterOpts', function(newVal, oldVal) {
          if (newVal == oldVal) {
            return;
          }

          loadUsers($scope, undefined, ctrl, $attrs.queryParams);
        });

        $attrs.$observe('queryParams',
          function() {
            if (!ctrl.listLoaded) {
              //
              // this is done to ensure we do not load users list twice
              // once by the attributes observer and another by the filterOpts watcher
              //
              return;
            }

            loadUsers($scope, undefined, ctrl, $attrs.queryParams);
          }
        );
      },

      link: function(scope, element, attrs, ctrl) {
        ctrl.attrs = attrs;

        if (!scope.ngModel && attrs.hasOwnProperty('defaultCurrentUser')) {
          var user = angular.copy(AuthorizationService.currentUser() || {});
          if (attrs.selectProp) {
            user = user[attrs.selectProp];
          }

          if (attrs.hasOwnProperty('multiple')) {
            scope.ngModel = [user];
          } else {
            scope.ngModel = user;
          }
        } else if (!scope.ngModel && attrs.hasOwnProperty('multiple')) {
          scope.ngModel = [];
        }
      },

      template: function(tElem, tAttrs) {
        var bodyAppend = angular.isDefined(tAttrs.appendToBody) ? tAttrs.appendToBody : "true";
        var tabable = angular.isDefined(tAttrs.osTabable) ? tAttrs.osTabable : "false";

        var loopExpr = 'user in users';
        if (angular.isDefined(tAttrs.selectProp)) {
          loopExpr = 'user.' + tAttrs.selectProp + ' as ' + loopExpr;
        }

        return angular.isDefined(tAttrs.multiple) ?
              '
' +
                '<ui-select multiple os-fix-dd ng-model="$parent.ngModel" reset-search-input="true"' +
                  (!!tAttrs.onSelect ? 'on-select="$parent.onSelect({user: $item})"' : '') +
                  ' append-to-body="' + bodyAppend + '" os-tabable="' + tabable + '">' +
                  '<ui-select-match placeholder="{{$parent.placeholder}}">' +
                    '{{$item.firstName}} {{$item.lastName}}' +
                  '</ui-select-match>' +
                  '<ui-select-choices repeat="' + loopExpr +'" refresh="searchUsers($select.search)" refresh-delay="750">' +
                    '' +
                  '</ui-select-choices>' +
                '</ui-select>' +
              '
'

              :

              '
' +
                '<ui-select os-fix-dd ng-model="$parent.ngModel" reset-search-input="true"' +
                  (!!tAttrs.onSelect ? 'on-select="$parent.onSelect({user: $item})"' : '') +
                  ' append-to-body="' + bodyAppend + '" os-tabable="' + tabable + '">' +
                  '<ui-select-match placeholder="{{$parent.placeholder}}" allow-clear="'+ (tAttrs.required == undefined) +'">' +
                    '{{$select.selected.firstName}} {{$select.selected.lastName}}' +
                  '</ui-select-match>' +
                  '<ui-select-choices repeat="' + loopExpr +'" refresh="searchUsers($select.search)" refresh-delay="750">' +
                    '' +
                  '</ui-select-choices>' +
                '</ui-select>' +
              '
';
      }
    };
  });
<commit_msg>Project tracker: Updated the users dropdown widget to show the list of users as per the view requirement. e.g. list of site project users.<commit_after>
angular.module('os.administrative.user.dropdown', ['os.administrative.models'])
  .directive('osUsers', function($filter, AuthorizationService, User) {
    function loadUsers(scope, searchTerm, ctrl, queryParams, listFn) {
      var opts = angular.extend({searchString : searchTerm}, scope.filterOpts || {});
      if (queryParams) {
        angular.extend(opts, JSON.parse(queryParams));
      }

      ctrl.listLoaded = true;

      var promise = !listFn ? User.query(opts) : scope.listFn(opts);
      promise.then(
        function(result) {
          scope.users = result;
          loadSelectedUser(scope, result, ctrl);
        }
      );
    };

    function loadSelectedUser(scope, usersList, ctrl) {
      if (ctrl.onceLoaded) {
        return;
      }

      ctrl.onceLoaded = true;
      var selectProp = ctrl.attrs.selectProp;
      if (selectProp != 'id' || !scope.ngModel) {
        return;
      }

      var selectedUser = usersList.find(function(user) { return user[selectProp] == scope.ngModel; });
      if (selectedUser) {
        return;
      }

      User.getById(scope.ngModel).then(
        function(user) {
          usersList.push(user);
        }
      );
    }

    return {
      restrict: 'AE',

      scope: {
        ngModel: '=ngModel',
        placeholder: '@',
        filterOpts: '=',
        defaultList: '=',
        onSelect: '&',
        listFn: '&'
      },

      replace: true,

      controller: function($scope, $element, $attrs) {
        var ctrl = this;

        if ($attrs.options) {
          $scope.users = ctrl.localList = JSON.parse($attrs.options);
          ctrl.listLoaded = true;

          $scope.searchUsers = function(searchTerm) {
            if (searchTerm) {
              $scope.users = $filter('filter')(ctrl.localList, searchTerm);
            } else {
              $scope.users = ctrl.localList;
            }
          }

          return;
        }

        $scope.searchUsers = function(searchTerm) {
          if (!searchTerm && $scope.defaultList) {
            $scope.users = $scope.defaultList;
            loadSelectedUser($scope, $scope.users, ctrl);
            return;
          }

          loadUsers($scope, searchTerm, ctrl, $attrs.queryParams, $attrs.listFn);
        };

        $scope.$watch('filterOpts', function(newVal, oldVal) {
          if (newVal == oldVal) {
            return;
          }

          loadUsers($scope, undefined, ctrl, $attrs.queryParams, $attrs.listFn);
        });

        $attrs.$observe('queryParams',
          function() {
            if (!ctrl.listLoaded) {
              //
              // this is done to ensure we do not load users list twice
              // once by the attributes observer and another by the filterOpts watcher
              //
              return;
            }

            loadUsers($scope, undefined, ctrl, $attrs.queryParams, $attrs.listFn);
          }
        );
      },

      link: function(scope, element, attrs, ctrl) {
        ctrl.attrs = attrs;

        if (!scope.ngModel && attrs.hasOwnProperty('defaultCurrentUser')) {
          var user = angular.copy(AuthorizationService.currentUser() || {});
          if (attrs.selectProp) {
            user = user[attrs.selectProp];
          }

          if (attrs.hasOwnProperty('multiple')) {
            scope.ngModel = [user];
          } else {
            scope.ngModel = user;
          }
        } else if (!scope.ngModel && attrs.hasOwnProperty('multiple')) {
          scope.ngModel = [];
        }
      },

      template: function(tElem, tAttrs) {
        var bodyAppend = angular.isDefined(tAttrs.appendToBody) ? tAttrs.appendToBody : "true";
        var tabable = angular.isDefined(tAttrs.osTabable) ? tAttrs.osTabable : "false";

        var loopExpr = 'user in users';
        if (angular.isDefined(tAttrs.selectProp)) {
          loopExpr = 'user.' + tAttrs.selectProp + ' as ' + loopExpr;
        }

        return angular.isDefined(tAttrs.multiple) ?
              '
' +
                '<ui-select multiple os-fix-dd ng-model="$parent.ngModel" reset-search-input="true"' +
                  (!!tAttrs.onSelect ? 'on-select="$parent.onSelect({user: $item})"' : '') +
                  ' append-to-body="' + bodyAppend + '" os-tabable="' + tabable + '">' +
                  '<ui-select-match placeholder="{{$parent.placeholder}}">' +
                    '{{$item.firstName}} {{$item.lastName}}' +
                  '</ui-select-match>' +
                  '<ui-select-choices repeat="' + loopExpr +'" refresh="searchUsers($select.search)" refresh-delay="750">' +
                    '' +
                  '</ui-select-choices>' +
                '</ui-select>' +
              '
'

              :

              '
' +
                '<ui-select os-fix-dd ng-model="$parent.ngModel" reset-search-input="true"' +
                  (!!tAttrs.onSelect ? 'on-select="$parent.onSelect({user: $item})"' : '') +
                  ' append-to-body="' + bodyAppend + '" os-tabable="' + tabable + '">' +
                  '<ui-select-match placeholder="{{$parent.placeholder}}" allow-clear="'+ (tAttrs.required == undefined) +'">' +
                    '{{$select.selected.firstName}} {{$select.selected.lastName}}' +
                  '</ui-select-match>' +
                  '<ui-select-choices repeat="' + loopExpr +'" refresh="searchUsers($select.search)" refresh-delay="750">' +
                    '' +
                  '</ui-select-choices>' +
                '</ui-select>' +
              '
';
      }
    };
  });
<|endoftext|>


<commit_before>(function () {
  'use strict';

  angular
    .module('app')
    .controller('OrientationDataTabController', OrientationDataTabController);

  OrientationDataTabController.$inject = ['$cordovaDeviceMotion', '$cordovaDeviceOrientation', '$ionicModal',
    '$ionicPopup', '$log', '$q', '$scope', '$state', 'DataModelsFactory', 'FormFactory', 'HelpersFactory',
    'ProjectFactory'];

  function OrientationDataTabController($cordovaDeviceMotion, $cordovaDeviceOrientation, $ionicModal, $ionicPopup, $log,
                                        $q, $scope, $state, DataModelsFactory, FormFactory, HelpersFactory,
                                        ProjectFactory) {
    var vm = this;
    var vmParent = $scope.vm;
    vmParent.loadTab($state);  // Need to load current state into parent

    vm.addAssociatedOrientation = addAssociatedOrientation;
    vm.addOrientation = addOrientation;
    vm.basicFormModal = {};
    vm.copyAssociatedOrientation = copyAssociatedOrientation;
    vm.copyOrientation = copyOrientation;
    vm.deleteAssociatedOrientation = deleteAssociatedOrientation;
    vm.deleteOrientation = deleteOrientation;
    vm.editAssociatedOrientation = editAssociatedOrientation;
    vm.editOrientation = editOrientation;
    vm.getCompassInfo = getCompassInfo;
    vm.modalTitle = '';
    vm.parentOrientation = {};
    vm.submit = submit;

    activate();

    /**
     * Private Functions
     */

    function activate() {
      $log.log('Orientation Data:', vmParent.spot.properties.orientation_data);
      checkProperties();
      createModal();
    }

    function assignProperties(item) {
      if (!item.label) item.label = item.name || createDefaultLabel(item);
      if (!item.id) item.id = HelpersFactory.newId();
      if (!item.type) item.type = item.orientation_type || 'planar_orientation';
    }

    function calculateOrientation(magneticHeading, x, y, z) {
      var g = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2));
      var s = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
      var B = Math.acos(Math.abs(y) / s);
      var R = 90 - B;
      var d = Math.acos(Math.abs(z) / g);
      var b = Math.atan(Math.tan(R) * Math.cos(d));
      var dipdir;
      var diry = magneticHeading;

      if (x === 0 && y === 0) {
        d = 0;
        dipdir = 180;
      }
      else if (x >= 0 && y >= 0) dipdir = diry - 90 - b;
      else if (y <= 0 && x >= 0) dipdir = diry - 90 + b;
      else if (y <= 0 && x <= 0) dipdir = diry + 90 - b;
      else if (x <= 0 && y >= 0) dipdir = diry + 90 + b;

      var strike = dipdir - 90;
      strike = strike % 360;
      dipdir = dipdir % 360;
      var dip = d;
      var trend = diry;
      var plunge = Math.acos(Math.abs(y) / g);

      if (vmParent.data.type === 'linear_orientation') {
        vmParent.data.trend = Math.round(trend * 1000) / 1000;
        vmParent.data.plunge = Math.round(plunge * 1000) / 1000;
      }
      else {
        vmParent.data.strike = Math.round(strike * 1000) / 1000;
        vmParent.data.dip_direction = Math.round(dipdir * 1000) / 1000;
        vmParent.data.dip = Math.round(dip * 1000) / 1000;
      }

      return {
        'strike': data.strike, 'dipdir': data.dip_direction, 'dip': data.dip,
        'trend': vmParent.data.trend, 'plunge': vmParent.data.plunge
      };
    }

    function checkProperties() {
      _.each(vmParent.spot.properties.orientation_data, function (orientation) {
        assignProperties(orientation);
        _.each(orientation.associated_orientation, function (associated_orientation) {
          assignProperties(associated_orientation);
        });
      });
    }

    function createDefaultLabel(orientationToLabel) {
      var label = DataModelsFactory.getFeatureTypeLabel(orientationToLabel.feature_type);
      if (!label && orientationToLabel.type) label = orientationToLabel.type.split('_')[0] + ' feature';
      if (orientationToLabel.strike) label += ' ' + orientationToLabel.strike.toString();
      else if (orientationToLabel.trend) label += ' ' + orientationToLabel.trend.toString();
      return label;
    }

    function createModal() {
      $ionicModal.fromTemplateUrl('app/spot/basic-form-modal.html', {
        'scope': $scope,
        'animation': 'slide-in-up',
        'focusFirstInput': true,
        'backdropClickToClose': false
      }).then(function (modal) {
        vm.basicFormModal = modal;
      });

      // Cleanup the modal when we're done with it!
      $scope.$on('$destroy', function () {
        vm.basicFormModal.remove();
      });
    }

    function getModalTitlePart() {
      if (vmParent.data.type === 'linear_orientation') return 'Line';
      if (vmParent.data.type === 'planar_orientation') return 'Plane';
      if (vmParent.data.type === 'tabular_orientation') return 'Tabular Zone';
    }

    /**
     * Public Functions
     */

    function addAssociatedOrientation(parentThisOrientation, type) {
      vm.parentOrientation = parentThisOrientation;
      vmParent.survey = DataModelsFactory.getDataModel('orientation_data')[type].survey;
      vmParent.choices = DataModelsFactory.getDataModel('orientation_data')[type].choices;
      vmParent.data = {};
      vmParent.data.type = type;
      vmParent.data.id = HelpersFactory.newId();
      vm.modalTitle = 'Add a ' + getModalTitlePart();
      vm.basicFormModal.show();
    }

    function addOrientation(type) {
      vm.parentOrientation = undefined;
      vmParent.survey = DataModelsFactory.getDataModel('orientation_data')[type].survey;
      vmParent.choices = DataModelsFactory.getDataModel('orientation_data')[type].choices;
      vmParent.data = {};
      vmParent.data.type = type;
      vmParent.data.id = HelpersFactory.newId();
      vm.modalTitle = 'Add a ' + getModalTitlePart();
      vm.basicFormModal.show();
    }

    function copyAssociatedOrientation(parentThisOrientation, orientation) {
      var copy = angular.copy(orientation);
      delete copy.id;
      assignProperties(copy);
      parentThisOrientation.associated_orientation.push(copy);
    }

    function copyOrientation(orientation) {
      var copy = angular.copy(orientation);
      delete copy.id;
      _.each(copy.associated_orientation, function (associatedOrientation) {
        delete associatedOrientation.id;
        assignProperties(associatedOrientation);
      });
      assignProperties(copy);
      vmParent.spot.properties.orientation_data.push(copy);
    }

    function deleteAssociatedOrientation(parentThisOrientation, orientationToDelete) {
      var confirmPopup = $ionicPopup.confirm({
        'title': 'Delete Associated Orientation',
        'template': 'Are you sure you want to delete this  associated orientation?'
      });
      confirmPopup.then(function (res) {
        if (res) {
          parentThisOrientation.associated_orientation = _.reject(parentThisOrientation.associated_orientation,
            function (associatedOrientation) {
              return associatedOrientation.id === orientationToDelete.id;
            });
          if (parentThisOrientation.associated_orientation === 0) delete parentThisOrientation.associated_orientation;
        }
      });
    }

    function deleteOrientation(orientationToDelete) {
      var confirmPopup = $ionicPopup.confirm({
        'title': 'Delete Orientation',
        'template': 'Are you sure you want to delete this orientation?'
      });
      confirmPopup.then(function (res) {
        if (res) {
          vmParent.spot.properties.orientation_data = _.reject(vmParent.spot.properties.orientation_data,
            function (orientation) {
              return orientation.id === orientationToDelete.id;
            });
          if (vmParent.spot.properties.orientation_data === 0) delete vmParent.spot.properties.orientation_data;
          ProjectFactory.removeFeatureFromTags(vmParent.spot.properties.id, orientationToDelete.id);
        }
      });
    }

    function editAssociatedOrientation(parentThisOrientation, orientationToEdit) {
      vm.parentOrientation = parentThisOrientation;
      vmParent.data = angular.fromJson(angular.toJson(orientationToEdit));  // Copy value, not reference
      vmParent.survey = DataModelsFactory.getDataModel('orientation_data')[vmParent.data.type].survey;
      vmParent.choices = DataModelsFactory.getDataModel('orientation_data')[vmParent.data.type].choices;
      vm.modalTitle = 'Edit ' + getModalTitlePart();
      vm.basicFormModal.show();
    }

    function editOrientation(orientationToEdit) {
      vm.parentOrientation = undefined;
      vmParent.data = angular.fromJson(angular.toJson(orientationToEdit));  // Copy value, not reference
      vmParent.survey = DataModelsFactory.getDataModel('orientation_data')[vmParent.data.type].survey;
      vmParent.choices = DataModelsFactory.getDataModel('orientation_data')[vmParent.data.type].choices;
      vm.modalTitle = 'Edit ' + getModalTitlePart();
      vm.basicFormModal.show();
    }

    function getCompassInfo() {
      var promises = [];
      var promise;
      var msgText = '';
      var magneticHeading, x, y, z;

      promise = $cordovaDeviceOrientation.getCurrentHeading().then(function (result) {
        magneticHeading = result.magneticHeading;
        msgText += 'Magnetic Heading = ' + magneticHeading + '
';
      }, function (err) {
        msgText += 'Compass Error: ' + err + '
';
        $log.log(err);
      });
      promises.push(promise);

      if (navigator.accelerometer) {
        promise = $cordovaDeviceMotion.getCurrentAcceleration().then(function (result) {
          x = result.x;
          y = result.y;
          z = result.z;
          msgText += 'X = ' + x + '
';
          msgText += 'Y = ' + y + '
';
          msgText += 'Z = ' + z + '
';
        }, function (err) {
          msgText = 'Acceleration Error: ' + err + '
';
        });
        promises.push(promise);
      }
      else msgText += 'Accelerometer Error: No accelerometer on Device
';

      $q.all(promises).then(function () {
        if (magneticHeading && x && y && z) {
          var orientation = calculateOrientation(magneticHeading, x, y, z);
          if (vmParent.data.type === 'linear_orientation') {
            msgText += 'Trend = ' + orientation.trend + '
';
            msgText += 'Plunge = ' + orientation.plunge + '
';
          }
          else {
            msgText += 'Strike = ' + orientation.strike + '
';
            msgText += 'Dip Direction = ' + orientation.dipdir + '
';
            msgText += 'Dip = ' + orientation.dip + '
';
          }
        }
        $ionicPopup.alert({
          'title': 'Compass & Accelerometer Info',
          'template': msgText
        });
      });
    }

    function submit() {
      if (_.size(vmParent.data) <= 2) {
        // If not more than type and id fields no data has been entered so don't continue, just close modal
        vmParent.data = {};
        vm.parentOrientation = undefined;
        vm.basicFormModal.hide();
        return;
      }
      if (!vmParent.data.label) vmParent.data.label = createDefaultLabel(vmParent.data);
      if (FormFactory.validate(vmParent.survey, vmParent.data)) {
        if (!vm.parentOrientation) {
          if (!vmParent.spot.properties.orientation_data) vmParent.spot.properties.orientation_data = [];
          vmParent.spot.properties.orientation_data = _.reject(vmParent.spot.properties.orientation_data,
            function (orientation) {
              return orientation.id === vmParent.data.id;
            });
          vmParent.spot.properties.orientation_data.push(vmParent.data);
        }
        else {
          if (!vm.parentOrientation.associated_orientation) vm.parentOrientation.associated_orientation = [];
          vm.parentOrientation.associated_orientation = _.reject(vm.parentOrientation.associated_orientation,
            function (associatedOrientation) {
              return associatedOrientation.id === vmParent.data.id;
            });
          vm.parentOrientation.associated_orientation.push(vmParent.data);
          vmParent.spot.properties.orientation_data = _.reject(vmParent.spot.properties.orientation_data,
            function (orientation) {
              return orientation.id === vm.parentOrientation.id;
            });
          vmParent.spot.properties.orientation_data.push(vm.parentOrientation);
        }
        vmParent.data = {};
        vm.basicFormModal.hide();
      }
    }
  }
}());
<commit_msg>fixed type-o<commit_after>(function () {
  'use strict';

  angular
    .module('app')
    .controller('OrientationDataTabController', OrientationDataTabController);

  OrientationDataTabController.$inject = ['$cordovaDeviceMotion', '$cordovaDeviceOrientation', '$ionicModal',
    '$ionicPopup', '$log', '$q', '$scope', '$state', 'DataModelsFactory', 'FormFactory', 'HelpersFactory',
    'ProjectFactory'];

  function OrientationDataTabController($cordovaDeviceMotion, $cordovaDeviceOrientation, $ionicModal, $ionicPopup, $log,
                                        $q, $scope, $state, DataModelsFactory, FormFactory, HelpersFactory,
                                        ProjectFactory) {
    var vm = this;
    var vmParent = $scope.vm;
    vmParent.loadTab($state);  // Need to load current state into parent

    vm.addAssociatedOrientation = addAssociatedOrientation;
    vm.addOrientation = addOrientation;
    vm.basicFormModal = {};
    vm.copyAssociatedOrientation = copyAssociatedOrientation;
    vm.copyOrientation = copyOrientation;
    vm.deleteAssociatedOrientation = deleteAssociatedOrientation;
    vm.deleteOrientation = deleteOrientation;
    vm.editAssociatedOrientation = editAssociatedOrientation;
    vm.editOrientation = editOrientation;
    vm.getCompassInfo = getCompassInfo;
    vm.modalTitle = '';
    vm.parentOrientation = {};
    vm.submit = submit;

    activate();

    /**
     * Private Functions
     */

    function activate() {
      $log.log('Orientation Data:', vmParent.spot.properties.orientation_data);
      checkProperties();
      createModal();
    }

    function assignProperties(item) {
      if (!item.label) item.label = item.name || createDefaultLabel(item);
      if (!item.id) item.id = HelpersFactory.newId();
      if (!item.type) item.type = item.orientation_type || 'planar_orientation';
    }

    function calculateOrientation(magneticHeading, x, y, z) {
      var g = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2));
      var s = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
      var B = Math.acos(Math.abs(y) / s);
      var R = 90 - B;
      var d = Math.acos(Math.abs(z) / g);
      var b = Math.atan(Math.tan(R) * Math.cos(d));
      var dipdir;
      var diry = magneticHeading;

      if (x === 0 && y === 0) {
        d = 0;
        dipdir = 180;
      }
      else if (x >= 0 && y >= 0) dipdir = diry - 90 - b;
      else if (y <= 0 && x >= 0) dipdir = diry - 90 + b;
      else if (y <= 0 && x <= 0) dipdir = diry + 90 - b;
      else if (x <= 0 && y >= 0) dipdir = diry + 90 + b;

      var strike = dipdir - 90;
      strike = strike % 360;
      dipdir = dipdir % 360;
      var dip = d;
      var trend = diry;
      var plunge = Math.acos(Math.abs(y) / g);

      if (vmParent.data.type === 'linear_orientation') {
        vmParent.data.trend = Math.round(trend * 1000) / 1000;
        vmParent.data.plunge = Math.round(plunge * 1000) / 1000;
      }
      else {
        vmParent.data.strike = Math.round(strike * 1000) / 1000;
        vmParent.data.dip_direction = Math.round(dipdir * 1000) / 1000;
        vmParent.data.dip = Math.round(dip * 1000) / 1000;
      }

      return {
        'strike': vmParent.data.strike, 'dipdir': vmParent.data.dip_direction, 'dip': vmParent.data.dip,
        'trend': vmParent.data.trend, 'plunge': vmParent.data.plunge
      };
    }

    function checkProperties() {
      _.each(vmParent.spot.properties.orientation_data, function (orientation) {
        assignProperties(orientation);
        _.each(orientation.associated_orientation, function (associated_orientation) {
          assignProperties(associated_orientation);
        });
      });
    }

    function createDefaultLabel(orientationToLabel) {
      var label = DataModelsFactory.getFeatureTypeLabel(orientationToLabel.feature_type);
      if (!label && orientationToLabel.type) label = orientationToLabel.type.split('_')[0] + ' feature';
      if (orientationToLabel.strike) label += ' ' + orientationToLabel.strike.toString();
      else if (orientationToLabel.trend) label += ' ' + orientationToLabel.trend.toString();
      return label;
    }

    function createModal() {
      $ionicModal.fromTemplateUrl('app/spot/basic-form-modal.html', {
        'scope': $scope,
        'animation': 'slide-in-up',
        'focusFirstInput': true,
        'backdropClickToClose': false
      }).then(function (modal) {
        vm.basicFormModal = modal;
      });

      // Cleanup the modal when we're done with it!
      $scope.$on('$destroy', function () {
        vm.basicFormModal.remove();
      });
    }

    function getModalTitlePart() {
      if (vmParent.data.type === 'linear_orientation') return 'Line';
      if (vmParent.data.type === 'planar_orientation') return 'Plane';
      if (vmParent.data.type === 'tabular_orientation') return 'Tabular Zone';
    }

    /**
     * Public Functions
     */

    function addAssociatedOrientation(parentThisOrientation, type) {
      vm.parentOrientation = parentThisOrientation;
      vmParent.survey = DataModelsFactory.getDataModel('orientation_data')[type].survey;
      vmParent.choices = DataModelsFactory.getDataModel('orientation_data')[type].choices;
      vmParent.data = {};
      vmParent.data.type = type;
      vmParent.data.id = HelpersFactory.newId();
      vm.modalTitle = 'Add a ' + getModalTitlePart();
      vm.basicFormModal.show();
    }

    function addOrientation(type) {
      vm.parentOrientation = undefined;
      vmParent.survey = DataModelsFactory.getDataModel('orientation_data')[type].survey;
      vmParent.choices = DataModelsFactory.getDataModel('orientation_data')[type].choices;
      vmParent.data = {};
      vmParent.data.type = type;
      vmParent.data.id = HelpersFactory.newId();
      vm.modalTitle = 'Add a ' + getModalTitlePart();
      vm.basicFormModal.show();
    }

    function copyAssociatedOrientation(parentThisOrientation, orientation) {
      var copy = angular.copy(orientation);
      delete copy.id;
      assignProperties(copy);
      parentThisOrientation.associated_orientation.push(copy);
    }

    function copyOrientation(orientation) {
      var copy = angular.copy(orientation);
      delete copy.id;
      _.each(copy.associated_orientation, function (associatedOrientation) {
        delete associatedOrientation.id;
        assignProperties(associatedOrientation);
      });
      assignProperties(copy);
      vmParent.spot.properties.orientation_data.push(copy);
    }

    function deleteAssociatedOrientation(parentThisOrientation, orientationToDelete) {
      var confirmPopup = $ionicPopup.confirm({
        'title': 'Delete Associated Orientation',
        'template': 'Are you sure you want to delete this  associated orientation?'
      });
      confirmPopup.then(function (res) {
        if (res) {
          parentThisOrientation.associated_orientation = _.reject(parentThisOrientation.associated_orientation,
            function (associatedOrientation) {
              return associatedOrientation.id === orientationToDelete.id;
            });
          if (parentThisOrientation.associated_orientation === 0) delete parentThisOrientation.associated_orientation;
        }
      });
    }

    function deleteOrientation(orientationToDelete) {
      var confirmPopup = $ionicPopup.confirm({
        'title': 'Delete Orientation',
        'template': 'Are you sure you want to delete this orientation?'
      });
      confirmPopup.then(function (res) {
        if (res) {
          vmParent.spot.properties.orientation_data = _.reject(vmParent.spot.properties.orientation_data,
            function (orientation) {
              return orientation.id === orientationToDelete.id;
            });
          if (vmParent.spot.properties.orientation_data === 0) delete vmParent.spot.properties.orientation_data;
          ProjectFactory.removeFeatureFromTags(vmParent.spot.properties.id, orientationToDelete.id);
        }
      });
    }

    function editAssociatedOrientation(parentThisOrientation, orientationToEdit) {
      vm.parentOrientation = parentThisOrientation;
      vmParent.data = angular.fromJson(angular.toJson(orientationToEdit));  // Copy value, not reference
      vmParent.survey = DataModelsFactory.getDataModel('orientation_data')[vmParent.data.type].survey;
      vmParent.choices = DataModelsFactory.getDataModel('orientation_data')[vmParent.data.type].choices;
      vm.modalTitle = 'Edit ' + getModalTitlePart();
      vm.basicFormModal.show();
    }

    function editOrientation(orientationToEdit) {
      vm.parentOrientation = undefined;
      vmParent.data = angular.fromJson(angular.toJson(orientationToEdit));  // Copy value, not reference
      vmParent.survey = DataModelsFactory.getDataModel('orientation_data')[vmParent.data.type].survey;
      vmParent.choices = DataModelsFactory.getDataModel('orientation_data')[vmParent.data.type].choices;
      vm.modalTitle = 'Edit ' + getModalTitlePart();
      vm.basicFormModal.show();
    }

    function getCompassInfo() {
      var promises = [];
      var promise;
      var msgText = '';
      var magneticHeading, x, y, z;

      promise = $cordovaDeviceOrientation.getCurrentHeading().then(function (result) {
        magneticHeading = result.magneticHeading;
        msgText += 'Magnetic Heading = ' + magneticHeading + '
';
      }, function (err) {
        msgText += 'Compass Error: ' + err + '
';
        $log.log(err);
      });
      promises.push(promise);

      if (navigator.accelerometer) {
        promise = $cordovaDeviceMotion.getCurrentAcceleration().then(function (result) {
          x = result.x;
          y = result.y;
          z = result.z;
          msgText += 'X = ' + x + '
';
          msgText += 'Y = ' + y + '
';
          msgText += 'Z = ' + z + '
';
        }, function (err) {
          msgText = 'Acceleration Error: ' + err + '
';
        });
        promises.push(promise);
      }
      else msgText += 'Accelerometer Error: No accelerometer on Device
';

      $q.all(promises).then(function () {
        if (magneticHeading && x && y && z) {
          var orientation = calculateOrientation(magneticHeading, x, y, z);
          if (vmParent.data.type === 'linear_orientation') {
            msgText += 'Trend = ' + orientation.trend + '
';
            msgText += 'Plunge = ' + orientation.plunge + '
';
          }
          else {
            msgText += 'Strike = ' + orientation.strike + '
';
            msgText += 'Dip Direction = ' + orientation.dipdir + '
';
            msgText += 'Dip = ' + orientation.dip + '
';
          }
        }
        $ionicPopup.alert({
          'title': 'Compass & Accelerometer Info',
          'template': msgText
        });
      });
    }

    function submit() {
      if (_.size(vmParent.data) <= 2) {
        // If not more than type and id fields no data has been entered so don't continue, just close modal
        vmParent.data = {};
        vm.parentOrientation = undefined;
        vm.basicFormModal.hide();
        return;
      }
      if (!vmParent.data.label) vmParent.data.label = createDefaultLabel(vmParent.data);
      if (FormFactory.validate(vmParent.survey, vmParent.data)) {
        if (!vm.parentOrientation) {
          if (!vmParent.spot.properties.orientation_data) vmParent.spot.properties.orientation_data = [];
          vmParent.spot.properties.orientation_data = _.reject(vmParent.spot.properties.orientation_data,
            function (orientation) {
              return orientation.id === vmParent.data.id;
            });
          vmParent.spot.properties.orientation_data.push(vmParent.data);
        }
        else {
          if (!vm.parentOrientation.associated_orientation) vm.parentOrientation.associated_orientation = [];
          vm.parentOrientation.associated_orientation = _.reject(vm.parentOrientation.associated_orientation,
            function (associatedOrientation) {
              return associatedOrientation.id === vmParent.data.id;
            });
          vm.parentOrientation.associated_orientation.push(vmParent.data);
          vmParent.spot.properties.orientation_data = _.reject(vmParent.spot.properties.orientation_data,
            function (orientation) {
              return orientation.id === vm.parentOrientation.id;
            });
          vmParent.spot.properties.orientation_data.push(vm.parentOrientation);
        }
        vmParent.data = {};
        vm.basicFormModal.hide();
      }
    }
  }
}());
<|endoftext|>


<commit_before>/** Global: trainerName */

$(function () {
	$.getJSON( "core/json/variables.json", function( jsondata ) {
		var pokeimg_suffix=jsondata['system']['pokeimg_suffix'];

		$('.trainerLoader').hide();
		var page = 0;
		var teamSelector=0; //0=all;1=Blue;2=Red;3=Yellow
		var rankingFilter=0; //0=Level & Gyms; 1=Level; 2=Gyms
		$('input#name').val(trainerName);
		loadTrainers(page,$('input#name').val(),null,null,pokeimg_suffix);
		page++;
		var win = $(window);
		win.scroll(function () {
			// End of the document reached?
			if ($(document).height() - win.height() == win.scrollTop()) {
				loadTrainers(page,$('input#name').val(),teamSelector,rankingFilter,pokeimg_suffix);
				page++;
			}
		});
		$("#searchTrainer").submit(function ( event ) {
			page = 0;
			$('input#name').val()!=''?$('#trainersGraph').hide():$('#trainersGraph').show();
			$('#trainersContainer tr:not(.trainersTemplate)').remove();
			loadTrainers(page,$('input#name').val(),teamSelector,rankingFilter,pokeimg_suffix);
			page++;
			event.preventDefault();
		});
		$(".teamSelectorItems").click(function ( event ) {
			switch ($(this).attr("id")) {
				case "AllTeamsFilter":
					teamSelector=0;
					break;
				case "BlueTeamFilter":
					teamSelector=1;
					break;
				case "RedTeamFilter":
					teamSelector=2;
					break;
				case "YellowFilter":
					teamSelector=3;
					break;
				default:
					teamSelector=0;
			}
			$("#teamSelectorText").html($(this).html());
			event.preventDefault();
			$("#searchTrainer").submit();

		});
		$(".rankingOrderItems").click(function ( event ) {
			switch ($(this).attr("id")) {
				case "levelsFirst":
					rankingFilter=0;
					break;
				case "gymsFirst":
					rankingFilter=1;
					break;
				case "maxCpFirst":
					rankingFilter=2;
					break;
				default:
					rankingFilter=0;
			}
			$("#rankingOrderText").html($(this).html());
			event.preventDefault();
			$("#searchTrainer").submit();

		});

	});
});

function loadTrainers(page,name,teamSelector,rankingFilter,pokeimg_suffix) {
	$('.trainerLoader').show();
	window.history.pushState("","","trainer?name="+name);
	var trainerIndex = 0+(page*10);
	$.ajax({
		'async': true,
		'type': "GET",
		'global': false,
		'dataType': 'json',
		'url': "core/process/aru.php",
		'data': {
			'request': "",
			'target': 'arrange_url',
			'method': 'method_target',
			'type' : 'trainer',
			'page' : page,
			'name' : name,
			'team' : teamSelector,
			'ranking' :rankingFilter
		}
	}).done(function (data) {
		$.each(data, function (trainerName, trainer) {
			trainerIndex++;
			printTrainer(trainer, trainerIndex,pokeimg_suffix);
		});
		$('.trainerLoader').hide();
	});
};
function printTrainer(trainer, trainerIndex,pokeimg_suffix) {
	var trainersInfos = $('<tr>',{id: 'trainerInfos_'+trainer.name}).css('border-bottom','2px solid '+(trainer.team=="3"?"#ffbe08":trainer.team=="2"?"#ff7676":"#00aaff"));
	trainersInfos.append($('<td>',{id : 'trainerIndex_'+trainer.name, text : trainerIndex}));
	trainersInfos.append($('<td>',{id : 'trainerRank_'+trainer.name, text : trainer.rank}));
	trainersInfos.append($('<td>',{id : 'trainerName_'+trainer.name, text : trainer.name}).click(
		function (e) {
			e.preventDefault();$('input#name').val(trainer.name);
			$("#searchTrainer").submit();
			$('#trainerName_'+trainer.name).off('click');
		}
	));
	trainersInfos.append($('<td>',{id : 'trainerLevel_'+trainer.name, text : trainer.level}));
	trainersInfos.append($('<td>',{id : 'trainerGyms_'+trainer.name, text : trainer.gyms}));
	trainersInfos.append($('<td>',{id : 'trainerLastSeen_'+trainer.name, text : trainer.last_seen}));
	$('#trainersContainer').append(trainersInfos);
	var trainersPokemonsRow = $('<tr>',{id: 'trainerPokemons_'+trainer.name});
	var trainersPokemons = $('<td>',{colspan : 6});
	var trainersPokemonsContainer = $('<div>',{class : ""});
	for (var pokeIndex = 0; pokeIndex<trainer.pokemons.length; pokeIndex++) {
		var pokemon = trainer.pokemons[pokeIndex];

		trainersPokemonsContainer.append(printPokemon(pokemon,pokeimg_suffix));
	}

	trainersPokemons.append(trainersPokemonsContainer);
	trainersPokemonsRow.append(trainersPokemons);
	$('#trainersContainer').append(trainersPokemonsRow);
}

function printPokemon(pokemon,pokeimg_suffix){
	var trainerPokemon = $('<div>',{id : 'trainerPokemon_'+pokemon.pokemon_uid, class: "col-md-1 col-xs-4 pokemon-single", style: "text-align: center" });
	var gymClass = "";
	if ((pokemon.gym_id===null)) {
		gymClass = "unseen";
	}
	trainerPokemon.append(
		$('<a>',
			{href : 'pokemon/'+pokemon.pokemon_id}
		).append($('<img />',
			{	src : 'core/pokemons/'+pokemon.pokemon_id+pokeimg_suffix,
				'class' : 'img-responsive '+gymClass
			})
		)
	);
	trainerPokemon.append($('<p>',{class : 'pkmn-name'}).append(pokemon.cp));
	var progressBar = $('<div>',{class : 'progress'}).css({'height': '6px','margin-bottom': '0'});
	progressBar.append(
		$('<div>',
			{
			title: 'IV Attack :'+pokemon.iv_attack,
			class: 'progress-bar progress-bar-danger' ,
			role : 'progressbar',
			'aria-valuenow' : pokemon.iv_attack,
			'aria-valuemin' : 0,
			'aria-valuemax' : 45
		}).css('width',((100/45)*pokemon.iv_attack ) + '%'))
	progressBar.append(
		$('<div>',
			{
			title: 'IV Defense :'+pokemon.iv_defense,
			class: 'progress-bar progress-bar-info' ,
			role : 'progressbar',
			'aria-valuenow': pokemon.iv_defense,
			'aria-valuemin' : 0,
			'aria-valuemax' : 45
		}).css('width',((100/45)*pokemon.iv_defense ) + '%'))
	progressBar.append(
		$('<div>',
			{
			title: 'IV Stamina :'+pokemon.iv_stamina,
			class: 'progress-bar progress-bar-success' ,
			role : 'progressbar',
			'aria-valuenow' :pokemon.iv_stamina,
			'aria-valuemin' : 0,
			'aria-valuemax' : 45
		}).css('width',((100/45)*pokemon.iv_stamina ) + '%'))
	trainerPokemon.append(progressBar);
	if (pokemon.last_scanned === '0') {
		trainerPokemon.append($('<small>',{text: "Today"}));
	}
	else if (pokemon.last_scanned === '1') {
		trainerPokemon.append($('<small>',{text: pokemon.last_scanned + " Day"}));
	}
	else {
		trainerPokemon.append($('<small>',{text: pokemon.last_scanned + " Days"}));
	}
	return trainerPokemon;
}
<commit_msg>Add link to trainer name in trainer page<commit_after>/** Global: trainerName */

$(function () {
	$.getJSON( "core/json/variables.json", function( jsondata ) {
		var pokeimg_suffix=jsondata['system']['pokeimg_suffix'];

		$('.trainerLoader').hide();
		var page = 0;
		var teamSelector=0; //0=all;1=Blue;2=Red;3=Yellow
		var rankingFilter=0; //0=Level & Gyms; 1=Level; 2=Gyms
		$('input#name').val(trainerName);
		loadTrainers(page,$('input#name').val(),null,null,pokeimg_suffix);
		page++;
		var win = $(window);
		win.scroll(function () {
			// End of the document reached?
			if ($(document).height() - win.height() == win.scrollTop()) {
				loadTrainers(page,$('input#name').val(),teamSelector,rankingFilter,pokeimg_suffix);
				page++;
			}
		});
		$("#searchTrainer").submit(function ( event ) {
			page = 0;
			$('input#name').val()!=''?$('#trainersGraph').hide():$('#trainersGraph').show();
			$('#trainersContainer tr:not(.trainersTemplate)').remove();
			loadTrainers(page,$('input#name').val(),teamSelector,rankingFilter,pokeimg_suffix);
			page++;
			event.preventDefault();
		});
		$(".teamSelectorItems").click(function ( event ) {
			switch ($(this).attr("id")) {
				case "AllTeamsFilter":
					teamSelector=0;
					break;
				case "BlueTeamFilter":
					teamSelector=1;
					break;
				case "RedTeamFilter":
					teamSelector=2;
					break;
				case "YellowFilter":
					teamSelector=3;
					break;
				default:
					teamSelector=0;
			}
			$("#teamSelectorText").html($(this).html());
			event.preventDefault();
			$("#searchTrainer").submit();

		});
		$(".rankingOrderItems").click(function ( event ) {
			switch ($(this).attr("id")) {
				case "levelsFirst":
					rankingFilter=0;
					break;
				case "gymsFirst":
					rankingFilter=1;
					break;
				case "maxCpFirst":
					rankingFilter=2;
					break;
				default:
					rankingFilter=0;
			}
			$("#rankingOrderText").html($(this).html());
			event.preventDefault();
			$("#searchTrainer").submit();

		});

	});
});

function loadTrainers(page,name,teamSelector,rankingFilter,pokeimg_suffix) {
	$('.trainerLoader').show();
	window.history.pushState("","","trainer?name="+name);
	var trainerIndex = 0+(page*10);
	$.ajax({
		'async': true,
		'type': "GET",
		'global': false,
		'dataType': 'json',
		'url': "core/process/aru.php",
		'data': {
			'request': "",
			'target': 'arrange_url',
			'method': 'method_target',
			'type' : 'trainer',
			'page' : page,
			'name' : name,
			'team' : teamSelector,
			'ranking' :rankingFilter
		}
	}).done(function (data) {
		$.each(data, function (trainerName, trainer) {
			trainerIndex++;
			printTrainer(trainer, trainerIndex,pokeimg_suffix);
		});
		$('.trainerLoader').hide();
	});
};
function printTrainer(trainer, trainerIndex,pokeimg_suffix) {
	var trainersInfos = $('<tr>',{id: 'trainerInfos_'+trainer.name}).css('border-bottom','2px solid '+(trainer.team=="3"?"#ffbe08":trainer.team=="2"?"#ff7676":"#00aaff"));
	trainersInfos.append($('<td>',{id : 'trainerIndex_'+trainer.name, text : trainerIndex}));
	trainersInfos.append($('<td>',{id : 'trainerRank_'+trainer.name, text : trainer.rank}));
	trainersInfos.append($('<td>',{id : 'trainerName_'+trainer.name}).append($('<a>',{href: 'trainer?name='+trainer.name, text: trainer.name})).click(
		function (e) {
			e.preventDefault();$('input#name').val(trainer.name);
			$("#searchTrainer").submit();
			$('#trainerName_'+trainer.name).off('click');
		}
	));
	trainersInfos.append($('<td>',{id : 'trainerLevel_'+trainer.name, text : trainer.level}));
	trainersInfos.append($('<td>',{id : 'trainerGyms_'+trainer.name, text : trainer.gyms}));
	trainersInfos.append($('<td>',{id : 'trainerLastSeen_'+trainer.name, text : trainer.last_seen}));
	$('#trainersContainer').append(trainersInfos);
	var trainersPokemonsRow = $('<tr>',{id: 'trainerPokemons_'+trainer.name});
	var trainersPokemons = $('<td>',{colspan : 6});
	var trainersPokemonsContainer = $('<div>',{class : ""});
	for (var pokeIndex = 0; pokeIndex<trainer.pokemons.length; pokeIndex++) {
		var pokemon = trainer.pokemons[pokeIndex];

		trainersPokemonsContainer.append(printPokemon(pokemon,pokeimg_suffix));
	}

	trainersPokemons.append(trainersPokemonsContainer);
	trainersPokemonsRow.append(trainersPokemons);
	$('#trainersContainer').append(trainersPokemonsRow);
}

function printPokemon(pokemon,pokeimg_suffix){
	var trainerPokemon = $('<div>',{id : 'trainerPokemon_'+pokemon.pokemon_uid, class: "col-md-1 col-xs-4 pokemon-single", style: "text-align: center" });
	var gymClass = "";
	if ((pokemon.gym_id===null)) {
		gymClass = "unseen";
	}
	trainerPokemon.append(
		$('<a>',
			{href : 'pokemon/'+pokemon.pokemon_id}
		).append($('<img />',
			{	src : 'core/pokemons/'+pokemon.pokemon_id+pokeimg_suffix,
				'class' : 'img-responsive '+gymClass
			})
		)
	);
	trainerPokemon.append($('<p>',{class : 'pkmn-name'}).append(pokemon.cp));
	var progressBar = $('<div>',{class : 'progress'}).css({'height': '6px','margin-bottom': '0'});
	progressBar.append(
		$('<div>',
			{
			title: 'IV Attack :'+pokemon.iv_attack,
			class: 'progress-bar progress-bar-danger' ,
			role : 'progressbar',
			'aria-valuenow' : pokemon.iv_attack,
			'aria-valuemin' : 0,
			'aria-valuemax' : 45
		}).css('width',((100/45)*pokemon.iv_attack ) + '%'))
	progressBar.append(
		$('<div>',
			{
			title: 'IV Defense :'+pokemon.iv_defense,
			class: 'progress-bar progress-bar-info' ,
			role : 'progressbar',
			'aria-valuenow': pokemon.iv_defense,
			'aria-valuemin' : 0,
			'aria-valuemax' : 45
		}).css('width',((100/45)*pokemon.iv_defense ) + '%'))
	progressBar.append(
		$('<div>',
			{
			title: 'IV Stamina :'+pokemon.iv_stamina,
			class: 'progress-bar progress-bar-success' ,
			role : 'progressbar',
			'aria-valuenow' :pokemon.iv_stamina,
			'aria-valuemin' : 0,
			'aria-valuemax' : 45
		}).css('width',((100/45)*pokemon.iv_stamina ) + '%'))
	trainerPokemon.append(progressBar);
	if (pokemon.last_scanned === '0') {
		trainerPokemon.append($('<small>',{text: "Today"}));
	}
	else if (pokemon.last_scanned === '1') {
		trainerPokemon.append($('<small>',{text: pokemon.last_scanned + " Day"}));
	}
	else {
		trainerPokemon.append($('<small>',{text: pokemon.last_scanned + " Days"}));
	}
	return trainerPokemon;
}
<|endoftext|>


<commit_before>import { setProperties } from '@ember/object';
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import URI from 'jsuri';
import config from 'ember-get-config';

module('Unit | Component | imgix image', function (hooks) {
  setupTest(hooks);

  test('the generated img has a srcset in the format of 2x, 3x, 4x, 5x when passing a fixed width', function (assert) {
    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
      width: 100,
    });

    const srcset = component.get('srcset');
    const actualNumberOfSrcSets = srcset.split(', ').length;
    assert.equal(actualNumberOfSrcSets, 4);
    srcset.split(', ').forEach((srcset) => {
      assert.ok(srcset.split(' ')[1].match(/^\dx$/));
    });
  });

  test('the generated img has a srcset in the format of 2x, 3x, 4x, 5x when passing a fixed height', function (assert) {
    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
      height: 100,
    });

    const srcset = component.get('srcset');
    const actualNumberOfSrcSets = srcset.split(', ').length;
    assert.equal(actualNumberOfSrcSets, 4);
    srcset.split(', ').forEach((srcset) => {
      assert.ok(srcset.split(' ')[1].match(/^\dx$/));
    });
  });

  test('the generated img has the correct number of srcsets', function (assert) {
    const expectedNumberOfSrcSets = 31;

    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
    });

    const srcset = component.get('srcset');
    const actualNumberOfSrcSets = srcset.split(',').length;
    assert.equal(actualNumberOfSrcSets, expectedNumberOfSrcSets);
  });

  test('the generated img has srcsets in the correct format', function (assert) {
    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
    });

    const srcset = component.get('srcset');
    const srcsets = srcset.split(',').map((v) => v.trim());

    srcsets.forEach((srcset) => {
      assert.equal(srcset.split(' ').length, 2);
      const [url, width] = srcset.split(' ');
      assert.ok(url);
      assert.ok(width.match(/^\d+w$/));
    });
  });

  test('the generated img should not contain a srcset when disableSrcSet is set', function (assert) {
    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
      disableSrcSet: true,
    });

    const srcset = component.get('srcset');
    assert.notOk(srcset);
  });

  test('the generated src url has an ixlib parameter', function (assert) {
    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
    });

    const src = component.get('src');
    const url = new URI(src);
    assert.ok(src.includes('ixlib=ember-'));
    assert.ok(/^ember-\d\.\d\.\d$/.test(url.getQueryParamValue('ixlib')));
  });

  test('setting disableLibraryParam should cause the url not to contain an ixlib parameter', function (assert) {
    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
      disableLibraryParam: true,
    });

    const src = component.get('src');
    assert.false(src.includes('ixlib=ember-'));
  });

  test('setting disableLibraryParam in the global config should cause the url not to contain an ixlib parameter', function (assert) {
    const oldDisableLibraryParam = config.APP.imgix.disableLibraryParam;

    config.APP.imgix.disableLibraryParam = true;
    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
    });

    const src = component.get('src');
    assert.false(src.includes('ixlib=ember-'));

    config.APP.imgix.disableLibraryParam = oldDisableLibraryParam;
  });
});
<commit_msg>Manually fix up qunit/require-expect in imgix-image-test<commit_after>import { setProperties } from '@ember/object';
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import URI from 'jsuri';
import config from 'ember-get-config';

module('Unit | Component | imgix image', function (hooks) {
  setupTest(hooks);

  test('the generated img has a srcset in the format of 2x, 3x, 4x, 5x when passing a fixed width', function (assert) {
    assert.expect(5);
    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
      width: 100,
    });

    const srcset = component.get('srcset');
    const actualNumberOfSrcSets = srcset.split(', ').length;
    assert.equal(actualNumberOfSrcSets, 4);
    srcset.split(', ').forEach((srcset) => {
      assert.ok(srcset.split(' ')[1].match(/^\dx$/));
    });
  });

  test('the generated img has a srcset in the format of 2x, 3x, 4x, 5x when passing a fixed height', function (assert) {
    assert.expect(5);
    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
      height: 100,
    });

    const srcset = component.get('srcset');
    const actualNumberOfSrcSets = srcset.split(', ').length;
    assert.equal(actualNumberOfSrcSets, 4);
    srcset.split(', ').forEach((srcset) => {
      assert.ok(srcset.split(' ')[1].match(/^\dx$/));
    });
  });

  test('the generated img has the correct number of srcsets', function (assert) {
    const expectedNumberOfSrcSets = 31;

    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
    });

    const srcset = component.get('srcset');
    const actualNumberOfSrcSets = srcset.split(',').length;
    assert.equal(actualNumberOfSrcSets, expectedNumberOfSrcSets);
  });

  test('the generated img has srcsets in the correct format', function (assert) {
    assert.expect(93);
    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
    });

    const srcset = component.get('srcset');
    const srcsets = srcset.split(',').map((v) => v.trim());

    srcsets.forEach((srcset) => {
      assert.equal(srcset.split(' ').length, 2);
      const [url, width] = srcset.split(' ');
      assert.ok(url);
      assert.ok(width.match(/^\d+w$/));
    });
  });

  test('the generated img should not contain a srcset when disableSrcSet is set', function (assert) {
    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
      disableSrcSet: true,
    });

    const srcset = component.get('srcset');
    assert.notOk(srcset);
  });

  test('the generated src url has an ixlib parameter', function (assert) {
    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
    });

    const src = component.get('src');
    const url = new URI(src);
    assert.ok(src.includes('ixlib=ember-'));
    assert.ok(/^ember-\d\.\d\.\d$/.test(url.getQueryParamValue('ixlib')));
  });

  test('setting disableLibraryParam should cause the url not to contain an ixlib parameter', function (assert) {
    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
      disableLibraryParam: true,
    });

    const src = component.get('src');
    assert.false(src.includes('ixlib=ember-'));
  });

  test('setting disableLibraryParam in the global config should cause the url not to contain an ixlib parameter', function (assert) {
    const oldDisableLibraryParam = config.APP.imgix.disableLibraryParam;

    config.APP.imgix.disableLibraryParam = true;
    const component = this.owner.factoryFor('component:imgix-image').create();
    setProperties(component, {
      path: '/users/1.png',
    });

    const src = component.get('src');
    assert.false(src.includes('ixlib=ember-'));

    config.APP.imgix.disableLibraryParam = oldDisableLibraryParam;
  });
});
<|endoftext|>


<commit_before>/*
 * degradeInputs unit tests
 */

(function($){
	module('jquery.mobile.slider.js');

	test('keepNative elements should not be degraded', function() {
		same($('input#not-to-be-degraded').attr("type"), "range");
	});

	test('should degrade input type to a different type, as specified in page options', function(){
		var degradeInputs = $.mobile.page.prototype.options.degradeInputs;

		expect( degradeInputs.length );

		// Initialize dialog page
		$.mobile.changePage($('#dialog'));
		$.mobile.changePage($('#page'));

		$.each(degradeInputs, function( oldType, newType ) {
			if (newType === false) {
				newType = oldType;
			}

			$('#page-test-container').html('<input type="' + oldType + '" />').trigger("create");

			same($('#page-test-container input').attr("type"), newType);

			$('#dialog-test-container').html('<input type="' + oldType + '" />').trigger("create");

			same($('#dialog-test-container input').attr("type"), newType);
		});
	});
})(jQuery);<commit_msg>respect page loading times and comment on assumption in degradeInputs test<commit_after>/*
 * degradeInputs unit tests
 */

(function($){
	module('jquery.mobile.slider.js');

	test('keepNative elements should not be degraded', function() {
		same($('input#not-to-be-degraded').attr("type"), "range");
	});

	asyncTest('should degrade input type to a different type, as specified in page options', function(){
		var degradeInputs = $.mobile.page.prototype.options.degradeInputs;

		expect( degradeInputs.length );

		// NOTE the initial page is already enhanced (or expected to be) so we load the dialog to enhance it
		// and _expect_ that the default page will remain "unreaped". This will break if that assumption changes
		$.testHelper.pageSequence([
			function() {
				$.mobile.changePage( "#dialog" );
			},

			function() {
				$.each(degradeInputs, function( oldType, newType ) {
					if (newType === false) {
						newType = oldType;
					}

					$('#page-test-container').html('<input type="' + oldType + '" />').trigger("create");

					same($('#page-test-container input').attr("type"), newType, "type attr on page is: " + newType);

					$('#dialog-test-container').html('<input type="' + oldType + '" />').trigger("create");

					same($('#dialog-test-container input').attr("type"), newType, "type attr on dialog is: " + newType);
				});

				start();
			}
		]);
	});
})(jQuery);<|endoftext|>


<commit_before>// ==UserScript==
// @name         Waze Map Editor - Utils
// @namespace    http://tampermonkey.net/
// @version      1.0.6
// @description  set of utils to speed development
// @author       Delfim Machado - dbcm@profundos.org
// @match        https://beta.waze.com/*editor/*
// @match        https://www.waze.com/*editor/*
// @exclude      https://www.waze.com/*user/*editor/*
// @grant        none
// ==/UserScript==

/*

reusable code for all WME tools i'm building

*/

(function(root) {
    "use strict";

    var face = {
        'meh': '¯\_(ツ)_/¯',
        'angry': '(⋟﹏⋞)',
        'happy': '⎦˚◡˚⎣'
    };

    var WMEutils = function(options) {
        this.init(options);
    };

    WMEutils.prototype.init = function(opt) {
        this._VERSION = 0.1;

        opt = opt || {};

        this.debug = opt.debug;

        this.app = opt.app || 'DUH';
        this.uid = opt.uid || '___';
        this.version = opt.version || '0.0.666';
    };

    /*
    	o
    	{
    		id: "blame",
    		name: "bl",
    		title: 'blame plugin : ¯\\_(ツ)_/¯  [last 10 days]',
    		desc: 'i blame you all',
    		content: menu
    	}
    */
    WMEutils.prototype.addTab = function(o) {
        var self = this;

        // while testing and developing...
        var mdk = function(id) {
            try {
                document.getElementById(id).remove();
            } catch (e) {
                console.log("X");
            };
        }

        if (document.getElementById("t" + o.id)) {
            return;
        };

        var addon = document.createElement('div');
        addon.innerHTML += '

' + o.title + '

';
        addon.innerHTML += o.content;
        addon.innerHTML += '

';

        var navTabs = document.getElementsByClassName("nav nav-tabs")[0];
        var tabContent = document.getElementsByClassName("tab-content")[0];

        var newtab = document.createElement('li');
        newtab.id = "t" + o.id;
        newtab.innerHTML = '' + o.name + '';
        //mdk("t" + o.id);
        navTabs.appendChild(newtab);

        addon.id = "sidepanel-" + o.id;
        addon.className = "tab-pane";
        //mdk("sidepanel-" + o.id);
        tabContent.appendChild(addon);

        return true;
    };

    /*
    	f = ARRAY of functions
    */
    WMEutils.prototype.loopSegments = function(f) {
        var ret = {};

        for (var segId in Waze.model.segments.objects) {
            var seg = Waze.model.segments.get(segId);

            if (!this.isOnScreen(seg)) {
                continue;
            }

            if (!this.canEdit(seg)) {
                continue;
            }

            var re = [];
            for (var i = 0; i < f.length; i++) {
                if (f[i]) {
                    var r = f[i](seg);
                    if (r && r.id)
                        re.push(r);
                };
            }
            if (re.length > 0)
                ret[seg.attributes.id] = re;
        }

        return ret;
    }

    /*
    	f = ARRAY of functions
    */
    WMEutils.prototype.loopVenues = function(f) {
        var ret = {};

        for (var venId in Waze.model.venues.objects) {
            var ven = Waze.model.venues.get(venId);

            if (!this.isOnScreen(ven)) {
                continue;
            }

            if (!this.canEdit(ven)) {
                continue;
            }

            var re = [];
            for (var i = 0; i < f.length; i++) {
                if (f[i]) {
                    var r = f[i](ven);
                    if (r && r.id)
                        re.push(r);
                }
            }
            if (re.length > 0)
                ret[ven.attributes.id] = re;
        }

        return ret;
    };

    /*
    	f = ARRAY of functions
    */
    WMEutils.prototype.loopNodes = function(f) {
        var ret = {};

        for (var nodId in Waze.model.nodes.objects) {
            var nod = Waze.model.nodes.get(nodId);

            if (!this.isOnScreen(nod)) {
                continue;
            }

            if (!this.canEdit(nod)) {
                continue;
            }

            var re = [];
            for (var i = 0; i < f.length; i++) {
                if (f[i]) {
                    var r = f[i](nod);
                    if (r && r.id)
                        re.push(r);
                }
            }
            if (re.length > 0)
                ret[nod.attributes.id] = re;
        }

        return ret;
    };

    /*
    	if the object visible
    */
    WMEutils.prototype.isOnScreen = function(obj) {
        if (obj.geometry) {
            return (Waze.map.getExtent().intersectsBounds(obj.geometry.getBounds()));
        }
        return false;
    }

    /*
    	can i edit this object
    */
    WMEutils.prototype.canEdit = function(obj) {
        if (obj.isDeleted())
            return false;

        if (obj.type === 'segment')
            return obj.isAllowed(obj.PERMISSIONS.EDIT_GEOMETRY) && !obj.hasClosures(); // || obj.isUpdated();
        if (obj.type === 'venue')
            return obj.isAllowed(obj.PERMISSIONS.EDIT_GEOMETRY) && obj.areExternalProvidersEditable(); // || obj.isUpdated();
        if (obj.type === 'node')
            return !obj.isConnectedToBigJunction() && obj.areConnectionsEditable() &&
                obj.isAllowedToMoveNode() &&
                obj.isAllowed(obj.PERMISSIONS.DELETE); // obj.isUpdated();
    };

    /*
    	is this object in Portugal
    */
    WMEutils.prototype.isPortugal = function(obj) {
        var att = obj.attributes;
        var street = Waze.model.streets.get(att.primaryStreetID);
        var city = segment.model.cities.get(street.cityID);
        var countryId = city.countryID;

        return countryId === 181;
    }

    /*
    	return a random color
    */
    WMEutils.prototype.rColor = function() {
        var letters = '0123456789ABCDEF';
        var color = '#';
        for (var i = 0; i < 6; i++) {
            color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
    }

    /*
        obj = must be a segment OBJ
    */
    WMEutils.prototype.isDrivable = function(obj) {
        if (obj.type === 'segment') {
            var drivable = [1, 2, 3, 4, 6, 7, 8, 17, 15, 20];

            if (drivable.includes(obj.attributes.roadType)) {
                return true;
            }
        };
        return false;
    };

    /*
        obj = object to highlight, can be and segment or a place (landmark/venue)
        color = highlight color
        bgColor = background color, if null, defaults to color
    */
    WMEutils.prototype.highlightObject = function(obj, color, bgColor, label) {
        return new OpenLayers.Feature.Vector(obj.geometry.clone(), {}, {
            strokeColor: color,
            strokeDashstyle: "none",
            strokeLinecap: "round",
            strokeWidth: 15,
            strokeOpacity: 0.5,
            fill: true,
            fillColor: bgColor || color,
            fillOpacity: 0.2,
            pointRadius: 6,
            fontColor: color,
            labelOutlineColor: bgColor || 'black',
            labelOutlineWidth: 4,
            labelAlign: 'cm',
            label: label || null,
            rotation: 0.785398164,
            textAlign: 'center',
            textBaseline: 'middle'
        });
    };

    /*
    	options stuff
    */
    WMEutils.prototype.loadOptions = function() {
        var self = this;

        return JSON.parse(localStorage.getItem(self.uid + "_options"));
    }
    WMEutils.prototype.saveOptions = function(options) {
        var self = this;

        return localStorage.setItem(self.uid + "_options", JSON.stringify(options));
    }

    /*
    	log stuff
    */
    WMEutils.prototype.log = function(msg) {
        var self = this;

        var now = Date.now();
        console.log("[" + this.app + "] " + now + " : " + msg);
    }

    /*
    	returns true if you are using beta editor
    */
    WMEutils.prototype.onBeta = function() {
        return -1 !== window.location.href.indexOf("beta");
    }

    /*
    	add menu layer

        section = [issues, places, road, display]
        name = layer name
        uid = internal id
        callback = function() {...}
        layer = OL Layer
    */
    WMEutils.prototype.addMenuLayer = function(o) {
        // from WME Street View Availability
        var roadGroupSelector = document.getElementById('layer-switcher-group_' + o.section);
        if (roadGroupSelector !== null) {
            var roadGroup = roadGroupSelector.parentNode.parentNode.querySelector('.children');
            var toggler = document.createElement('li');
            var togglerContainer = document.createElement('div');
            togglerContainer.className = 'controls-container toggler';
            var checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.id = 'layer-switcher-item_' + o.uid;
            checkbox.className = 'toggle';
            checkbox.checked = true;
            checkbox.addEventListener('click', function(e) {
                o.layer.setVisibility(e.target.checked);
            });
            togglerContainer.appendChild(checkbox);
            var label = document.createElement('label');
            label.htmlFor = checkbox.id;
            var labelText = document.createElement('span');
            labelText.className = 'label-text';
            labelText.appendChild(document.createTextNode(o.name));
            label.appendChild(labelText);
            togglerContainer.appendChild(label);
            toggler.appendChild(togglerContainer);
            roadGroup.appendChild(toggler);
        }
    };

    root.WMEutils = WMEutils;
})(window);
<commit_msg>more functions<commit_after>// ==UserScript==
// @name         Waze Map Editor - Utils
// @namespace    http://tampermonkey.net/
// @version      1.0.6
// @description  set of utils to speed development
// @author       Delfim Machado - dbcm@profundos.org
// @match        https://beta.waze.com/*editor/*
// @match        https://www.waze.com/*editor/*
// @exclude      https://www.waze.com/*user/*editor/*
// @grant        none
// ==/UserScript==

/*

reusable code for all WME tools i'm building

*/

(function(root) {
    "use strict";

    var face = {
        'meh': '¯\_(ツ)_/¯',
        'angry': '(⋟﹏⋞)',
        'happy': '⎦˚◡˚⎣'
    };

    var WMEutils = function(options) {
        this.init(options);
    };

    WMEutils.prototype.init = function(opt) {
        this._VERSION = 0.1;

        opt = opt || {};

        this.debug = opt.debug;

        this.app = opt.app || 'DUH';
        this.uid = opt.uid || '___';
        this.version = opt.version || '0.0.666';
        this.doLog = opt.hasOwnProperty('doLog') ? opt.doLog : true;
    };

    /*
    	o
    	{
    		id: "blame",
    		name: "bl",
    		title: 'blame plugin : ¯\\_(ツ)_/¯  [last 10 days]',
    		desc: 'i blame you all',
    		content: menu
    	}
    */
    WMEutils.prototype.addTab = function(o) {
        var self = this;

        // while testing and developing...
        var mdk = function(id) {
            try {
                document.getElementById(id).remove();
            } catch (e) {
                console.log("X");
            };
        }

        if (document.getElementById("t" + o.id)) {
            return;
        };

        var addon = document.createElement('div');
        addon.innerHTML += '

' + o.title + '

';
        addon.innerHTML += o.content;
        addon.innerHTML += '

';

        var navTabs = document.getElementsByClassName("nav nav-tabs")[0];
        var tabContent = document.getElementsByClassName("tab-content")[0];

        var newtab = document.createElement('li');
        newtab.id = "t" + o.id;
        newtab.innerHTML = '' + o.name + '';
        //mdk("t" + o.id);
        navTabs.appendChild(newtab);

        addon.id = "sidepanel-" + o.id;
        addon.className = "tab-pane";
        //mdk("sidepanel-" + o.id);
        tabContent.appendChild(addon);

        return true;
    };

    /*
    	f = ARRAY of functions
    */
    WMEutils.prototype.loopSegments = function(f) {
        var ret = {};

        for (var segId in Waze.model.segments.objects) {
            var seg = Waze.model.segments.get(segId);

            if (!this.isOnScreen(seg)) {
                continue;
            }

            if (!this.canEdit(seg)) {
                continue;
            }

            var re = [];
            for (var i = 0; i < f.length; i++) {
                if (f[i]) {
                    var r = f[i](seg);
                    if (r && r.id)
                        re.push(r);
                };
            }
            if (re.length > 0)
                ret[seg.attributes.id] = re;
        }

        return ret;
    }

    /*
    	f = ARRAY of functions
    */
    WMEutils.prototype.loopVenues = function(f) {
        var ret = {};

        for (var venId in Waze.model.venues.objects) {
            var ven = Waze.model.venues.get(venId);

            if (!this.isOnScreen(ven)) {
                continue;
            }

            if (!this.canEdit(ven)) {
                continue;
            }

            var re = [];
            for (var i = 0; i < f.length; i++) {
                if (f[i]) {
                    var r = f[i](ven);
                    if (r && r.id)
                        re.push(r);
                }
            }
            if (re.length > 0)
                ret[ven.attributes.id] = re;
        }

        return ret;
    };

    /*
    	f = ARRAY of functions
    */
    WMEutils.prototype.loopNodes = function(f) {
        var ret = {};

        for (var nodId in Waze.model.nodes.objects) {
            var nod = Waze.model.nodes.get(nodId);

            if (!this.isOnScreen(nod)) {
                continue;
            }

            if (!this.canEdit(nod)) {
                continue;
            }

            var re = [];
            for (var i = 0; i < f.length; i++) {
                if (f[i]) {
                    var r = f[i](nod);
                    if (r && r.id)
                        re.push(r);
                }
            }
            if (re.length > 0)
                ret[nod.attributes.id] = re;
        }

        return ret;
    };

    /*
    	if the object visible
    */
    WMEutils.prototype.isOnScreen = function(obj) {
        if (obj.geometry) {
            return (Waze.map.getExtent().intersectsBounds(obj.geometry.getBounds()));
        }
        return false;
    }

    /*
    	can i edit this object
    */
    WMEutils.prototype.canEdit = function(obj) {
        if (obj.isDeleted())
            return false;

        if (obj.type === 'segment')
            return obj.isAllowed(obj.PERMISSIONS.EDIT_GEOMETRY) && !obj.hasClosures(); // || obj.isUpdated();
        if (obj.type === 'venue')
            return obj.isAllowed(obj.PERMISSIONS.EDIT_GEOMETRY) && obj.areExternalProvidersEditable(); // || obj.isUpdated();
        if (obj.type === 'node')
            return !obj.isConnectedToBigJunction() && obj.areConnectionsEditable() &&
                obj.isAllowedToMoveNode() &&
                obj.isAllowed(obj.PERMISSIONS.DELETE); // obj.isUpdated();
    };

    /*
    	is this object in Portugal
    */
    WMEutils.prototype.isPortugal = function(obj) {
        var att = obj.attributes;
        var street = Waze.model.streets.get(att.primaryStreetID);
        var city = segment.model.cities.get(street.cityID);
        var countryId = city.countryID;

        return countryId === 181;
    }

    /*
    	return a random color
    */
    WMEutils.prototype.rColor = function() {
        var letters = '0123456789ABCDEF';
        var color = '#';
        for (var i = 0; i < 6; i++) {
            color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
    }

    /*
        obj = must be a segment OBJ
    */
    WMEutils.prototype.isDrivable = function(obj) {
        if (obj.type === 'segment') {
            var drivable = [1, 2, 3, 4, 6, 7, 8, 17, 15, 20];

            if (drivable.includes(obj.attributes.roadType)) {
                return true;
            }
        };
        return false;
    };

    /*
        obj = object to highlight, can be and segment or a place (landmark/venue)
        color = highlight color
        bgColor = background color, if null, defaults to color
    */
    WMEutils.prototype.highlightObject = function(obj, color, bgColor, label) {
        return new OpenLayers.Feature.Vector(obj.geometry.clone(), {}, {
            strokeColor: color,
            strokeDashstyle: "none",
            strokeLinecap: "round",
            strokeWidth: 15,
            strokeOpacity: 0.5,
            fill: true,
            fillColor: bgColor || color,
            fillOpacity: 0.2,
            pointRadius: 6,
            fontColor: color,
            labelOutlineColor: bgColor || 'black',
            labelOutlineWidth: 4,
            labelAlign: 'cm',
            label: label || null,
            rotation: 0.785398164,
            textAlign: 'center',
            textBaseline: 'middle'
        });
    };

    /*
    	options stuff
    */
    WMEutils.prototype.loadOptions = function() {
        var self = this;

        return JSON.parse(localStorage.getItem(self.uid + "_options"));
    }
    WMEutils.prototype.saveOptions = function(options) {
        var self = this;

        return localStorage.setItem(self.uid + "_options", JSON.stringify(options));
    }

    /*
    	log stuff
    */
    WMEutils.prototype.log = function(msg) {
        var self = this;

        if (!this.doLog)
            return;

        var now = Date.now();
        console.log("[" + this.app + "] " + now + " : " + msg);
    };

    /*
    	set attributes to objects
    */
    WMEutils.prototype.setAttributes = function(obj, attr) {
        var WazeActionUpdateObject = window.require("Waze/Action/UpdateObject");
        var WazeActionMultiAction = window.require("Waze/Action/MultiAction");

        var action = [];
        action.push(new WazeActionUpdateObject(obj, attr));
        Waze.model.actionManager.add(new WazeActionMultiAction(action));
    };

    /*
    	get normalized lock rank
    */
    WMEutils.prototype.getLockRank = function(obj) {
        var rank = obj.attributes.lockRank;

        // support for the automatic lock
        if (obj.attributes.rank > rank)
            rank = obj.attributes.rank;

        if (!rank) {
            rank = 1;
        } else {
            rank++;
        }
        return rank;
    };

    /*
    	get road name
    */
    WMEutils.prototype.getRoadName = function(obj) {
        var attr = obj.attributes;
        var segStreetID = attr.primaryStreetID;
        if (segStreetID !== null && segStreetID !== -100) {
            var street = Waze.model.streets.get(segStreetID);

            if (!street)
                return '';

            return street.name || '';
        };
    };

    /*
    	returns true if you are using beta editor
    */
    WMEutils.prototype.onBeta = function() {
        return -1 !== window.location.href.indexOf("beta");
    }

    /*
    	add menu layer

        section = [issues, places, road, display]
        name = layer name
        uid = internal id
        callback = function() {...}
        layer = OL Layer
    */
    WMEutils.prototype.addMenuLayer = function(o) {
        // from WME Street View Availability
        var roadGroupSelector = document.getElementById('layer-switcher-group_' + o.section);
        if (roadGroupSelector !== null) {
            var roadGroup = roadGroupSelector.parentNode.parentNode.querySelector('.children');
            var toggler = document.createElement('li');
            var togglerContainer = document.createElement('div');
            togglerContainer.className = 'controls-container toggler';
            var checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.id = 'layer-switcher-item_' + o.uid;
            checkbox.className = 'toggle';
            checkbox.checked = true;
            checkbox.addEventListener('click', function(e) {
                o.layer.setVisibility(e.target.checked);
            });
            togglerContainer.appendChild(checkbox);
            var label = document.createElement('label');
            label.htmlFor = checkbox.id;
            var labelText = document.createElement('span');
            labelText.className = 'label-text';
            labelText.appendChild(document.createTextNode(o.name));
            label.appendChild(labelText);
            togglerContainer.appendChild(label);
            toggler.appendChild(togglerContainer);
            roadGroup.appendChild(toggler);
        }
    };

    root.WMEutils = WMEutils;
})(window);
<|endoftext|>


<commit_before>define( function ( require ) {

  var guid = require( "common/guid" );
  var when = require( "../external/when" );

  var Complete = function( value ) {
    if( !(this instanceof Complete ) ) {
      return new Complete( value );
    }
    this.value = value;
  };

  var Continue = function( value ) {
    if( !(this instanceof Continue ) ) {
      return new Continue( value );
    }
    this.value = value;
  };

  var Wait = function( value ) {
    if( !(this instanceof Wait ) ) {
      return new Wait( value );
    }
    this.value = value;
  };

  // Task states
  var T_STARTED = 0,
      T_PAUSED = 1,
      T_CANCELLED = 2,
      T_CLOSED = 3;

  // Run states
  var R_RUNNING = 0,
      R_BLOCKED = 1,
      R_RESOLVED = 2,
      R_REJECTED = 3;

  var Task = function( scheduler, schedule, thunk ) {
    this.id = guid();
    this._thunk = thunk;
    this._taskState = T_PAUSED;
    this._runState = R_RESOLVED;
    this._scheduler = scheduler;
    this._schedule = schedule || undefined;
    this.result = undefined;
    this._deferred = when.defer();
    this.then = this._deferred.promise;
    this.when = when;
  };

  function start( schedule ) {
    this._schedule = schedule || this._schedule;
    if( this._taskState !== T_PAUSED ) {
      throw new Error( "task is already started or completed" );
    }
    this._taskState = T_STARTED;
    if( this._runState !== R_BLOCKED ) {
      this._scheduler.insert( this, this._schedule );
    }
    return this;
  };

  function pause() {
    if( this._runState !== R_BLOCKED ) {
      throw new Error( "task can only be paused while blocked" );
    }
    this._taskState = T_PAUSED;
    this._scheduler.remove( this );
    return this;
  };

  function cancel( schedule ) {
    this._schedule = schedule || undefined;
    if( this._taskState !== R_BLOCKED ) {
      throw new Error( "tasks can only be cancelled while blocked" );
    }
    this._taskState = T_CANCELLED;
    this._scheduler.insert( this, this._schedule );
    return this;
  };

  function isStarted() {
    return this._taskState === T_STARTED;
  };

  function isRunning() {
    return this._runState === R_RUNNING;
  };

  // TD: this will need to change for cooperative tasks
  function _run() {
    var result = this._result;
    this.result = undefined;
    try{
      this._runState = R_RUNNING;
      if( this._taskState === T_CANCELLED ) {
        this._runState = R_RESOLVED;
        this._taskState = T_CLOSED;
      } else if( this._taskState === T_STARTED ) {
        result = this._thunk.call( this );
        this._runState = R_BLOCKED;

        if( result instanceof Continue ) {
          this._runState = R_RESOLVED;
          this.result = Continue.value;
          if( this._threadState === T_STARTED ) {
            this._scheduler.insert( this, this._schedule );
          }
        } else if( result instanceof Wait ) {
          this._runState = R_BLOCKED;
        } else if( result instanceof Complete ) {
          this._runState = R_RESOLVED;
          this._taskState = R_CLOSED;
        } else {

        }
      }
    } catch( exception ) {

    }
  };

  function toString() {
    return "[object PreemptiveTask " + this.id + " ]";
  };

  Task.prototype = {
    pause: pause,
    start: start,
    cancel: cancel,
    isStarted: isStarted,
    isRunning: isRunning,
    _run: _run
  };

} );<commit_msg>Task run implementation (incomplete).<commit_after>define( function ( require ) {

  var guid = require( "common/guid" );
  var when = require( "../external/when" );

  var Complete = function( value ) {
    if( !(this instanceof Complete ) ) {
      return new Complete( value );
    }
    this.value = value;
  };

  // Task states
  var T_STARTED = 0,
      T_PAUSED = 1,
      T_CANCELLED = 2,
      T_CLOSED = 3;

  // Run states
  var R_RUNNING = 0,
      R_BLOCKED = 1,
      R_RESOLVED = 2,
      R_REJECTED = 3;

  var Task = function( scheduler, schedule, thunk ) {
    this.id = guid();
    this._thunk = thunk;
    this._taskState = T_PAUSED;
    this._runState = R_RESOLVED;
    this._scheduler = scheduler;
    this._schedule = schedule || undefined;
    this.result = undefined;
    this._deferred = when.defer();
    this.then = this._deferred.promise;
    this.when = when;
  };

  function start( schedule ) {
    this._schedule = schedule || this._schedule;
    if( this._taskState !== T_PAUSED ) {
      throw new Error( "task is already started or completed" );
    }
    this._taskState = T_STARTED;
    if( this._runState !== R_BLOCKED ) {
      this._scheduler.insert( this, this._schedule );
    }
    return this;
  };

  function pause() {
    if( this._runState !== R_BLOCKED ) {
      throw new Error( "task can only be paused while blocked" );
    }
    this._taskState = T_PAUSED;
    this._scheduler.remove( this );
    return this;
  };

  function cancel( schedule ) {
    this._schedule = schedule || undefined;
    if( this._taskState !== R_BLOCKED ) {
      throw new Error( "tasks can only be cancelled while blocked" );
    }
    this._taskState = T_CANCELLED;
    this._scheduler.insert( this, this._schedule );
    return this;
  };

  function isStarted() {
    return this._taskState === T_STARTED;
  };

  function isRunning() {
    return this._runState === R_RUNNING;
  };

  // TD: this will need to change for cooperative tasks
  function _run() {
    var result = this._result;
    this.result = undefined;
    try{
      this._runState = R_RUNNING;
      if( this._taskState === T_CANCELLED ) {
        this._runState = R_RESOLVED;
        this._taskState = T_CLOSED;
      } else if( this._taskState === T_STARTED ) {
        result = this._thunk.call( this );
        this._runState = R_BLOCKED;

        if( when.isPromise( result ) ) {

        } else if( result instanceof Complete ) {

        }

        if( result instanceof Continue ) {
          this._runState = R_RESOLVED;
          this.result = Continue.value;
          if( this._threadState === T_STARTED ) {
            this._scheduler.insert( this, this._schedule );
          }
        } else if( result instanceof Wait ) {
          this._runState = R_BLOCKED;
        } else if( result instanceof Complete ) {
          this._runState = R_RESOLVED;
          this._taskState = R_CLOSED;
        } else {

        }
      }
    } catch( exception ) {

    }
  };

  function toString() {
    return "[object PreemptiveTask " + this.id + " ]";
  };

  Task.prototype = {
    pause: pause,
    start: start,
    cancel: cancel,
    isStarted: isStarted,
    isRunning: isRunning,
    _run: _run
  };

} );<|endoftext|>