<commit_before>/**
 * AngularJS directive for responsive images and image maps
 *
 * @author Hein Bekker <hein@netbek.co.za>
 * @copyright (c) 2015 Hein Bekker
 * @license http://www.gnu.org/licenses/agpl-3.0.txt AGPLv3
 */

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

	angular
		.module('nb.picture')
		.controller('nbPictureMapController', nbPictureMapController);

	nbPictureMapController.$inject = ['$scope', '$element', '$attrs', '$timeout', 'nbI18N', 'nbPictureConfig', 'picturefill', '_', 'nbPictureService', 'PICTURE_SHAPE'];
	function nbPictureMapController ($scope, $element, $attrs, $timeout, nbI18N, nbPictureConfig, picturefill, _, nbPictureService, PICTURE_SHAPE) {
		/*jshint validthis: true */
		var pictureId;
		var flags = {
			init: false, // {Boolean} Whether init() has been fired.
			touch: false // {Boolean} Whether the device supports touch events.
		};
		var timeouts = [];
		var $img, img;

		$scope.complete = false; // {Boolean} Whether the image has loaded or failed to load.
//		$scope.map = nbPictureService.getMap(); // {Object}

		/**
		 *
		 * @param {Event} event
		 */
		$scope.clickArea = function (event) {
			var locationHref = window.location.href;
			var aHref = event.target.href;

			if (aHref.indexOf(locationHref) === 0) {
				aHref = aHref.slice(locationHref.length);
			}

			// If default href, then stop event.
			if (aHref === '#') {
				event.preventDefault();
			}

			$scope.$broadcast('nbPicture:clickArea', event);
		};

		/**
		 *
		 * @param {Event} event
		 * @param {Boolean} blur
		 */
		$scope.focusArea = function (event, blur) {
			$scope.$broadcast('nbPicture:focusArea', event, blur);
		};

		/**
		 *
		 * @param {Event} event
		 * @param {Boolean} blur
		 */
		$scope.hoverArea = function (event, blur) {
			$scope.$broadcast('nbPicture:hoverArea', event, blur);
		};

		/**
		 * Returns width of image.
		 *
		 * @returns {Number}
		 */
		$scope.width = function () {
			return $scope.complete && img ? img.scrollWidth : 0;
		};

		/**
		 * Returns height of image.
		 *
		 * @returns {Number}
		 */
		$scope.height = function () {
			return $scope.complete && img ? img.scrollHeight : 0;
		};

		/**
		 *
		 *
		 * @param {Scope} scope
		 * @returns {Object}
		 */
		this.attrs = function watchAttrs (scope) {
			return {
				defaultSource: $attrs.defaultSource,
				sources: $attrs.sources,
				alt: $attrs.alt,
				map: $attrs.map
			};
		};

		/**
		 *
		 */
		this.init = function () {
			if (flags.init) {
				return;
			}

			flags.init = true;

			pictureId = nbPictureService.initPicture();

			$img = $element.find('img');
			img = $img[0];
		};

		/**
		 *
		 */
		this.destroy = function () {
			_.forEach(timeouts, function (fn) {
				$timeout.cancel(fn);
			});

			removeWindowEventListeners();

			if ($img) {
				removeImgEventListeners();
			}

			nbPictureService.destroyPicture(pictureId);
		};

		/**
		 *
		 *
		 * @param {Object} options
		 */
		this.update = function (options) {
			if (!flags.init) {
				return;
			}

			_.forEach(timeouts, function (fn) {
				$timeout.cancel(fn);
			});

			removeWindowEventListeners();

			if ($img) {
				removeImgEventListeners();
			}

			// Reset state.
			$scope.complete = false;

			// Add image event handlers.
			addImgEventListeners();

			options.map = $scope.$eval(options.map);
			nbPictureService.setMap(pictureId, options);

			options.sources = $scope.$eval(options.sources);
			nbPictureService.setPicture(pictureId, options);

			// Assign data to scope.
			$scope.map = nbPictureService.getMap(pictureId);
			$scope.picture = nbPictureService.getPicture(pictureId);

			timeouts.push($timeout(function () {
				// Run picture polyfill.
				picturefill($element);

				// Add window event handlers.
				addWindowEventListeners();
			}));
		};

		/**
		 * Checks if a given image has loaded.
		 *
		 * @param {DOM element} img
		 * @returns {Boolean}
		 */
		function isImgComplete (img) {
			var readyState = img.readyState;
			if ((img.src || img.srcset) && (img.complete || readyState == 'complete' || readyState == 'loaded' || readyState == 4)) {
				return true;
			}
			return false;
		}

		/**
		 * Callback fired after `error` event.
		 *
		 * @param {Event} event
		 */
		function onImgError (event) {
			if (img.src || img.srcset) {
				$scope.complete = true;

				removeImgEventListeners();

				$scope.$broadcast('nbPicture:baseError');
			}
		}

		/**
		 * Callback fired after `load` and `readystatechange` events.
		 *
		 * @param {Event} event
		 */
		function onImgLoad (event) {
			if (isImgComplete(img)) {
				$scope.complete = true;

				removeImgEventListeners();

				nbPictureService.resizeMap(pictureId, $scope.width(), $scope.height(), true);

				$scope.$broadcast('nbPicture:baseLoad');

				$scope.$apply();
			}
		}

		/**
		 * Adds image event handlers.
		 */
		function addImgEventListeners () {
			$img.on('error', onImgError);
			$img.on('load', onImgLoad);
			$img.on('readystatechange', onImgLoad);
		}

		/**
		 * Removes image event handlers.
		 */
		function removeImgEventListeners () {
			$img.off('error', onImgError);
			$img.off('load', onImgLoad);
			$img.off('readystatechange', onImgLoad);
		}

		/**
		 * Callback fired after window `resize` event.
		 *
		 * @param {Event} event
		 */
		function onWindowResize (event) {
			nbPictureService.resizeMap(pictureId, $scope.width(), $scope.height(), true);

			$scope.$broadcast('nbPicture:resize');

			$scope.$apply();
		}

		/**
		 * Adds window event handlers.
		 */
		function addWindowEventListeners () {
			if (window.addEventListener) {
				window.addEventListener('resize', onWindowResize, false);
			}
			else if (window.attachEvent) {
				window.attachEvent('onresize', onWindowResize);
			}
		}

		/**
		 * Removes window event handlers.
		 */
		function removeWindowEventListeners () {
			if (window.removeEventListener) {
				window.removeEventListener('resize', onWindowResize, false);
			}
			else if (window.detachEvent) {
				window.detachEvent('onresize', onWindowResize);
			}
		}
	}
})(window, window.angular);<commit_msg>Remove old code<commit_after>/**
 * AngularJS directive for responsive images and image maps
 *
 * @author Hein Bekker <hein@netbek.co.za>
 * @copyright (c) 2015 Hein Bekker
 * @license http://www.gnu.org/licenses/agpl-3.0.txt AGPLv3
 */

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

	angular
		.module('nb.picture')
		.controller('nbPictureMapController', nbPictureMapController);

	nbPictureMapController.$inject = ['$scope', '$element', '$attrs', '$timeout', 'nbI18N', 'nbPictureConfig', 'picturefill', '_', 'nbPictureService', 'PICTURE_SHAPE'];
	function nbPictureMapController ($scope, $element, $attrs, $timeout, nbI18N, nbPictureConfig, picturefill, _, nbPictureService, PICTURE_SHAPE) {
		/*jshint validthis: true */
		var pictureId;
		var flags = {
			init: false, // {Boolean} Whether init() has been fired.
			touch: false // {Boolean} Whether the device supports touch events.
		};
		var timeouts = [];
		var $img, img;

		$scope.complete = false; // {Boolean} Whether the image has loaded or failed to load.

		/**
		 *
		 * @param {Event} event
		 */
		$scope.clickArea = function (event) {
			var locationHref = window.location.href;
			var aHref = event.target.href;

			if (aHref.indexOf(locationHref) === 0) {
				aHref = aHref.slice(locationHref.length);
			}

			// If default href, then stop event.
			if (aHref === '#') {
				event.preventDefault();
			}

			$scope.$broadcast('nbPicture:clickArea', event);
		};

		/**
		 *
		 * @param {Event} event
		 * @param {Boolean} blur
		 */
		$scope.focusArea = function (event, blur) {
			$scope.$broadcast('nbPicture:focusArea', event, blur);
		};

		/**
		 *
		 * @param {Event} event
		 * @param {Boolean} blur
		 */
		$scope.hoverArea = function (event, blur) {
			$scope.$broadcast('nbPicture:hoverArea', event, blur);
		};

		/**
		 * Returns width of image.
		 *
		 * @returns {Number}
		 */
		$scope.width = function () {
			return $scope.complete && img ? img.scrollWidth : 0;
		};

		/**
		 * Returns height of image.
		 *
		 * @returns {Number}
		 */
		$scope.height = function () {
			return $scope.complete && img ? img.scrollHeight : 0;
		};

		/**
		 *
		 *
		 * @param {Scope} scope
		 * @returns {Object}
		 */
		this.attrs = function watchAttrs (scope) {
			return {
				defaultSource: $attrs.defaultSource,
				sources: $attrs.sources,
				alt: $attrs.alt,
				map: $attrs.map
			};
		};

		/**
		 *
		 */
		this.init = function () {
			if (flags.init) {
				return;
			}

			flags.init = true;

			pictureId = nbPictureService.initPicture();

			$img = $element.find('img');
			img = $img[0];
		};

		/**
		 *
		 */
		this.destroy = function () {
			_.forEach(timeouts, function (fn) {
				$timeout.cancel(fn);
			});

			removeWindowEventListeners();

			if ($img) {
				removeImgEventListeners();
			}

			nbPictureService.destroyPicture(pictureId);
		};

		/**
		 *
		 *
		 * @param {Object} options
		 */
		this.update = function (options) {
			if (!flags.init) {
				return;
			}

			_.forEach(timeouts, function (fn) {
				$timeout.cancel(fn);
			});

			removeWindowEventListeners();

			if ($img) {
				removeImgEventListeners();
			}

			// Reset state.
			$scope.complete = false;

			// Add image event handlers.
			addImgEventListeners();

			options.map = $scope.$eval(options.map);
			nbPictureService.setMap(pictureId, options);

			options.sources = $scope.$eval(options.sources);
			nbPictureService.setPicture(pictureId, options);

			// Assign data to scope.
			$scope.map = nbPictureService.getMap(pictureId);
			$scope.picture = nbPictureService.getPicture(pictureId);

			timeouts.push($timeout(function () {
				// Run picture polyfill.
				picturefill($element);

				// Add window event handlers.
				addWindowEventListeners();
			}));
		};

		/**
		 * Checks if a given image has loaded.
		 *
		 * @param {DOM element} img
		 * @returns {Boolean}
		 */
		function isImgComplete (img) {
			var readyState = img.readyState;
			if ((img.src || img.srcset) && (img.complete || readyState == 'complete' || readyState == 'loaded' || readyState == 4)) {
				return true;
			}
			return false;
		}

		/**
		 * Callback fired after `error` event.
		 *
		 * @param {Event} event
		 */
		function onImgError (event) {
			if (img.src || img.srcset) {
				$scope.complete = true;

				removeImgEventListeners();

				$scope.$broadcast('nbPicture:baseError');
			}
		}

		/**
		 * Callback fired after `load` and `readystatechange` events.
		 *
		 * @param {Event} event
		 */
		function onImgLoad (event) {
			if (isImgComplete(img)) {
				$scope.complete = true;

				removeImgEventListeners();

				nbPictureService.resizeMap(pictureId, $scope.width(), $scope.height(), true);

				$scope.$broadcast('nbPicture:baseLoad');

				$scope.$apply();
			}
		}

		/**
		 * Adds image event handlers.
		 */
		function addImgEventListeners () {
			$img.on('error', onImgError);
			$img.on('load', onImgLoad);
			$img.on('readystatechange', onImgLoad);
		}

		/**
		 * Removes image event handlers.
		 */
		function removeImgEventListeners () {
			$img.off('error', onImgError);
			$img.off('load', onImgLoad);
			$img.off('readystatechange', onImgLoad);
		}

		/**
		 * Callback fired after window `resize` event.
		 *
		 * @param {Event} event
		 */
		function onWindowResize (event) {
			nbPictureService.resizeMap(pictureId, $scope.width(), $scope.height(), true);

			$scope.$broadcast('nbPicture:resize');

			$scope.$apply();
		}

		/**
		 * Adds window event handlers.
		 */
		function addWindowEventListeners () {
			if (window.addEventListener) {
				window.addEventListener('resize', onWindowResize, false);
			}
			else if (window.attachEvent) {
				window.attachEvent('onresize', onWindowResize);
			}
		}

		/**
		 * Removes window event handlers.
		 */
		function removeWindowEventListeners () {
			if (window.removeEventListener) {
				window.removeEventListener('resize', onWindowResize, false);
			}
			else if (window.detachEvent) {
				window.detachEvent('onresize', onWindowResize);
			}
		}
	}
})(window, window.angular);<|endoftext|>


<commit_before>import PluginSDK from 'PluginSDK';
import {
  REQUEST_TASK_DIRECTORY_ERROR,
  REQUEST_TASK_DIRECTORY_SUCCESS,
  SERVER_ACTION
} from '../constants/ActionTypes';
import {
  TASK_DIRECTORY_CHANGE,
  TASK_DIRECTORY_ERROR
} from '../constants/EventTypes';
import AppDispatcher from '../events/AppDispatcher';
import Config from '../config/Config';
import GetSetBaseStore from './GetSetBaseStore';
import MesosStateStore from '../stores/MesosStateStore';
import TaskDirectory from '../structs/TaskDirectory';
import TaskDirectoryActions from '../events/TaskDirectoryActions';

var requestInterval = null;
var activeXHR = null;

function fetchState(task, innerPath) {
  let node = MesosStateStore.getNodeFromID(task.slave_id);
  activeXHR = TaskDirectoryActions.fetchNodeState(
    task,
    node,
    function (response) {
      activeXHR = TaskDirectoryActions
        .fetchDirectory(task, innerPath, response);
    }
  );
}

function startPolling(task, innerPath) {
  if (requestInterval == null) {
    fetchState(task, innerPath);

    requestInterval = setInterval(
      fetchState.bind(this, task, innerPath), Config.getRefreshRate()
    );
  }
}

class TaskDirectoryStore extends GetSetBaseStore {
  constructor() {
    super(...arguments);

    this.getSet_data = {
      directory: null,
      innerPath: ''
    };

    PluginSDK.addStoreConfig({
      store: this,
      storeID: this.storeID,
      events: {
        success: TASK_DIRECTORY_CHANGE,
        error: TASK_DIRECTORY_ERROR
      },
      unmountWhen() {
        return true;
      },
      listenAlways: true
    });

    this.dispatcherIndex = AppDispatcher.register((payload) => {
      if (payload.source !== SERVER_ACTION) {
        return false;
      }

      let {data, innerPath, taskID, type} = payload.action;
      switch (type) {
        case REQUEST_TASK_DIRECTORY_SUCCESS:
          this.processStateSuccess(data, innerPath, taskID);
          break;
        case REQUEST_TASK_DIRECTORY_ERROR:
          this.processStateError(taskID);
          break;
      }

      return true;
    });

  }

  addChangeListener(eventName, callback) {
    this.on(eventName, callback);
  }

  removeChangeListener(eventName, callback) {
    this.removeListener(eventName, callback);

    if (this.listeners(TASK_DIRECTORY_CHANGE).length === 0) {
      this.resetRequests();
      this.set({innerPath: '', directory: null});
    }
  }

  resetRequests() {
    if (requestInterval != null) {
      clearInterval(requestInterval);
      requestInterval = null;
    }

    if (activeXHR != null) {
      activeXHR.abort();
      activeXHR = null;
    }
  }

  // Default innerPath to empty string so it matches with default innerPath
  fetchDirectory(task, innerPath = '') {
    this.resetRequests();
    this.set({directory: null});
    // Make sure to update innerPath if different before fetching
    if (this.get('innerPath') !== innerPath) {
      this.set({innerPath: innerPath});
    }

    this.emit(TASK_DIRECTORY_CHANGE, task.id);
    startPolling(task, innerPath);
  }

  addPath(task, path) {
    this.set({innerPath: this.get('innerPath') + '/' + path});
    this.fetchDirectory(task, this.get('innerPath'));
  }

  setPath(task, path) {
    this.set({innerPath: path});
    this.fetchDirectory(task, path);
  }

  processStateError(taskID) {
    this.emit(TASK_DIRECTORY_ERROR, taskID);
  }

  processStateSuccess(items, innerPath, taskID) {
    // Only update when receiving response from what was requested
    if (this.get('innerPath') === innerPath) {
      this.set({directory: new TaskDirectory({items})});
      this.emit(TASK_DIRECTORY_CHANGE, taskID);
    }
  }

  get storeID() {
    return 'taskDirectory';
  }

}

module.exports = new TaskDirectoryStore();
<commit_msg>Fix linting.<commit_after>import PluginSDK from 'PluginSDK';
import {
  REQUEST_TASK_DIRECTORY_ERROR,
  REQUEST_TASK_DIRECTORY_SUCCESS,
  SERVER_ACTION
} from '../constants/ActionTypes';
import {
  TASK_DIRECTORY_CHANGE,
  TASK_DIRECTORY_ERROR
} from '../constants/EventTypes';
import AppDispatcher from '../events/AppDispatcher';
import Config from '../config/Config';
import GetSetBaseStore from './GetSetBaseStore';
import MesosStateStore from '../stores/MesosStateStore';
import TaskDirectory from '../structs/TaskDirectory';
import TaskDirectoryActions from '../events/TaskDirectoryActions';

var requestInterval = null;
var activeXHR = null;

function fetchState(task, innerPath) {
  let node = MesosStateStore.getNodeFromID(task.slave_id);
  activeXHR = TaskDirectoryActions.fetchNodeState(
    task,
    node,
    function (response) {
      activeXHR = TaskDirectoryActions
        .fetchDirectory(task, innerPath, response);
    }
  );
}

function startPolling(task, innerPath) {
  if (requestInterval == null) {
    fetchState(task, innerPath);

    requestInterval = setInterval(
      fetchState.bind(this, task, innerPath), Config.getRefreshRate()
    );
  }
}

class TaskDirectoryStore extends GetSetBaseStore {
  constructor() {
    super(...arguments);

    this.getSet_data = {
      directory: null,
      innerPath: ''
    };

    PluginSDK.addStoreConfig({
      store: this,
      storeID: this.storeID,
      events: {
        success: TASK_DIRECTORY_CHANGE,
        error: TASK_DIRECTORY_ERROR
      },
      unmountWhen() {
        return true;
      },
      listenAlways: true
    });

    this.dispatcherIndex = AppDispatcher.register((payload) => {
      if (payload.source !== SERVER_ACTION) {
        return false;
      }

      let {data, innerPath, taskID, type} = payload.action;
      switch (type) {
        case REQUEST_TASK_DIRECTORY_SUCCESS:
          this.processStateSuccess(data, innerPath, taskID);
          break;
        case REQUEST_TASK_DIRECTORY_ERROR:
          this.processStateError(taskID);
          break;
      }

      return true;
    });

  }

  addChangeListener(eventName, callback) {
    this.on(eventName, callback);
  }

  removeChangeListener(eventName, callback) {
    this.removeListener(eventName, callback);

    if (this.listeners(TASK_DIRECTORY_CHANGE).length === 0) {
      this.resetRequests();
      this.set({innerPath: '', directory: null});
    }
  }

  resetRequests() {
    if (requestInterval != null) {
      clearInterval(requestInterval);
      requestInterval = null;
    }

    if (activeXHR != null) {
      activeXHR.abort();
      activeXHR = null;
    }
  }

  // Default innerPath to empty string so it matches with default innerPath
  fetchDirectory(task, innerPath = '') {
    this.resetRequests();
    this.set({directory: null});
    // Make sure to update innerPath if different before fetching
    if (this.get('innerPath') !== innerPath) {
      this.set({innerPath});
    }

    this.emit(TASK_DIRECTORY_CHANGE, task.id);
    startPolling(task, innerPath);
  }

  addPath(task, path) {
    this.set({innerPath: this.get('innerPath') + '/' + path});
    this.fetchDirectory(task, this.get('innerPath'));
  }

  setPath(task, path) {
    this.set({innerPath: path});
    this.fetchDirectory(task, path);
  }

  processStateError(taskID) {
    this.emit(TASK_DIRECTORY_ERROR, taskID);
  }

  processStateSuccess(items, innerPath, taskID) {
    // Only update when receiving response from what was requested
    if (this.get('innerPath') === innerPath) {
      this.set({directory: new TaskDirectory({items})});
      this.emit(TASK_DIRECTORY_CHANGE, taskID);
    }
  }

  get storeID() {
    return 'taskDirectory';
  }

}

module.exports = new TaskDirectoryStore();
<|endoftext|>


<commit_before>define([
  'summernote/base/core/agent',
  'summernote/base/core/dom',
  'summernote/base/core/func',
  'summernote/base/core/list',
  'summernote/base/core/range'
], function (agent, dom, func, list, range) {
  var AirPopover = function (context) {
    var self = this;

    var $document = $(document);
    var $editable = context.layoutInfo.editable;
    var editable = $editable[0];

    var options = context.options;

    var innerMouseUp;

    this.events = {
      'summernote.keyup summernote.mouseup summernote.scroll': function () {
        innerMouseUp = true;
        self.update();
      },
      'summernote.change summernote.dialog.shown': function () {
        self.update();
      },
      'summernote.focusout': function (we, e) {
        // [workaround] Firefox doesn't support relatedTarget on focusout
        //  - Ignore hide action on focus out in FF.
        if (agent.isFF) {
          return;
        }

        if (!e.relatedTarget) {
          self.hide();
        }

        self.lastRange = range.createFromSelection();
      }
    };

    $editable.on('mousedown', function () {
      $document.on('mouseup', function () {
        if (!innerMouseUp) {
          self.update();
        }

        innerMouseUp = false;
        $document.off('mouseup');
      });
    });

    this.shouldInitialize = function () {
      return options.airMode &&
        options.popover &&
        options.popover.air &&
        typeof options.popover.air.hide === 'function' &&
        typeof options.popover.air.update === 'function';
    };

    this.initialize = function () {
      this.fontInstalledMap = {};
    };

    this.destroy = function () {
      delete this.fontInstalledMap;
    };

    this.isFontInstalled = function (name) {
      if (!self.fontInstalledMap.hasOwnProperty(name)) {
        self.fontInstalledMap[name] = agent.isFontInstalled(name) ||
          list.contains(options.fontNamesIgnoreCheck, name);
      }

      return self.fontInstalledMap[name];
    };

    this.getAvailablesFont = function () {
      return options.fontNames.filter(self.isFontInstalled);
    };

    this.getLastRange = function () {
      return self.lastRange;
    };

    this.insertNode = function (node, rng, forceInline) {
      if (!$editable.is(':focus')) {
        $editable.focus();
      }
      rng = rng || self.lastRange || range.create(editable);
      var info = dom.splitPoint(rng.getStartPoint(), forceInline || dom.isInline(node));

      if (info.rightNode) {
        info.rightNode.parentNode.insertBefore(node, info.rightNode);
      } else {
        info.container.appendChild(node);
      }

      self.lastRange = range.createFromNodeAfter(node);
      self.lastRange.select();
    };

    this.moveCursorToEnd = function () {
      if (editable.lastChild || editable.lastElementChild) {
        range.createFromNodeAfter(editable.lastChild || editable.lastElementChild).select();
      }
    };

    this.update = function (force) {
      var styleInfo = context.invoke('editor.currentStyle');
      if (styleInfo.range && (!styleInfo.range.isCollapsed() || force)) {
        var rect = list.last(styleInfo.range.getClientRects());
        var bnd;
        if (rect) {
          bnd = func.rect2bnd(rect);
          options.popover.air.update(styleInfo, bnd);
        } else if (force) {
          options.popover.air.update(styleInfo, null);
        }
      } else {
        this.hide();
      }
    };

    this.hide = function () {
      options.popover.air.hide();
    };
  };

  return AirPopover;
});
<commit_msg>feat(airPopover): Add pasteHTML<commit_after>define([
  'summernote/base/core/agent',
  'summernote/base/core/dom',
  'summernote/base/core/func',
  'summernote/base/core/list',
  'summernote/base/core/range'
], function (agent, dom, func, list, range) {
  var AirPopover = function (context) {
    var self = this;

    var $document = $(document);
    var $editable = context.layoutInfo.editable;
    var editable = $editable[0];

    var options = context.options;

    var innerMouseUp;

    this.events = {
      'summernote.keyup summernote.mouseup summernote.scroll': function () {
        innerMouseUp = true;
        self.update();
      },
      'summernote.change summernote.dialog.shown': function () {
        self.update();
      },
      'summernote.focusout': function (we, e) {
        // [workaround] Firefox doesn't support relatedTarget on focusout
        //  - Ignore hide action on focus out in FF.
        if (agent.isFF) {
          return;
        }

        if (!e.relatedTarget) {
          self.hide();
        }

        self.lastRange = range.createFromSelection();
      }
    };

    $editable.on('mousedown', function () {
      $document.on('mouseup', function () {
        if (!innerMouseUp) {
          self.update();
        }

        innerMouseUp = false;
        $document.off('mouseup');
      });
    });

    this.shouldInitialize = function () {
      return options.airMode &&
        options.popover &&
        options.popover.air &&
        typeof options.popover.air.hide === 'function' &&
        typeof options.popover.air.update === 'function';
    };

    this.initialize = function () {
      this.fontInstalledMap = {};
    };

    this.destroy = function () {
      delete this.fontInstalledMap;
    };

    this.isFontInstalled = function (name) {
      if (!self.fontInstalledMap.hasOwnProperty(name)) {
        self.fontInstalledMap[name] = agent.isFontInstalled(name) ||
          list.contains(options.fontNamesIgnoreCheck, name);
      }

      return self.fontInstalledMap[name];
    };

    this.getAvailablesFont = function () {
      return options.fontNames.filter(self.isFontInstalled);
    };

    this.getLastRange = function () {
      return self.lastRange;
    };

    this.insertNode = function (node, rng, forceInline) {
      if (!$editable.is(':focus')) {
        $editable.focus();
      }
      rng = rng || self.lastRange || range.create(editable);
      var info = dom.splitPoint(rng.getStartPoint(), forceInline || dom.isInline(node));

      if (info.rightNode) {
        info.rightNode.parentNode.insertBefore(node, info.rightNode);
      } else {
        info.container.appendChild(node);
      }

      self.lastRange = range.createFromNodeAfter(node);
      self.lastRange.select();
    };

    this.moveCursorToEnd = function () {
      if (editable.lastChild || editable.lastElementChild) {
        range.createFromNodeAfter(editable.lastChild || editable.lastElementChild).select();
      }
    };

    this.pasteHTML = function (markup, rng) {
      if (!$editable.is(':focus')) {
        $editable.focus();
      }
      rng = rng || self.lastRange || range.create(editable);
      var info = dom.splitPoint(rng.getStartPoint(), false);

      var contentsContainer = $('

').html(markup)[0];
      var childNodes = list.from(contentsContainer.childNodes);

      var contents = childNodes.map(function (childNode) {
        if (info.rightNode) {
          info.rightNode.parentNode.insertBefore(childNode, info.rightNode);
        } else {
          info.container.appendChild(childNode);
        }
        return childNode;
      });

      self.lastRange = range.createFromNodeAfter(list.last(contents));
      self.lastRange.select();
    };

    this.update = function (force) {
      var styleInfo = context.invoke('editor.currentStyle');
      if (styleInfo.range && (!styleInfo.range.isCollapsed() || force)) {
        var rect = list.last(styleInfo.range.getClientRects());
        var bnd;
        if (rect) {
          bnd = func.rect2bnd(rect);
          options.popover.air.update(styleInfo, bnd);
        } else if (force) {
          options.popover.air.update(styleInfo, null);
        }
      } else {
        this.hide();
      }
    };

    this.hide = function () {
      options.popover.air.hide();
    };
  };

  return AirPopover;
});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Image,
  TextInput,
  View,
  TouchableOpacity,
  TouchableHighlight
} from 'react-native';
import { Container, Header, Title, Content, Card, CardItem, Left, Right, Thumbnail, Body, Text, Button, Icon } from 'native-base';
import MainDrawer from './components/Drawer';
import ResponsiveImage from 'react-native-responsive-image';
import { StackNavigator } from 'react-navigation';

export default class ReactNativeProject extends Component {

    static navigationOptions = {
        title: 'අන්තර්ජාල නැබ',
    };

    render() {
        const {navigate} = this.props.navigation;
        return (
          <Container>
              {/*<Header>
                  <Left>
                      <Button transparent onPress={()=> console.log(MainDrawer)}>
                          <Icon name='menu' />
                      </Button>
                  </Left>
                  <Body>
                      <Title>අන්තර්ජාල නැබ</Title>
                  </Body>
                  <Right />
              </Header>*/}

              <Content>

                <View style={[styles.layout]}>
                    <TouchableHighlight onPress={() => navigate('Detail', { title: 'පුවත් පත්' })}>
                        <View style={styles.box} >
                            <ResponsiveImage source={require('./img/news-papers.png')} initWidth="138" initHeight="138"/>
                        </View>
                    </TouchableHighlight>
                    <View style={styles.box} >
                        <ResponsiveImage source={require('./img/unknown.png')} initWidth="138" initHeight="138"/>
                    </View>
                </View>

                <View style={[styles.layout]}>
                    <View style={styles.box} >
                        <ResponsiveImage source={require('./img/unknown.png')} initWidth="138" initHeight="138"/>
                    </View>
                    <View style={styles.box} >
                        <ResponsiveImage source={require('./img/unknown.png')} initWidth="138" initHeight="138"/>
                    </View>
                </View>
              </Content>
          </Container>
        );

    }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  layout: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center'
  },
  box: {
    padding: 20,
    backgroundColor: 'rgba(0,0,0,0.05)',
    margin: 10,
  },
})
<commit_msg>code improvement<commit_after>import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Image,
  TextInput,
  View,
  TouchableOpacity,
  TouchableHighlight
} from 'react-native';
import { Container, Header, Title, Content, Card, CardItem, Left, Right, Thumbnail, Body, Text, Button, Icon } from 'native-base';
import MainDrawer from './components/Drawer';
import ResponsiveImage from 'react-native-responsive-image';
import { StackNavigator } from 'react-navigation';

export default class ReactNativeProject extends Component {

    static navigationOptions = {
        title: 'අන්තර්ජාල නැබ',
    };

    render() {
        const {navigate} = this.props.navigation;
        return (
          <Container>
              <Content>

                <View style={[styles.layout]}>
                    <TouchableHighlight onPress={() => navigate('Detail', { title: 'පුවත් පත්' })}>
                        <View style={styles.box} >
                            <ResponsiveImage source={require('./img/news-papers.png')} initWidth="138" initHeight="138"/>
                        </View>
                    </TouchableHighlight>
                    <View style={styles.box} >
                        <ResponsiveImage source={require('./img/unknown.png')} initWidth="138" initHeight="138"/>
                    </View>
                </View>

                <View style={[styles.layout]}>
                    <View style={styles.box} >
                        <ResponsiveImage source={require('./img/unknown.png')} initWidth="138" initHeight="138"/>
                    </View>
                    <View style={styles.box} >
                        <ResponsiveImage source={require('./img/unknown.png')} initWidth="138" initHeight="138"/>
                    </View>
                </View>
              </Content>
          </Container>
        );

    }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  layout: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center'
  },
  box: {
    padding: 20,
    backgroundColor: 'rgba(0,0,0,0.05)',
    margin: 10,
  },
})
<|endoftext|>


<commit_before>/* @flow */

import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Alert, Button } from 'react-native';

export default class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      currentPlayer: 'X',
      box1: '',
      box2: '',
      box3: '',
      box4: '',
      box5: '',
      box6: '',
      box7: '',
      box8: '',
      box9: '',
    }

  }

  render() {
    const tapped = (i, event) => {
      if (this.state.currentPlayer === 'X') {
        this.setState({ [`box${i}`]: 'X', currentPlayer: 'O' })
      } else {
        this.setState({ [`box${i}`]: 'O', currentPlayer: 'X' })
      }
    }
    const reset = () => {
      for (let i = 1; i <= 9; i++) {
        this.setState({ [`box${i}`]: '', currentPlayer: 'X' });
      }
      Alert.alert('Board has been reset');
    }
    const createBoard = () => {
      const board = [];
      for (let i = 1; i <= 9; i++) {
        board.push(<TouchableOpacity key={i} style={styles.box} onPress={tapped.bind(this, i)}><Text style={styles.value}>{this.state[`box${i}`]}</Text></TouchableOpacity>)
      }
      return board;
    }
    return (
      <View>
        <View style={styles.container}>
          {createBoard()}
          <Button title="Reset" onPress={reset} />
          <View>
            <Text>Player {this.state.currentPlayer}'s Turn</Text>
          </View>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    marginTop: '50%',
    height: '100%',
    width: '100%',
    flexDirection: 'row',
    flexWrap: 'wrap',
    flexBasis: '30%',
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  box: {
    display: 'inline-block',
    flexGrow: 1,
    height: '50%',
    width: '33%',
    borderStyle: 'solid',
    borderWidth: 3,
    justifyContent: 'center',
    alignItems: 'center',
  },
  value: {
    justifyContent: 'center',
    alignSelf: 'center',
    alignItems: 'center',
    fontWeight: '900',
  },
});
<commit_msg>:bug: Quick text fix<commit_after>/* @flow */

import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Alert, Button } from 'react-native';

export default class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      currentPlayer: 'X',
      box1: '',
      box2: '',
      box3: '',
      box4: '',
      box5: '',
      box6: '',
      box7: '',
      box8: '',
      box9: '',
    }

  }

  render() {
    const tapped = (i, event) => {
      if (this.state.currentPlayer === 'X') {
        this.setState({ [`box${i}`]: 'X', currentPlayer: 'O' })
      } else {
        this.setState({ [`box${i}`]: 'O', currentPlayer: 'X' })
      }
    }
    const reset = () => {
      for (let i = 1; i <= 9; i++) {
        this.setState({ [`box${i}`]: '', currentPlayer: 'X' });
      }
      Alert.alert('Board has been reset');
    }
    const createBoard = () => {
      const board = [];
      for (let i = 1; i <= 9; i++) {
        board.push(<TouchableOpacity key={i} style={styles.box} onPress={tapped.bind(this, i)}><Text style={styles.value}>{this.state[`box${i}`]}</Text></TouchableOpacity>)
      }
      return board;
    }
    return (
      <View>
        <View style={styles.container}>
          {createBoard()}
          <Button title="Reset" onPress={reset} />
          <View>
            <Text>Player Turn: {this.state.currentPlayer}</Text>
          </View>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    marginTop: '50%',
    height: '100%',
    width: '100%',
    flexDirection: 'row',
    flexWrap: 'wrap',
    flexBasis: '30%',
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  box: {
    display: 'inline-block',
    flexGrow: 1,
    height: '50%',
    width: '33%',
    borderStyle: 'solid',
    borderWidth: 3,
    justifyContent: 'center',
    alignItems: 'center',
  },
  value: {
    justifyContent: 'center',
    alignSelf: 'center',
    alignItems: 'center',
    fontWeight: '900',
  },
});
<|endoftext|>


<commit_before>// This App is supposed to find Test Sets and then list the Test Cases within them
//
//A new comment is added
//
// Verify connector function
// Prepare to add pull requests
//
// A Comment that needs to be made
// Another Change
// Change, Change, Change.....
//
// A change for the better
// Added by JC
Ext.define('CustomApp', {
    extend: 'Rally.app.App',
    componentCls: 'app',
    items:{ html:'App SDK 2.0rc3 Docs'},
    launch: function() {
    		var deStore;

    		var panel1 = Ext.create( 'Ext.panel.Panel', {
    			layout : {
    				type : 'hbox', // Arrange child items vertically
    				align : 'middle', // Each takes up full width
    			},
    			width : '100%',
    			bodyPadding : 10,
    			bodyStyle : {
    				background : '#9A9494',
    			},
    			items : [
    					{
    						xtype : 'container',
    						itemId : 'iterationFilter'
    					}, {
    						xtype : 'rallybutton',
    						text : 'Print Summary',
    						handler : function () {
    							this._printSummary();
    						},
    						style : {
    							marginRight : '10px',
    							marginLeft : '10px'
    						},
    						// flex:'1',
    						scope : this
    					}
    			/*
    			 * { xtype:'rallybutton', text: 'Print Defects', handler: function() { this._printDefects(); }, style: { marginLeft: '10px' },
    			 *
    			 * flex:'1', scope:this }
    			 */
    			]
    		} );
    		this.add( panel1 );
    		var panel2 = Ext.create( 'Ext.panel.Panel', {
    			layout : 'vbox',
    			width : '100%',
    			bodyPadding : 10,
    			bodyStyle : {
    				background : '#9A9494',
    			},
    			items : [

    				{
    					xtype : 'container',
    					layout : 'accordion',
    					itemId : 'testStatus',
    					width : '100%',
    					height : 500
    				}
    			]
    		} );

    		this.add( panel2 );
    		this._testSummary = [];
    		this._testResultList = [];
    		this._testSetTestList = [];
    		var TestSetStore;
    		var TestResultStore;
    		scope: this;

    		this.down( '#iterationFilter' ).add( {
    			xtype : 'rallyiterationcombobox',
    			itemId : 'iterationComboBox',
    			listeners : {
    				change : this._queryForTestSets,
    				ready : this._queryForTestSets,
    				scope : this
    			}
    		} );
    		;
    	},
    	_queryForTestSets : function () {

    		// if loading new iteration, destroy existing grids
    		if ( this._summaryGrid !== undefined ) {
    			this._summaryGrid.destroy();
    			this._Grid.destroy();
    			this._Grid2.destroy();
    		}

    		TestSetStore = Ext.create( 'Rally.data.WsapiDataStore', {
    			model : 'TestSet',
    			autoLoad : true,
    			storeId : 'TestSetStorer',
    			context : {
    				projectScopeUp : false,
    				projectScopeDown : true
    			},
    			filters : [
    					{
    						property : 'Project',
    						operator : '=',
    						value : this.getContext().getDataContext().project
    					}, {
    						property : 'Iteration.Name',
    						operator : '=',
    						value : this.down( '#iterationComboBox' ).getRecord().data.Name
    					}
    			],
    			fetch : [
    					'FormattedID', 'Name', 'TestCases', 'ObjectID', 'Project'
    			],
    			limit : 10000,
    			listeners : {
    				load : function ( store, data, success ) {
    					this._queryForTestResults( store, data )
    				},
    				scope : this
    			}
    		} );
    	},
});
<commit_msg>TA125: Testing 1 2 3 <commit_after>// This App is supposed to find Test Sets and then list the Test Cases within them
//
//A new comment is added
//
// Verify connector function
// Prepare to add pull requests
//
// Another Change
// Change, Change, Change.....
//
// A change for the better
// Added by JC
Ext.define('CustomApp', {
    extend: 'Rally.app.App',
    componentCls: 'app',
    items:{ html:'App SDK 2.0rc3 Docs'},
    launch: function() {
    		var deStore;

    		var panel1 = Ext.create( 'Ext.panel.Panel', {
    			layout : {
    				type : 'hbox', // Arrange child items vertically
    				align : 'middle', // Each takes up full width
    			},
    			width : '100%',
    			bodyPadding : 10,
    			bodyStyle : {
    				background : '#9A9494',
    			},
    			items : [
    					{
    						xtype : 'container',
    						itemId : 'iterationFilter'
    					}, {
    						xtype : 'rallybutton',
    						text : 'Print Summary',
    						handler : function () {
    							this._printSummary();
    						},
    						style : {
    							marginRight : '10px',
    							marginLeft : '10px'
    						},
    						// flex:'1',
    						scope : this
    					}
    			/*
    			 * { xtype:'rallybutton', text: 'Print Defects', handler: function() { this._printDefects(); }, style: { marginLeft: '10px' },
    			 *
    			 * flex:'1', scope:this }
    			 */
    			]
    		} );
    		this.add( panel1 );
    		var panel2 = Ext.create( 'Ext.panel.Panel', {
    			layout : 'vbox',
    			width : '100%',
    			bodyPadding : 10,
    			bodyStyle : {
    				background : '#9A9494',
    			},
    			items : [

    				{
    					xtype : 'container',
    					layout : 'accordion',
    					itemId : 'testStatus',
    					width : '100%',
    					height : 500
    				}
    			]
    		} );

    		this.add( panel2 );
    		this._testSummary = [];
    		this._testResultList = [];
    		this._testSetTestList = [];
    		var TestSetStore;
    		var TestResultStore;
    		scope: this;

    		this.down( '#iterationFilter' ).add( {
    			xtype : 'rallyiterationcombobox',
    			itemId : 'iterationComboBox',
    			listeners : {
    				change : this._queryForTestSets,
    				ready : this._queryForTestSets,
    				scope : this
    			}
    		} );
    		;
    	},
    	_queryForTestSets : function () {

    		// if loading new iteration, destroy existing grids
    		if ( this._summaryGrid !== undefined ) {
    			this._summaryGrid.destroy();
    			this._Grid.destroy();
    			this._Grid2.destroy();
    		}

    		TestSetStore = Ext.create( 'Rally.data.WsapiDataStore', {
    			model : 'TestSet',
    			autoLoad : true,
    			storeId : 'TestSetStorer',
    			context : {
    				projectScopeUp : false,
    				projectScopeDown : true
    			},
    			filters : [
    					{
    						property : 'Project',
    						operator : '=',
    						value : this.getContext().getDataContext().project
    					}, {
    						property : 'Iteration.Name',
    						operator : '=',
    						value : this.down( '#iterationComboBox' ).getRecord().data.Name
    					}
    			],
    			fetch : [
    					'FormattedID', 'Name', 'TestCases', 'ObjectID', 'Project'
    			],
    			limit : 10000,
    			listeners : {
    				load : function ( store, data, success ) {
    					this._queryForTestResults( store, data )
    				},
    				scope : this
    			}
    		} );
    	},
});
<|endoftext|>


<commit_before>// return all leaf stories of a hard-coded PI object ID

Ext.define('CustomApp', {
    extend:'Rally.app.App',
    componentCls:'app',
    layout:{
        type:'vbox',
        align:'stretch'
    },
    items:[

        { // define a container to house the PI combo box selector
            xtype:'container',
            itemId:'piChooserContainer',
            padding:'15 15 15 15' // top ? bottom left
        },
        {
            // panel where we will place the grid
            xtype:'panel',
            itemId:'piLeafStoryGridContainer',
            layout:'fit',
            height:400
        }
    ],

    // --- App global variables ---
    //gPiStories:[], // array to capture the list of all leaf stories in the PI
    gPiReleases:[], // array to capture the list of all stories a PI is scheduled in

    //gStoryGrid:undefined,

    // --- end global variables ---

    launch:function () {

        Ext.create('Rally.ui.dialog.ChooserDialog',{
            artifactTypes:['PortfolioItem/Feature'],
            autoShow:true,
            title:'Choose Feature',
            listeners:{
                artifactChosen:function (selectedRecord) {
                    //Ext.Msg.alert('Chooser', selectedRecord.get('Name') + ' was chosen');
                    this._getLeafStoriesInPi(selectedRecord.get('ObjectID'));
                },
                scope:this
            }
        });

    }, // end launch

    // reset the page's controls
    _reset:function () {
        this.gPiStories = [];
        //this._outstandingQueries = 0;
        this.down('#piLeafStoryGridContainer').removeAll();
    },

    // after PI selected, query for all its leaf level stories
    _getLeafStoriesInPi:function (piObjectID) {

        this._reset();

        var query = {
            "__At":"current",
            "_TypeHierarchy":"HierarchicalRequirement",
            "Children":null,
            "_ItemHierarchy":piObjectID
        };

        // set query config info
        var find = ["ObjectID", "_UnformattedID", "Name", "Release", "ScheduleState", "PlanEstimate"];
        var queryString = Ext.JSON.encode(query);

        // set context to global across the workspace
        var context = this.getContext().getDataContext();
        context.project = undefined;

        // fetch the snapshot of all leaf level stories for the PI
        var ssPiLeafStories = Ext.create('Rally.data.lookback.SnapshotStore', {
            context:{
                workspace:this.context.getWorkspace(),
                project:this.context.getProject()
            },
            fetch:find,
            rawFind:query,
            hydrate: ["ScheduleState"],
            autoLoad:true,
            listeners:{
                scope:this,
                load:this._processPiStories
            }
        });

    }, // end _getStoriesInPi

    // bucket the PI's stories by RELEASE (and no release)
    _processPiStories:function (store, records) {

        // spit out all leaf stories into a grid
        var snapshotGrid = Ext.create('Rally.ui.grid.Grid', {
            title:'Snapshots',
            store:store,
            columnCfgs:[
                {
                    text:'ObjectID',
                    dataIndex:'ObjectID'
                },
                {
                    text:'Name',
                    dataIndex:'Name'
                },
                {
                    text:'Project',
                    dataIndex:'Project'
                },
                {
                    text:'_UnformattedID',
                    dataIndex:'_UnformattedID'
                },
                ,
                {
                    text:'Release',
                    dataIndex:'Release'
                }
            ],
            height:400
        });

        // render the grid of all of the PI's leaf stories
        var gridHolder = this.down('#piLeafStoryGridContainer');
        gridHolder.removeAll(true);
        gridHolder.add(snapshotGrid);

        // --- BUCKET TIME BABY ---
        var aStory;
        var aRelease;

        var nbrStories = records.length;
        console.log("nbrStories: " + nbrStories);

        var storyNdx;

        // loop through each of the PI's stories
        for (storyNdx = 0; storyNdx < nbrStories; storyNdx++){
            aStory = records[storyNdx];

            if (aStory !== null){

                console.dir(aStory);
                console.log("aStory" + aStory);
                console.log("aStory" + aStory.get("Name"));
                console.log("aStory.PlanEstimate: " + aStory.get("PlanEstimate"));
                console.log("aStory.Release: " + aStory.get("Release"));
                console.log("aStory.ScheduleState: " + aStory.get("ScheduleState"));

                aRelease = null;

                aRelease = this._findReleaseEntry(this.gPiReleases, aStory.Release);

                if (aRelease === null){

                    // populate initial entry for this release
                    aRelease = new Object();

                    aRelease.itsStoryCount = 0;
                    aRelease.itsStoryPlanEstimate = 0;
                    aRelease.itsStoryCountAccepted = 0;
                    aRelease.itsStoryPlanEstimateAccepted = 0;

                }

                if (aStory.Release === null){
                    aRelease.itsOID = "Not Scheduled";
                }
                else{
                    aRelease.itsOID = aStory.get("Release");
                }

                aRelease.itsStoryCount += 1;
                aRelease.itsStoryPlanEstimate += aStory.get("PlanEstimate");

                if (aStory.get("ScheduleState") === "Accepted"){
                    aRelease.itsStoryCountAccepted += 1;
                    aRelease.itsStoryPlanEstimateAccepted += aStory.get("PlanEstimate");
                }

                this.gPiReleases.push(aRelease);

            } // end process this story

        } // end loop through all stories

        // process the PI's releases data
        this._processPiReleases();

        // chart PI's release meta data
        this._chartPiReleases();

        // --- END BUCKET TIME BABY ---

    }, // end _processPiStories

    _processPiReleases: function() {

        var nbrReleases = this.gPiReleases.length;
        console.log("nbrReleases: " + nbrReleases);

        var releaseNdx;
        var aRelease;

        // loop through each of the PI's releases
        for (releaseNdx = 0; releaseNdx < nbrReleases; releaseNdx++){

            aRelease = this.gPiReleases[releaseNdx];

            if (aRelease !== null){

                console.dir(aRelease);
                console.log("aRelease.itsOID: " + aRelease.itsOID);
                console.log("aRelease.itsStoryCount: " + aRelease.itsStoryCount);
                console.log("aRelease.itsStoryPlanEstimate: " + aRelease.itsStoryPlanEstimate);
                console.log("aRelease.itsStoryCountAccepted: " + aRelease.itsStoryCountAccepted);
                console.log("aRelease.itsStoryPlanEstimateAccepted: " + aRelease.itsStoryPlanEstimateAccepted);
            }

        } // end loop through each of the PI's releases

    }, // end _processPiReleases

    // bucket the PI's stories by RELEASE (and no release)
    _processPiStories:function () {

//        // spit out all leaf stories into a grid
//        var snapshotGrid = Ext.create('Rally.ui.grid.Grid', {
//            title:'Snapshots',
//            store:store,
//            columnCfgs:[
//                {
//                    text:'ObjectID',
//                    dataIndex:'ObjectID'
//                },
//                {
//                    text:'Name',
//                    dataIndex:'Name'
//                },
//                {
//                    text:'Project',
//                    dataIndex:'Project'
//                },
//                {
//                    text:'_UnformattedID',
//                    dataIndex:'_UnformattedID'
//                },
//                ,
//                {
//                    text:'Release',
//                    dataIndex:'Release'
//                }
//            ],
//            height:400
//        });
//
//        // render the grid of all of the PI's leaf stories
//        var gridHolder = this.down('#piLeafStoryGridContainer');
//        gridHolder.removeAll(true);
//        gridHolder.add(snapshotGrid);

    }, // end _chartPiReleases

    _findReleaseEntry:function (theArr, theReleaseOID) {

        // check if array is empty
        if (this.gReleaseArray === null)
            return null;

        arrLen = theArr.length;

        for (x = 0; x < arrLen; x++) {
            var anEntry = theArr[x];

            if (anEntry.itsOID == theReleaseOID) {
                return anEntry
            }
        }
        return null;
    } // end _findReleaseEntry

});
<commit_msg>Bucketed by release<commit_after>// return all leaf stories of a hard-coded PI object ID

Ext.define('CustomApp', {
    extend:'Rally.app.App',
    componentCls:'app',
    layout:{
        type:'vbox',
        align:'stretch'
    },
    items:[

        { // define a container to house the PI combo box selector
            xtype:'container',
            itemId:'piChooserContainer',
            padding:'15 15 15 15' // top ? bottom left
        },
        {
            // panel where we will place the grid
            xtype:'panel',
            itemId:'piLeafStoryGridContainer',
            layout:'fit',
            height:400
        }
    ],

    // --- App global variables ---
    //gPiStories:[], // array to capture the list of all leaf stories in the PI
    gPiReleases:[], // array to capture the list of all stories a PI is scheduled in

    //gStoryGrid:undefined,

    // --- end global variables ---

    launch:function () {

        Ext.create('Rally.ui.dialog.ChooserDialog',{
            artifactTypes:['PortfolioItem/Feature'],
            autoShow:true,
            title:'Choose Feature',
            listeners:{
                artifactChosen:function (selectedRecord) {
                    //Ext.Msg.alert('Chooser', selectedRecord.get('Name') + ' was chosen');
                    this._getLeafStoriesInPi(selectedRecord.get('ObjectID'));
                },
                scope:this
            }
        });

    }, // end launch

    // reset the page's controls
    _reset:function () {
        this.gPiStories = [];
        //this._outstandingQueries = 0;
        this.down('#piLeafStoryGridContainer').removeAll();
    },

    // after PI selected, query for all its leaf level stories
    _getLeafStoriesInPi:function (piObjectID) {

        this._reset();

        var query = {
            "__At":"current",
            "_TypeHierarchy":"HierarchicalRequirement",
            "Children":null,
            "_ItemHierarchy":piObjectID
        };

        // set query config info
        var find = ["ObjectID", "_UnformattedID", "Name", "Release", "ScheduleState", "PlanEstimate"];
        var queryString = Ext.JSON.encode(query);

        // set context to global across the workspace
        var context = this.getContext().getDataContext();
        context.project = undefined;

        // fetch the snapshot of all leaf level stories for the PI
        var ssPiLeafStories = Ext.create('Rally.data.lookback.SnapshotStore', {
            context:{
                workspace:this.context.getWorkspace(),
                project:this.context.getProject()
            },
            fetch:find,
            rawFind:query,
            hydrate: ["ScheduleState"],
            autoLoad:true,
            listeners:{
                scope:this,
                load:this._processPiStories
            }
        });

    }, // end _getStoriesInPi

    // bucket the PI's stories by RELEASE (and no release)
    _processPiStories:function (store, records) {

        // spit out all leaf stories into a grid
        var snapshotGrid = Ext.create('Rally.ui.grid.Grid', {
            title:'Snapshots',
            store:store,
            columnCfgs:[
                {
                    text:'ObjectID',
                    dataIndex:'ObjectID'
                },
                {
                    text:'Name',
                    dataIndex:'Name'
                },
                {
                    text:'Project',
                    dataIndex:'Project'
                },
                {
                    text:'_UnformattedID',
                    dataIndex:'_UnformattedID'
                },
                ,
                {
                    text:'Release',
                    dataIndex:'Release'
                }
            ],
            height:400
        });

        // render the grid of all of the PI's leaf stories
        var gridHolder = this.down('#piLeafStoryGridContainer');
        gridHolder.removeAll(true);
        gridHolder.add(snapshotGrid);

        // --- BUCKET TIME BABY ---
        var aStory;
        var aRelease;

        var nbrStories = records.length;
        console.log("nbrStories: " + nbrStories);

        var storyNdx;

        // loop through each of the PI's stories
        for (storyNdx = 0; storyNdx < nbrStories; storyNdx++){
            aStory = records[storyNdx];

            if (aStory !== null){

                console.dir(aStory);
                console.log("aStory" + aStory);
                console.log("aStory" + aStory.get("Name"));
                console.log("aStory.PlanEstimate: " + aStory.get("PlanEstimate"));
                console.log("aStory.Release: " + aStory.get("Release"));
                console.log("aStory.ScheduleState: " + aStory.get("ScheduleState"));

                aRelease = null;

                aRelease = this._findReleaseEntry(this.gPiReleases, aStory.Release);

                if (aRelease === null){

                    // populate initial entry for this release
                    aRelease = new Object();

                    aRelease.itsStoryCount = 0;
                    aRelease.itsStoryPlanEstimate = 0;
                    aRelease.itsStoryCountAccepted = 0;
                    aRelease.itsStoryPlanEstimateAccepted = 0;

                }

                if (!aStory.get("Release")){
                    aRelease.itsOID = "Not Scheduled";
                }
                else{
                    aRelease.itsOID = aStory.get("Release");
                }

                aRelease.itsStoryCount += 1;
                aRelease.itsStoryPlanEstimate += aStory.get("PlanEstimate");

                if (aStory.get("ScheduleState") === "Accepted"){
                    aRelease.itsStoryCountAccepted += 1;
                    aRelease.itsStoryPlanEstimateAccepted += aStory.get("PlanEstimate");
                }

                this.gPiReleases.push(aRelease);

            } // end process this story

        } // end loop through all stories

        // process the PI's releases data
        this._processPiReleases();

        // fetch release names (we need to convert Release OIDs from the LBAPI to logical Release names)
        this._fetchReleaseNames();

        // --- END BUCKET TIME BABY ---

    }, // end _processPiStories

    _processPiReleases: function() {

        var nbrReleases = this.gPiReleases.length;
        console.log("nbrReleases: " + nbrReleases);

        var releaseNdx;
        var aRelease;

        // loop through each of the PI's releases
        for (releaseNdx = 0; releaseNdx < nbrReleases; releaseNdx++){

            aRelease = this.gPiReleases[releaseNdx];

            if (aRelease !== null){

                console.dir(aRelease);
                console.log("aRelease.itsOID: " + aRelease.itsOID);
                console.log("aRelease.itsStoryCount: " + aRelease.itsStoryCount);
                console.log("aRelease.itsStoryPlanEstimate: " + aRelease.itsStoryPlanEstimate);
                console.log("aRelease.itsStoryCountAccepted: " + aRelease.itsStoryCountAccepted);
                console.log("aRelease.itsStoryPlanEstimateAccepted: " + aRelease.itsStoryPlanEstimateAccepted);
            }

        } // end loop through each of the PI's releases

    }, // end _processPiReleases

    // fetch all release names (we may later have to scale this back and do this more efficiently)
    _fetchReleaseNames: function() {

        var store = Ext.create('Rally.data.WsapiDataStore', {
            model: 'Release',

            fetch: ["ObjectID","Name"],
            // scope globally
            context: {
                project: null
            },
            limit: Infinity,
            autoLoad:true,
            listeners: {
                load: function(store, data, success) {
                    console.log("data",data);

                    // map release OIDs to release NAMES
                    this._mapReleaseOIDsToNames(store, data);

                },
                scope: this
            }
        });

    }, // end _fetchReleaseNames

    _mapReleaseOIDsToNames: function(theStore, allReleaseRecords)
    {
        var releaseNamesByObjectId = {};

        Ext.Array.each(allReleaseRecords,function(releaseRecord){
            releaseNamesByObjectId[releaseRecord.get("ObjectID")] = releaseRecord.get("Name");
        });

        //This sets each to have its name
        Ext.Array.each(this.gPiReleases,function(piReleases){
            piReleases.itsName = releaseNamesByObjectId[piReleases.itsOID];

            if(!piReleases.itsName){
                piReleases.itsName = "Unscheduled";
            }
        });

        var bucketReleaseByName = {};
        Ext.Array.each(this.gPiReleases,function(piReleases){
            if(!Ext.isArray(bucketReleaseByName[piReleases.itsName])){
                bucketReleaseByName[piReleases.itsName] = [];
            }
            bucketReleaseByName[piReleases.itsName].push(piReleases);
        });

        console.log(bucketReleaseByName);

        // chart PI's release meta data
        this._chartPiReleases();

    }, // end _fetchReleaseNames

    // chart out the PI's releases
    _chartPiReleases:function () {

//        // spit out all leaf stories into a grid
//        var snapshotGrid = Ext.create('Rally.ui.grid.Grid', {
//            title:'Snapshots',
//            store:store,
//            columnCfgs:[
//                {
//                    text:'ObjectID',
//                    dataIndex:'ObjectID'
//                },
//                {
//                    text:'Name',
//                    dataIndex:'Name'
//                },
//                {
//                    text:'Project',
//                    dataIndex:'Project'
//                },
//                {
//                    text:'_UnformattedID',
//                    dataIndex:'_UnformattedID'
//                },
//                ,
//                {
//                    text:'Release',
//                    dataIndex:'Release'
//                }
//            ],
//            height:400
//        });
//
//        // render the grid of all of the PI's leaf stories
//        var gridHolder = this.down('#piLeafStoryGridContainer');
//        gridHolder.removeAll(true);
//        gridHolder.add(snapshotGrid);

    }, // end _chartPiReleases

    _findReleaseEntry:function (theArr, theReleaseOID) {

        // check if array is empty
        if (this.gReleaseArray === null)
            return null;

        arrLen = theArr.length;

        for (x = 0; x < arrLen; x++) {
            var anEntry = theArr[x];

            if (anEntry.itsOID == theReleaseOID) {
                return anEntry
            }
        }
        return null;
    } // end _findReleaseEntry

});
<|endoftext|>


<commit_before>// This App is supposed to find Test Sets and then list the Test Cases within them
//
//
//A new comment is added
//
// Verify connector function
// Prepare to add pull requests
//
// This is a change for the better
//
//
//This a Test of vcs connector 2.0.5
//
//Creating a change in the code
//
// Test the logistics
// A change for the better
// Added by JC
//

// A change that is needed for my PR
//
//
// Times they are a changing
//
=======

Ext.define('CustomApp', {
    extend: 'Rally.app.App',
    componentCls: 'app',
    items:{ html:'App SDK 2.0rc3 Docs'},
    launch: function() {
    		var deStore;
// Adding a comment to this file - JC
//
    		var panel1 = Ext.create( 'Ext.panel.Panel', {
    			layout : {
    				type : 'hbox', // Arrange child items vertically
    				align : 'middle', // Each takes up full width
    			},
    			width : '100%',
    			bodyPadding : 10,
    			bodyStyle : {
    				background : '#9A9494',
    			},
    			items : [
    					{
    						xtype : 'container',
    						itemId : 'iterationFilter'
    					}, {
    						xtype : 'rallybutton',
    						text : 'Print Summary',
    						handler : function () {
    							this._printSummary();
    						},
    						style : {
    							marginRight : '10px',
    							marginLeft : '10px'
    						},
    						// flex:'1',
    						scope : this
    					}
    			/*
    			 * { xtype:'rallybutton', text: 'Print Defects', handler: function() { this._printDefects(); }, style: { marginLeft: '10px' },
    			 *
    			 * flex:'1', scope:this }
    			 */
    			]
    		} );
    		this.add( panel1 );
    		var panel2 = Ext.create( 'Ext.panel.Panel', {
    			layout : 'vbox',
    			width : '100%',
    			bodyPadding : 10,
    			bodyStyle : {
    				background : '#9A9494',
    			},
    			items : [

    				{
    					xtype : 'container',
    					layout : 'accordion',
    					itemId : 'testStatus',
    					width : '100%',
    					height : 500
    				}
    			]
    		} );

    		this.add( panel2 );
    		this._testSummary = [];
    		this._testResultList = [];
    		this._testSetTestList = [];
    		var TestSetStore;
    		var TestResultStore;
    		scope: this;

    		this.down( '#iterationFilter' ).add( {
    			xtype : 'rallyiterationcombobox',
    			itemId : 'iterationComboBox',
    			listeners : {
    				change : this._queryForTestSets,
    				ready : this._queryForTestSets,
    				scope : this
    			}
    		} );
    		;
    	},
    	_queryForTestSets : function () {

    		// if loading new iteration, destroy existing grids
    		if ( this._summaryGrid !== undefined ) {
    			this._summaryGrid.destroy();
    			this._Grid.destroy();
    			this._Grid2.destroy();
    		}

    		TestSetStore = Ext.create( 'Rally.data.WsapiDataStore', {
    			model : 'TestSet',
    			autoLoad : true,
    			storeId : 'TestSetStorer',
    			context : {
    				projectScopeUp : false,
    				projectScopeDown : true
    			},
    			filters : [
    					{
    						property : 'Project',
    						operator : '=',
    						value : this.getContext().getDataContext().project
    					}, {
    						property : 'Iteration.Name',
    						operator : '=',
    						value : this.down( '#iterationComboBox' ).getRecord().data.Name
    					}
    			],
    			fetch : [
    					'FormattedID', 'Name', 'TestCases', 'ObjectID', 'Project'
    			],
    			limit : 10000,
    			listeners : {
    				load : function ( store, data, success ) {
    					this._queryForTestResults( store, data )
    				},
    				scope : this
    			}
    		} );
    	},
});
<commit_msg>Added some pertinent Comments<commit_after>// This App is supposed to find Test Sets and then list the Test Cases within them
//
//
//A new comment is added
//
// Verify connector function
// Prepare to add pull requests
//
// This is a change for the better
//
//
//This a Test of vcs connector 2.0.5
//
//Creating a change in the code
//
// Test the logistics
// A change for the better
// Added by JC
//

// Some Overdue changes
// that need to be made
//
=======

Ext.define('CustomApp', {
    extend: 'Rally.app.App',
    componentCls: 'app',
    items:{ html:'App SDK 2.0rc3 Docs'},
    launch: function() {
    		var deStore;
// Adding a comment to this file - JC
//
    		var panel1 = Ext.create( 'Ext.panel.Panel', {
    			layout : {
    				type : 'hbox', // Arrange child items vertically
    				align : 'middle', // Each takes up full width
    			},
    			width : '100%',
    			bodyPadding : 10,
    			bodyStyle : {
    				background : '#9A9494',
    			},
    			items : [
    					{
    						xtype : 'container',
    						itemId : 'iterationFilter'
    					}, {
    						xtype : 'rallybutton',
    						text : 'Print Summary',
    						handler : function () {
    							this._printSummary();
    						},
    						style : {
    							marginRight : '10px',
    							marginLeft : '10px'
    						},
    						// flex:'1',
    						scope : this
    					}
    			/*
    			 * { xtype:'rallybutton', text: 'Print Defects', handler: function() { this._printDefects(); }, style: { marginLeft: '10px' },
    			 *
    			 * flex:'1', scope:this }
    			 */
    			]
    		} );
    		this.add( panel1 );
    		var panel2 = Ext.create( 'Ext.panel.Panel', {
    			layout : 'vbox',
    			width : '100%',
    			bodyPadding : 10,
    			bodyStyle : {
    				background : '#9A9494',
    			},
    			items : [

    				{
    					xtype : 'container',
    					layout : 'accordion',
    					itemId : 'testStatus',
    					width : '100%',
    					height : 500
    				}
    			]
    		} );

    		this.add( panel2 );
    		this._testSummary = [];
    		this._testResultList = [];
    		this._testSetTestList = [];
    		var TestSetStore;
    		var TestResultStore;
    		scope: this;

    		this.down( '#iterationFilter' ).add( {
    			xtype : 'rallyiterationcombobox',
    			itemId : 'iterationComboBox',
    			listeners : {
    				change : this._queryForTestSets,
    				ready : this._queryForTestSets,
    				scope : this
    			}
    		} );
    		;
    	},
    	_queryForTestSets : function () {

    		// if loading new iteration, destroy existing grids
    		if ( this._summaryGrid !== undefined ) {
    			this._summaryGrid.destroy();
    			this._Grid.destroy();
    			this._Grid2.destroy();
    		}

    		TestSetStore = Ext.create( 'Rally.data.WsapiDataStore', {
    			model : 'TestSet',
    			autoLoad : true,
    			storeId : 'TestSetStorer',
    			context : {
    				projectScopeUp : false,
    				projectScopeDown : true
    			},
    			filters : [
    					{
    						property : 'Project',
    						operator : '=',
    						value : this.getContext().getDataContext().project
    					}, {
    						property : 'Iteration.Name',
    						operator : '=',
    						value : this.down( '#iterationComboBox' ).getRecord().data.Name
    					}
    			],
    			fetch : [
    					'FormattedID', 'Name', 'TestCases', 'ObjectID', 'Project'
    			],
    			limit : 10000,
    			listeners : {
    				load : function ( store, data, success ) {
    					this._queryForTestResults( store, data )
    				},
    				scope : this
    			}
    		} );
    	},
});
<|endoftext|>


<commit_before>import React from 'react';
import { Platform, StatusBar, StyleSheet, View } from 'react-native';
import { AppLoading, Asset, Font } from 'expo';
import { Ionicons } from '@expo/vector-icons';
import RootNavigation from './navigation/RootNavigation';

export default class App extends React.Component {
  state = {
    assetsAreLoaded: false,
  };

  componentWillMount() {
    this._loadAssetsAsync();
  }

  render() {
    if (!this.state.assetsAreLoaded && !this.props.skipLoadingScreen) {
      return <AppLoading />;
    } else {
      return (
        <View style={styles.container}>
          {Platform.OS === 'ios' && <StatusBar barStyle="default" />}
          {Platform.OS === 'android' &&
            <View style={styles.statusBarUnderlay} />}
          <RootNavigation />
        </View>
      );
    }
  }

  async _loadAssetsAsync() {
    try {
      await Promise.all([
        Asset.loadAsync([
          require('./assets/images/robot-dev.png'),
          require('./assets/images/robot-prod.png'),
        ]),
        Font.loadAsync([
          // This is the font that we are using for our tab bar
          Ionicons.font,
          // We include SpaceMono because we use it in HomeScreen.js. Feel free
          // to remove this if you are not using it in your app
          { 'space-mono': require('./assets/fonts/SpaceMono-Regular.ttf') },
        ]),
      ]);
    } catch (e) {
      // In this case, you might want to report the error to your error
      // reporting service, for example Sentry
      console.warn(
        'There was an error caching assets (see: App.js), perhaps due to a ' +
          'network timeout, so we skipped caching. Reload the app to try again.'
      );
      console.log(e);
    } finally {
      this.setState({ assetsAreLoaded: true });
    }
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  statusBarUnderlay: {
    height: 24,
    backgroundColor: 'rgba(0,0,0,0.2)',
  },
});
<commit_msg>Create Redux store and add redux related import statements<commit_after>import React from 'react';
import { createStore, applyMiddleware } from 'redux';
import ReduxThunk from 'redux-thunk';
import { Platform, StatusBar, StyleSheet, View } from 'react-native';
import { AppLoading, Asset, Font } from 'expo';
import { Ionicons } from '@expo/vector-icons';
import RootNavigation from './navigation/RootNavigation';
import reducers from './reducers';

export default class App extends React.Component {
  state = {
    assetsAreLoaded: false,
  };

  componentWillMount() {
    this._loadAssetsAsync();
  }

  render() {
    const store = createStore(reducers, {}, applyMiddleware(ReduxThunk));

    if (!this.state.assetsAreLoaded && !this.props.skipLoadingScreen) {
      return <AppLoading />;
    } else {
      return (
        <View style={styles.container}>
          {Platform.OS === 'ios' && <StatusBar barStyle="default" />}
          {Platform.OS === 'android' &&
            <View style={styles.statusBarUnderlay} />}
          <RootNavigation />
        </View>
      );
    }
  }

  async _loadAssetsAsync() {
    try {
      await Promise.all([
        Asset.loadAsync([
          require('./assets/images/robot-dev.png'),
          require('./assets/images/robot-prod.png'),
        ]),
        Font.loadAsync([
          // This is the font that we are using for our tab bar
          Ionicons.font,
          // We include SpaceMono because we use it in HomeScreen.js. Feel free
          // to remove this if you are not using it in your app
          { 'space-mono': require('./assets/fonts/SpaceMono-Regular.ttf') },
        ]),
      ]);
    } catch (e) {
      // In this case, you might want to report the error to your error
      // reporting service, for example Sentry
      console.warn(
        'There was an error caching assets (see: App.js), perhaps due to a ' +
          'network timeout, so we skipped caching. Reload the app to try again.'
      );
      console.log(e);
    } finally {
      this.setState({ assetsAreLoaded: true });
    }
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  statusBarUnderlay: {
    height: 24,
    backgroundColor: 'rgba(0,0,0,0.2)',
  },
});
<|endoftext|>


<commit_before>Ext.define('CustomApp', {
    extend: 'Rally.app.App',
    componentCls: 'app',

        items : [
            {
                xtype: 'rallybutton',
                text: 'Click me',
                handler: function() {
                    Ext.Msg.alert('Button', 'You clicked me');
                }
            }
        ],

        launch: function() {
        //Write app code here
    }
});
<commit_msg>success<commit_after>Ext.define('CustomApp', {
    extend: 'Rally.app.App',
    componentCls: 'app',

        items : [
            {
                xtype: 'rallybutton',
                text: 'Click me',
                handler: function() {
                    Ext.Msg.alert('Alert Message', 'You clicked me');
                }
            }
        ],

        launch: function() {
        //Write app code here
    }
});
<|endoftext|>


<commit_before>var ID3 = (function() {
  ID3 = {};

  var textDecoder = new TextDecoder("utf-8");

  function rmPadding(tag) {
    var index = tag.indexOf('\u0000');
    if (index !== -1)
      return tag.slice(0, index);

    return tag;
  }

  function ID3v1Parser() {
  }

  ID3v1Parser.prototype = {
    parse: function(view) {
      var tags = {
        title: null,
        artist: null,
        album: null,
        year: null,
        comment: null,
        track: null,
        genre: null
      };
      view = view.subarray(view.byteLength - 128 + 3);

      var title = textDecoder.decode(view.subarray(0, 30));
      tags.title = rmPadding(title);

      var artist = textDecoder.decode(view.subarray(30, 60));
      tags.artist = rmPadding(artist);

      var album = textDecoder.decode(view.subarray(60, 90));
      tags.album = rmPadding(album);

      var year = textDecoder.decode(view.subarray(90, 94));
      tags.year = rmPadding(year);

      var comment =
        textDecoder.decode(view.subarray(94, 124));
      tags.comment = rmPadding(comment);

      if (view[122] === 0)
        tags.track = view[123];

      tags.genre = ID3.genres[view[124]];

      return tags;
    }
  };

  ID3.genres = [
    'Blues',
    'Classic Rock',
    'Country',
    'Dance',
    'Disco',
    'Funk',
    'Grunge',
    'Hip-Hop',
    'Jazz',
    'Metal',
    'New Age',
    'Oldies',
    'Other',
    'Pop',
    'R&B',
    'Rap',
    'Reggae',
    'Rock',
    'Techno',
    'Industrial',
    'Alternative',
    'Ska',
    'Death Metal',
    'Pranks',
    'Soundtrack',
    'Euro-Techno',
    'Ambient',
    'Trip-Hop',
    'Vocal',
    'Jazz+Funk',
    'Fusion',
    'Trance',
    'Classical',
    'Instrumental',
    'Acid',
    'House',
    'Game',
    'Sound Clip',
    'Gospel',
    'Noise',
    'AlternRock',
    'Bass',
    'Soul',
    'Punk',
    'Space',
    'Meditative',
    'Instrumental Pop',
    'Instrumental Rock',
    'Ethnic',
    'Gothic',
    'Darkwave',
    'Techno-Industrial',
    'Electronic',
    'Pop-Folk',
    'Eurodance',
    'Dream',
    'Southern Rock',
    'Comedy',
    'Cult',
    'Gangsta Rap',
    'Top 40',
    'Christian Rap',
    'Pop / Funk',
    'Jungle',
    'Native American',
    'Cabaret',
    'New Wave',
    'Psychedelic',
    'Rave',
    'Showtunes',
    'Trailer',
    'Lo-Fi',
    'Tribal',
    'Acid Punk',
    'Acid Jazz',
    'Polka',
    'Retro',
    'Musical',
    'Rock & Roll',
    'Hard Rock',
    'Folk',
    'Folk-Rock',
    'National Folk',
    'Swing',
    'Fast Fusion',
    'Bebob',
    'Latin',
    'Revival',
    'Celtic',
    'Bluegrass',
    'Avantgarde',
    'Gothic Rock',
    'Progressive Rock',
    'Psychedelic Rock',
    'Symphonic Rock',
    'Slow Rock',
    'Big Band',
    'Chorus',
    'Easy Listening',
    'Acoustic',
    'Humour',
    'Speech',
    'Chanson',
    'Opera',
    'Chamber Music',
    'Sonata',
    'Symphony',
    'Booty Bass',
    'Primus',
    'Porn Groove',
    'Satire',
    'Slow Jam',
    'Club',
    'Tango',
    'Samba',
    'Folklore',
    'Ballad',
    'Power Ballad',
    'Rhythmic Soul',
    'Freestyle',
    'Duet',
    'Punk Rock',
    'Drum Solo',
    'A Cappella',
    'Euro-House',
    'Dance Hall',
    'Goa',
    'Drum & Bass',
    'Club-House',
    'Hardcore',
    'Terror',
    'Indie',
    'BritPop',
    'Negerpunk',
    'Polsk Punk',
    'Beat',
    'Christian Gangsta Rap',
    'Heavy Metal',
    'Black Metal',
    'Crossover',
    'Contemporary Christian',
    'Christian Rock',
    'Merengue',
    'Salsa',
    'Thrash Metal',
    'Anime',
    'JPop',
    'Synthpop',
    'Rock/Pop'
  ];

  function ID3v2Parser() {
  }

  ID3v2Parser.decoders = {
    'string': function(description) {
      return textDecoder.decode(description);
    },

    'integer': function(description) {
      return parseInt(textDecoder.decode(description), 10);
    }
  }

  ID3v2Parser.tags = {
    'TIT2': {name: 'title',  type: 'string'},
    'TPE1': {name: 'artist', type: 'string'},
    'TALB': {name: 'album',  type: 'string'},
    'TYER': {name: 'year',   type: 'string'},
    // XXX: we may want to have a tack type here as it can be
    // something else than an integer. See TRCK frame description
    // http://id3.org/id3v2.3.0#Declared_ID3v2_frames for more
    // information.
    'TRCK': {name: 'track',  type: 'integer'}
  }

  ID3v2Parser.prototype = {
    _parseFrames: function(view) {
      var cursor = 0;
      var frames = [];
      var frame;

      while (cursor < view.byteLength) {
        frame = this._parseFrame(view.subarray(cursor));
        frames.push(frame);
        cursor += 10 + frame.size;
      }

      return frames;
    },

    _parseFrame: function(view) {
      var id, size, description;

      id = view.subarray(0, 4);
      size = new DataView(view.buffer, view.byteOffset + 4, 4);
      size = size.getUint32(0);
      // XXX: here we skip the encoding byte
      description = view.subarray(10 + 1, 10 + size);

      return {id: id, description: description, size: size};
    },

    parse: function(view) {
      var tagSize = new DataView(view.buffer, view.byteOffset + 6, 4);
      tagSize = tagSize.getUint32(0);

      var frames = this._parseFrames(view.subarray(10, 10 + tagSize));
      var tags = frames.reduce(function(tags, frame) {
        var id  = textDecoder.decode(frame.id);
        var tag = ID3v2Parser.tags[id];
        var decode;

        // We only decode the tag if it is known in ID3v2Parser.tags
        if (tag) {
          decode = ID3v2Parser.decoders[tag.type];
          tags[tag.name] = decode(frame.description);
        }

        return tags;
      }, {});

      return tags;
    }
  };

  ID3.ID3v1Parser = ID3v1Parser;
  ID3.ID3v2Parser = ID3v2Parser;

  return ID3;
}());
<commit_msg>Handle latin1 and utf-16 encodings<commit_after>var ID3 = (function() {
  var ID3 = {};

  var latin1 = new TextDecoder("latin1", {fatal: true});
  var utf16  = new TextDecoder("utf-16", {fatal: true});

  function rmPadding(tag) {
    var index = tag.indexOf('\u0000');
    if (index !== -1)
      return tag.slice(0, index);

    return tag;
  }

  function ID3v1Parser() {
  }

  ID3v1Parser.prototype = {
    parse: function(view) {
      var tags = {
        title: null,
        artist: null,
        album: null,
        year: null,
        comment: null,
        track: null,
        genre: null
      };
      view = view.subarray(view.byteLength - 128 + 3);

      var title = utf16.decode(view.subarray(0, 30));
      tags.title = rmPadding(title);

      var artist = utf16.decode(view.subarray(30, 60));
      tags.artist = rmPadding(artist);

      var album = utf16.decode(view.subarray(60, 90));
      tags.album = rmPadding(album);

      var year = utf16.decode(view.subarray(90, 94));
      tags.year = rmPadding(year);

      var comment =
        utf16.decode(view.subarray(94, 124));
      tags.comment = rmPadding(comment);

      if (view[122] === 0)
        tags.track = view[123];

      tags.genre = ID3.genres[view[124]];

      return tags;
    }
  };

  ID3.genres = [
    'Blues',
    'Classic Rock',
    'Country',
    'Dance',
    'Disco',
    'Funk',
    'Grunge',
    'Hip-Hop',
    'Jazz',
    'Metal',
    'New Age',
    'Oldies',
    'Other',
    'Pop',
    'R&B',
    'Rap',
    'Reggae',
    'Rock',
    'Techno',
    'Industrial',
    'Alternative',
    'Ska',
    'Death Metal',
    'Pranks',
    'Soundtrack',
    'Euro-Techno',
    'Ambient',
    'Trip-Hop',
    'Vocal',
    'Jazz+Funk',
    'Fusion',
    'Trance',
    'Classical',
    'Instrumental',
    'Acid',
    'House',
    'Game',
    'Sound Clip',
    'Gospel',
    'Noise',
    'AlternRock',
    'Bass',
    'Soul',
    'Punk',
    'Space',
    'Meditative',
    'Instrumental Pop',
    'Instrumental Rock',
    'Ethnic',
    'Gothic',
    'Darkwave',
    'Techno-Industrial',
    'Electronic',
    'Pop-Folk',
    'Eurodance',
    'Dream',
    'Southern Rock',
    'Comedy',
    'Cult',
    'Gangsta Rap',
    'Top 40',
    'Christian Rap',
    'Pop / Funk',
    'Jungle',
    'Native American',
    'Cabaret',
    'New Wave',
    'Psychedelic',
    'Rave',
    'Showtunes',
    'Trailer',
    'Lo-Fi',
    'Tribal',
    'Acid Punk',
    'Acid Jazz',
    'Polka',
    'Retro',
    'Musical',
    'Rock & Roll',
    'Hard Rock',
    'Folk',
    'Folk-Rock',
    'National Folk',
    'Swing',
    'Fast Fusion',
    'Bebob',
    'Latin',
    'Revival',
    'Celtic',
    'Bluegrass',
    'Avantgarde',
    'Gothic Rock',
    'Progressive Rock',
    'Psychedelic Rock',
    'Symphonic Rock',
    'Slow Rock',
    'Big Band',
    'Chorus',
    'Easy Listening',
    'Acoustic',
    'Humour',
    'Speech',
    'Chanson',
    'Opera',
    'Chamber Music',
    'Sonata',
    'Symphony',
    'Booty Bass',
    'Primus',
    'Porn Groove',
    'Satire',
    'Slow Jam',
    'Club',
    'Tango',
    'Samba',
    'Folklore',
    'Ballad',
    'Power Ballad',
    'Rhythmic Soul',
    'Freestyle',
    'Duet',
    'Punk Rock',
    'Drum Solo',
    'A Cappella',
    'Euro-House',
    'Dance Hall',
    'Goa',
    'Drum & Bass',
    'Club-House',
    'Hardcore',
    'Terror',
    'Indie',
    'BritPop',
    'Negerpunk',
    'Polsk Punk',
    'Beat',
    'Christian Gangsta Rap',
    'Heavy Metal',
    'Black Metal',
    'Crossover',
    'Contemporary Christian',
    'Christian Rock',
    'Merengue',
    'Salsa',
    'Thrash Metal',
    'Anime',
    'JPop',
    'Synthpop',
    'Rock/Pop'
  ];

  function ID3v2Parser() {
  }

  ID3v2Parser.decoders = {
    'string': function(description) {
      var isUnicode = description[0] === 1;
      var decoder   = (isUnicode) ? utf16 : latin1;

      return decoder.decode(description.subarray(1));
    },

    'integer': function(description) {
      description = ID3v2Parser.decoders.string(description);
      return parseInt(description, 10);
    }
  }

  ID3v2Parser.tags = {
    'TIT2': {name: 'title',  type: 'string'},
    'TPE1': {name: 'artist', type: 'string'},
    'TALB': {name: 'album',  type: 'string'},
    'TYER': {name: 'year',   type: 'string'},
    // XXX: we may want to have a tack type here as it can be
    // something else than an integer. See TRCK frame description
    // http://id3.org/id3v2.3.0#Declared_ID3v2_frames for more
    // information.
    'TRCK': {name: 'track',  type: 'integer'}
  }

  ID3v2Parser.prototype = {
    _parseFrames: function(view) {
      var cursor = 0;
      var frames = [];
      var frame;

      while (cursor < view.byteLength) {
        frame = this._parseFrame(view.subarray(cursor));
        frames.push(frame);
        cursor += 10 + frame.size;
      }

      return frames;
    },

    _parseFrame: function(view) {
      var id, size, description;

      id = view.subarray(0, 4);
      size = new DataView(view.buffer, view.byteOffset + 4, 4);
      size = size.getUint32(0);
      description = view.subarray(10, 10 + size);

      return {id: id, description: description, size: size};
    },

    parse: function(view) {
      var tagSize = new DataView(view.buffer, view.byteOffset + 6, 4);
      tagSize = tagSize.getUint32(0);

      var frames = this._parseFrames(view.subarray(10, 10 + tagSize));
      var tags = frames.reduce(function(tags, frame) {
        var id  = latin1.decode(frame.id);
        var tag = ID3v2Parser.tags[id];
        var decode;

        // We only decode the tag if it is known in ID3v2Parser.tags
        if (tag) {
          decode = ID3v2Parser.decoders[tag.type];
          tags[tag.name] = decode(frame.description);
        }

        return tags;
      }, {});

      return tags;
    }
  };

  ID3.ID3v1Parser = ID3v1Parser;
  ID3.ID3v2Parser = ID3v2Parser;

  return ID3;
}());
<|endoftext|>


<commit_before>(function (){
    var myConnector = tableau.makeConnector();

    setupConnector = function (){
        var server = $('#serverInput').val().trim();
        var token = $('#tokenInput').val().trim();
        if (server && token){
            tableau.connectionData = JSON.stringify({server: server, token: token});
            tableau.connectionName = "Method52";
        }
    };

    myConnector.getSchema = function (schemaCallback){
        var params = JSON.parse(tableau.connectionData);
        var cols = [];
        // http://stackoverflow.com/questions/3595515/xmlhttprequest-error-origin-null-is-not-allowed-by-access-control-allow-origin
        var apiURL = params.server + "/access-tokens/handle?target=schema&token=" + params.token;

        var types = {
            "java.lang.Long": tableau.dataTypeEnum.int,
            "java.lang.Integer": tableau.dataTypeEnum.int,
            "java.lang.Float": tableau.dataTypeEnum.float,
            "java.lang.Double": tableau.dataTypeEnum.float,
            "java.lang.String": tableau.dataTypeEnum.string,
            "java.lang.Boolean": tableau.dataTypeEnum.bool,
            "org.joda.time.Instant": tableau.dataTypeEnum.date,
        }
        // todo how do we handle "java.util.List"?

        $.getJSON(apiURL, function (resp){
            $.each(resp.schema, function (keyName, value){
                //http://tableau.github.io/webdataconnector/ref/api_ref.html#webdataconnectorapi.columninfo
                const type = types[value.type.class];
                if (type == 'java.util.List' || type === undefined){
                    return true; // continue
                }

                cols.push({
                    id: keyName.replace(/\W+/g, "_"),
                    alias: keyName,
                    description: 'Original name is "' + keyName + '"in',
                    dataType: type
                });
            });
            for (var keyName in resp){
                if (resp.hasOwnProperty(keyName)){

                }
            }
        }).success(function (){
            var tableInfo = {
                id: "M52Feed",
		        alias: "table",
                description: "Data from the M52 API",
                columns: cols
            };

            schemaCallback([tableInfo]);
        });
    };

    myConnector.getData = function (table, doneCallback){
        var params = JSON.parse(tableau.connectionData);
        var apiURL = params.server + "/access-tokens/handle?token=" + params.token;
        var originalURL = apiURL;
        var getMoreData = function (){
            $.getJSON(apiURL, function (resp){
                if (resp.data == "EOF"){
                    console.info("End of data stream");
                    doneCallback();
                } else {
                    if (resp.data.length==0){
                        console.info("No new data has been fetched.");
                    } else {
                        console.info("Got more data: " + resp.data.length);
                    }

                    var parsedResponse = [];
                    $.each(resp.data, function (index, rawObj){
                        var cleanedObj = new Object();

                        $.each(rawObj, function (keyName, value){
                            if (value.iMillis !== undefined){
                                // this is a serialised jodatime Instant
                                value = value.iMillis;
                            }
                            var cleanKey = keyName.replace(/\W+/g, "_");
                            cleanedObj[cleanKey] = value;
                        })

                        parsedResponse.push(cleanedObj);
                    });

                    table.appendRows(parsedResponse);

                    if (resp.next) {
                        apiURL = originalURL + "&next=" + resp.next;
                    }

                    getMoreData();
                }
            }).error(function (jqXHR, textStatus, errorThrown){
                tableau.abortWithError(errorThrown + "; " + textStatus);
            })
            ;
        }

        getMoreData();

    };

    tableau.registerConnector(myConnector);

    $(document).ready(function (){
        $("#submitButton").click(function (){
            console.log("clicked");
            setupConnector();
            tableau.submit();
        });
    });
})();
<commit_msg>corrected URLs<commit_after>(function (){
    var myConnector = tableau.makeConnector();

    setupConnector = function (){
        var server = $('#serverInput').val().trim();
        var token = $('#tokenInput').val().trim();
        if (server && token){
            tableau.connectionData = JSON.stringify({server: server, token: token});
            tableau.connectionName = "Method52";
        }
    };

    myConnector.getSchema = function (schemaCallback){
        var params = JSON.parse(tableau.connectionData);
        var cols = [];
        // http://stackoverflow.com/questions/3595515/xmlhttprequest-error-origin-null-is-not-allowed-by-access-control-allow-origin
        var apiURL = params.server + "/supergui/access-tokens/handle?target=schema&token=" + params.token;

        var types = {
            "java.lang.Long": tableau.dataTypeEnum.int,
            "java.lang.Integer": tableau.dataTypeEnum.int,
            "java.lang.Float": tableau.dataTypeEnum.float,
            "java.lang.Double": tableau.dataTypeEnum.float,
            "java.lang.String": tableau.dataTypeEnum.string,
            "java.lang.Boolean": tableau.dataTypeEnum.bool,
            "org.joda.time.Instant": tableau.dataTypeEnum.date,
        }
        // todo how do we handle "java.util.List"?

        $.getJSON(apiURL, function (resp){
            $.each(resp.schema, function (keyName, value){
                //http://tableau.github.io/webdataconnector/ref/api_ref.html#webdataconnectorapi.columninfo
                const type = types[value.type.class];
                if (type == 'java.util.List' || type === undefined){
                    return true; // continue
                }

                cols.push({
                    id: keyName.replace(/\W+/g, "_"),
                    alias: keyName,
                    description: 'Original name is "' + keyName + '"in',
                    dataType: type
                });
            });
            for (var keyName in resp){
                if (resp.hasOwnProperty(keyName)){

                }
            }
        }).success(function (){
            var tableInfo = {
                id: "M52Feed",
		        alias: "table",
                description: "Data from the M52 API",
                columns: cols
            };

            schemaCallback([tableInfo]);
        });
    };

    myConnector.getData = function (table, doneCallback){
        var params = JSON.parse(tableau.connectionData);
        var apiURL = params.server + "/supergui/access-tokens/handle?token=" + params.token;
        var originalURL = apiURL;
        var getMoreData = function (){
            $.getJSON(apiURL, function (resp){
                if (resp.data == "EOF"){
                    console.info("End of data stream");
                    doneCallback();
                } else {
                    if (resp.data.length==0){
                        console.info("No new data has been fetched.");
                    } else {
                        console.info("Got more data: " + resp.data.length);
                    }

                    var parsedResponse = [];
                    $.each(resp.data, function (index, rawObj){
                        var cleanedObj = new Object();

                        $.each(rawObj, function (keyName, value){
                            if (value.iMillis !== undefined){
                                // this is a serialised jodatime Instant
                                value = value.iMillis;
                            }
                            var cleanKey = keyName.replace(/\W+/g, "_");
                            cleanedObj[cleanKey] = value;
                        })

                        parsedResponse.push(cleanedObj);
                    });

                    table.appendRows(parsedResponse);

                    if (resp.next) {
                        apiURL = originalURL + "&next=" + resp.next;
                    }

                    getMoreData();
                }
            }).error(function (jqXHR, textStatus, errorThrown){
                tableau.abortWithError(errorThrown + "; " + textStatus);
            })
            ;
        }

        getMoreData();

    };

    tableau.registerConnector(myConnector);

    $(document).ready(function (){
        $("#submitButton").click(function (){
            console.log("clicked");
            setupConnector();
            tableau.submit();
        });
    });
})();
<|endoftext|>


<commit_before>'use strict';

import React, {
  PropTypes,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';

import autobind from 'autobind-decorator';

import Layout from './Layout';

export default class Tab extends React.Component {
  static propTypes = {
    title: PropTypes.string,
    titleStyle: Text.propTypes.style,
    badge: PropTypes.element,
    onPress: PropTypes.func,
  };

  render() {
    let { title, badge } = this.props;
    let icon = React.Children.only(this.props.children);

    if (title) {
      title =
        <Text
          numberOfLines={1}
          style={[styles.title, this.props.titleStyle]}>
          {title}
        </Text>;
    }

    if (badge) {
      badge = React.cloneElement(badge, {
        style: [styles.badge, badge.style],
      });
    }

    let tabStyle = [styles.container, title ? null : styles.untitledContainer];
    return (
      <TouchableOpacity
        activeOpacity={0.8}
        onPress={this._handlePress}
        style={tabStyle}>
        <View>
          {icon}
          {badge}
        </View>
        {title}
      </TouchableOpacity>
    );
  }

  @autobind
  _handlePress(event) {
    if (this.props.onPress) {
      this.props.onPress(event);
    }
  }
}

let styles = StyleSheet.create({
  badge: {
    position: 'absolute',
    top: -6,
    right: -10,
  },
  container: {
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'flex-end',
    alignItems: 'center',
  },
  untitledContainer: {
    paddingBottom: 13,
  },
  title: {
    color: '#929292',
    fontSize: 10,
    textAlign: 'center',
    alignSelf: 'stretch',
    marginTop: 4,
    marginBottom: 1 + Layout.pixel,
  },
});
<commit_msg>make customer badge style available<commit_after>'use strict';

import React, {
  PropTypes,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';

import autobind from 'autobind-decorator';

import Layout from './Layout';

export default class Tab extends React.Component {
  static propTypes = {
    title: PropTypes.string,
    titleStyle: Text.propTypes.style,
    badge: PropTypes.element,
    onPress: PropTypes.func,
  };

  render() {
    let { title, badge } = this.props;
    let icon = React.Children.only(this.props.children);

    if (title) {
      title =
        <Text
          numberOfLines={1}
          style={[styles.title, this.props.titleStyle]}>
          {title}
        </Text>;
    }

    if (badge) {
      badge = React.cloneElement(badge, {
        style: [styles.badge, badge.props.style],
      });
    }

    let tabStyle = [styles.container, title ? null : styles.untitledContainer];
    return (
      <TouchableOpacity
        activeOpacity={0.8}
        onPress={this._handlePress}
        style={tabStyle}>
        <View>
          {icon}
          {badge}
        </View>
        {title}
      </TouchableOpacity>
    );
  }

  @autobind
  _handlePress(event) {
    if (this.props.onPress) {
      this.props.onPress(event);
    }
  }
}

let styles = StyleSheet.create({
  badge: {
    position: 'absolute',
    top: -6,
    right: -10,
  },
  container: {
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'flex-end',
    alignItems: 'center',
  },
  untitledContainer: {
    paddingBottom: 13,
  },
  title: {
    color: '#929292',
    fontSize: 10,
    textAlign: 'center',
    alignSelf: 'stretch',
    marginTop: 4,
    marginBottom: 1 + Layout.pixel,
  },
});
<|endoftext|>