<commit_before>// Code goes here
(function(window){

window.onload = function() {

var startPosition = null,
  endPosition = null,
  tabsContainer = document.getElementById('tabs-container'),
  tabs = document.getElementById('tabs-move'),
  lastTab = tabs.getElementsByClassName('tab').length - 1,
  tabsLink = document.getElementsByClassName('tabs-link')[0],
  tabsLinkArray = document.getElementsByClassName('tab-link'),
  indicator = document.getElementsByClassName('indicator')[0],
  startTranslate = 0,
  endTranslate = -100 * lastTab,
  currentTranslate = startTranslate,
  sliding = false,
  distanceToChangeView = 150,
  touchOffset = 50,
  currentTab = 0,
  changingTab = false,

  indicatorMargin = 0,
  prevTab = {},
  nextTab = {},
  containerWdith = tabsContainer.clientWidth;
  currentTranslateIndicator = 0;

// Obtener datos de las pestañas
var tabsData = [ ],
  marginLeftAux = 0;

[].forEach.call( tabsLinkArray, setData);

function setData( element, index ){
  element.setAttribute('data-id', index);

  var tab = {
    id: index,
    width: element.getBoundingClientRect().width
  };
  tab.center = tab.width/2;
  tab.marginLeft = marginLeftAux + tab.center;

  tabsData.push(tab);

  marginLeftAux += tab.width;
}

tabsLinkArray[currentTab].classList.add('active');

var a = tabsLinkArray[currentTab+1].getBoundingClientRect();

nextTab = {
  id: currentTab+1,
  width: tabsLinkArray[currentTab+1].clientWidth,
  marginLeft: Math.floor(a.width/2 + a.left + tabsLink.scrollLeft)
}

moveIndicator();

tabs.addEventListener('touchend', mouseUp);
tabs.addEventListener('touchstart', mouseDown);
tabs.addEventListener('touchmove', mouseMove);
tabsLink.addEventListener('click', tabLink);

function updateIndicatorWidth(){
  indicator.style.transform =  "scaleX(" + tabsData[currentTab].width + ")";
  currentTranslateIndicator = tabsData[currentTab].width;
}

function updateIndicatorPosition(){
  indicatorMargin = tabsData[currentTab].marginLeft;
  indicator.style.marginLeft = indicatorMargin +'px';
}

function moveIndicator(){
  updateIndicatorWidth();
  updateIndicatorPosition();
}

function tabLink(event){
  if( changingTab ){ return; }

  changingTab = true;

  setTransition();
  tabsLinkArray[currentTab].classList.remove('active');
  currentTab = event.target.getAttribute('data-id');
  currentTranslate = currentTab*-100;
  setTranslationPercen( currentTranslate );
  tabsLinkArray[currentTab].classList.add('active');

  moveIndicator();

  changingTab = false;
}

function mouseUp(event) {

  sliding = false;

  setTransition();
  tabsLinkArray[currentTab].classList.remove('active');

  if ( moveToLeftView() ) {
    currentTab--;
    calcTranslation();
    setTranslationPercen( currentTranslate );

    var currentTabDistance = tabsLinkArray[ currentTab ].getBoundingClientRect();
      currentTabLeftDistance = currentTabDistance.left;

    if( currentTabLeftDistance < 0 ){
      tabsLink.scrollLeft = tabsLink.scrollLeft + currentTabLeftDistance;
    }else if ( currentTabDistance.right > tabsLink.clientWidth ){
      tabsLink.scrollLeft = currentTabDistance.right - tabsLink.clientWidth;
    }

  } else if ( moveToRightView() ) {
    currentTab++;
    calcTranslation();
    setTranslationPercen( currentTranslate );

    var currentTabDistance = tabsLinkArray[ currentTab ].getBoundingClientRect(),
      currentTabRightDistance = currentTabDistance.right;

    if( tabsLink.clientWidth < currentTabRightDistance ){
      tabsLink.scrollLeft = tabsLink.scrollLeft + currentTabRightDistance - tabsLink.clientWidth;
    }else if( currentTabRightDistance < 0 ){
      tabsLink.scrollLeft = tabsLink.scrollLeft + currentTabDistance.left;
    }

  } else if ( leftLimit() ) {
    setTranslationPercen( startTranslate );

  } else if ( rightLimit() ) {
    setTranslationPercen( endTranslate );

  } else {
    setTranslationPercen( currentTranslate );
  }

  tabsLinkArray[currentTab].classList.add('active');
  moveIndicator();

}

function mouseDown(event) {
  sliding = true;
  startPosition = event.touches[0].clientX;
}

function mouseMove(event){

  if (!sliding) {
    return;
  }
  endPosition = event.touches[0].clientX;

  removeTransition();

  if ( toRight( event ) ) {
    setTranslation( "calc( " + (event.touches[0].clientX - touchOffset - startPosition) + "px + " + currentTranslate + "% )" );
    //indicator.style.marginLeft = indicatorMargin + (event.touches[0].clientX - touchOffset - startPosition) +'px';

    var vistaRespectoPantalla = containerWdith / (event.touches[0].clientX - touchOffset - startPosition);

    var currentTab = {
      id: 0,
      width: tabsLinkArray[0].clientWidth,
      marginLeft: Math.floor(tabsLinkArray[0].clientWidth/2 + tabsLinkArray[0].getBoundingClientRect().left + tabsLink.scrollLeft)
    }

    var auxWidth = nextTab.marginLeft - currentTab.marginLeft;
    var newPos = auxWidth / vistaRespectoPantalla;
    indicator.style.marginLeft = indicatorMargin - newPos +'px';

  } else if ( toLeft( event ) ) {
    setTranslation( "calc( " + currentTranslate + "% - " + (startPosition - event.touches[0].clientX - touchOffset) + "px)" );

    var vistaRespectoPantalla = containerWdith / (startPosition - event.touches[0].clientX - touchOffset);

    var currentTab = {
      id: 0,
      width: tabsLinkArray[0].clientWidth,
      marginLeft: Math.floor(tabsLinkArray[0].clientWidth/2 + tabsLinkArray[0].getBoundingClientRect().left + tabsLink.scrollLeft)
    }

    var auxWidth = nextTab.marginLeft - currentTab.marginLeft;
    var newPos = auxWidth / vistaRespectoPantalla;
    indicator.style.marginLeft = indicatorMargin + newPos +'px';

    //indicator.style.transform =  "scaleX(" + Math.floor(tabsLinkArray[0].clientWidth - newPos) + ")";
    //console.log( tabsLinkArray[0].clientWidth - Math.floor(newPos) );
    /*var repectoAnchuras = currentTab.width / nextTab.width;
    indicator.style.transform =  "scaleX(" + currentTranslateIndicator - Math.floor(repectoAnchuras) + ")";
    currentTranslateIndicator = currentTranslateIndicator - Math.floor(repectoAnchuras);
    console.log(currentTranslateIndicator);*/

  }

}

function setTranslation( translation ){
  tabs.style.transform = "translateX(" + translation + ")";
}

function setTranslationPercen( translation ){
  setTranslation( translation+'%' );
}

function setTransition(){
  tabs.style.transition = "transform 0.4s ease-out";
}

function removeTransition(){
  tabs.style.transition = "";
}

function toLeft(event){
  return event.touches[0].clientX < startPosition - touchOffset;
}

function toRight(event){
  return event.touches[0].clientX > startPosition + touchOffset;
}

function leftLimit(){
  return currentTranslate === startTranslate;
}

function rightLimit(){
  return currentTranslate === endTranslate;
}

function moveToRightView(){
  return startPosition > endPosition&&
    startPosition - endPosition > distanceToChangeView &&
    !rightLimit();
}

function moveToLeftView(){
  return endPosition > startPosition &&
    endPosition - startPosition > distanceToChangeView &&
    !leftLimit();
}

function calcTranslation(){
  currentTranslate = currentTab * -100;
}

}

})(window);<commit_msg>Quitar variable global marginLeft para calcular el margin left del indicador<commit_after>// Code goes here
(function(window){

window.onload = function() {

var startPosition = null,
  endPosition = null,
  tabsContainer = document.getElementById('tabs-container'),
  tabs = document.getElementById('tabs-move'),
  lastTab = tabs.getElementsByClassName('tab').length - 1,
  tabsLink = document.getElementsByClassName('tabs-link')[0],
  tabsLinkArray = document.getElementsByClassName('tab-link'),
  indicator = document.getElementsByClassName('indicator')[0],
  startTranslate = 0,
  endTranslate = -100 * lastTab,
  currentTranslate = startTranslate,
  sliding = false,
  distanceToChangeView = 150,
  touchOffset = 50,
  currentTab = 0,
  changingTab = false,

  indicatorMargin = 0,
  prevTab = {},
  nextTab = {},
  containerWdith = tabsContainer.clientWidth;
  currentTranslateIndicator = 0;

// Obtener datos de las pestañas
var tabsData = [ ];

[].forEach.call( tabsLinkArray, setData);

function setData( element, index ){
  element.setAttribute('data-id', index);

  var tab = {
    id: index,
    width: element.getBoundingClientRect().width
  };
  tab.center = tab.width/2;

  if( index ){
    tab.left = tabsData[index-1].right;
    tab.right = tab.left + tab.width;
  }else{
    tab.left = 0;
    tab.right = tab.width;
  }

  tab.marginLeft = tab.left + tab.center;

  tabsData.push(tab);

}

tabsLinkArray[currentTab].classList.add('active');

var a = tabsLinkArray[currentTab+1].getBoundingClientRect();

nextTab = {
  id: currentTab+1,
  width: tabsLinkArray[currentTab+1].clientWidth,
  marginLeft: Math.floor(a.width/2 + a.left + tabsLink.scrollLeft)
}

moveIndicator();

tabs.addEventListener('touchend', mouseUp);
tabs.addEventListener('touchstart', mouseDown);
tabs.addEventListener('touchmove', mouseMove);
tabsLink.addEventListener('click', tabLink);

function updateIndicatorWidth(){
  indicator.style.transform =  "scaleX(" + tabsData[currentTab].width + ")";
  currentTranslateIndicator = tabsData[currentTab].width;
}

function updateIndicatorPosition(){
  indicatorMargin = tabsData[currentTab].marginLeft;
  indicator.style.marginLeft = indicatorMargin +'px';
}

function moveIndicator(){
  updateIndicatorWidth();
  updateIndicatorPosition();
}

function tabLink(event){
  if( changingTab ){ return; }

  changingTab = true;

  setTransition();
  tabsLinkArray[currentTab].classList.remove('active');
  currentTab = event.target.getAttribute('data-id');
  currentTranslate = currentTab*-100;
  setTranslationPercen( currentTranslate );
  tabsLinkArray[currentTab].classList.add('active');

  moveIndicator();

  changingTab = false;
}

function mouseUp(event) {

  sliding = false;

  setTransition();
  tabsLinkArray[currentTab].classList.remove('active');

  if ( moveToLeftView() ) {
    currentTab--;
    calcTranslation();
    setTranslationPercen( currentTranslate );

    var currentTabDistance = tabsLinkArray[ currentTab ].getBoundingClientRect();
      currentTabLeftDistance = currentTabDistance.left;

    if( currentTabLeftDistance < 0 ){
      tabsLink.scrollLeft = tabsLink.scrollLeft + currentTabLeftDistance;
    }else if ( currentTabDistance.right > tabsLink.clientWidth ){
      tabsLink.scrollLeft = currentTabDistance.right - tabsLink.clientWidth;
    }

  } else if ( moveToRightView() ) {
    currentTab++;
    calcTranslation();
    setTranslationPercen( currentTranslate );

    var currentTabDistance = tabsLinkArray[ currentTab ].getBoundingClientRect(),
      currentTabRightDistance = currentTabDistance.right;

    if( tabsLink.clientWidth < currentTabRightDistance ){
      tabsLink.scrollLeft = tabsLink.scrollLeft + currentTabRightDistance - tabsLink.clientWidth;
    }else if( currentTabRightDistance < 0 ){
      tabsLink.scrollLeft = tabsLink.scrollLeft + currentTabDistance.left;
    }

  } else if ( leftLimit() ) {
    setTranslationPercen( startTranslate );

  } else if ( rightLimit() ) {
    setTranslationPercen( endTranslate );

  } else {
    setTranslationPercen( currentTranslate );
  }

  tabsLinkArray[currentTab].classList.add('active');
  moveIndicator();

}

function mouseDown(event) {
  sliding = true;
  startPosition = event.touches[0].clientX;
}

function mouseMove(event){

  if (!sliding) {
    return;
  }
  endPosition = event.touches[0].clientX;

  removeTransition();

  if ( toRight( event ) ) {
    setTranslation( "calc( " + (event.touches[0].clientX - touchOffset - startPosition) + "px + " + currentTranslate + "% )" );
    //indicator.style.marginLeft = indicatorMargin + (event.touches[0].clientX - touchOffset - startPosition) +'px';

    var vistaRespectoPantalla = containerWdith / (event.touches[0].clientX - touchOffset - startPosition);

    var currentTab = {
      id: 0,
      width: tabsLinkArray[0].clientWidth,
      marginLeft: Math.floor(tabsLinkArray[0].clientWidth/2 + tabsLinkArray[0].getBoundingClientRect().left + tabsLink.scrollLeft)
    }

    var auxWidth = nextTab.marginLeft - currentTab.marginLeft;
    var newPos = auxWidth / vistaRespectoPantalla;
    indicator.style.marginLeft = indicatorMargin - newPos +'px';

  } else if ( toLeft( event ) ) {
    setTranslation( "calc( " + currentTranslate + "% - " + (startPosition - event.touches[0].clientX - touchOffset) + "px)" );

    var vistaRespectoPantalla = containerWdith / (startPosition - event.touches[0].clientX - touchOffset);

    var currentTab = {
      id: 0,
      width: tabsLinkArray[0].clientWidth,
      marginLeft: Math.floor(tabsLinkArray[0].clientWidth/2 + tabsLinkArray[0].getBoundingClientRect().left + tabsLink.scrollLeft)
    }

    var auxWidth = nextTab.marginLeft - currentTab.marginLeft;
    var newPos = auxWidth / vistaRespectoPantalla;
    indicator.style.marginLeft = indicatorMargin + newPos +'px';

    //indicator.style.transform =  "scaleX(" + Math.floor(tabsLinkArray[0].clientWidth - newPos) + ")";
    //console.log( tabsLinkArray[0].clientWidth - Math.floor(newPos) );
    /*var repectoAnchuras = currentTab.width / nextTab.width;
    indicator.style.transform =  "scaleX(" + currentTranslateIndicator - Math.floor(repectoAnchuras) + ")";
    currentTranslateIndicator = currentTranslateIndicator - Math.floor(repectoAnchuras);
    console.log(currentTranslateIndicator);*/

  }

}

function setTranslation( translation ){
  tabs.style.transform = "translateX(" + translation + ")";
}

function setTranslationPercen( translation ){
  setTranslation( translation+'%' );
}

function setTransition(){
  tabs.style.transition = "transform 0.4s ease-out";
}

function removeTransition(){
  tabs.style.transition = "";
}

function toLeft(event){
  return event.touches[0].clientX < startPosition - touchOffset;
}

function toRight(event){
  return event.touches[0].clientX > startPosition + touchOffset;
}

function leftLimit(){
  return currentTranslate === startTranslate;
}

function rightLimit(){
  return currentTranslate === endTranslate;
}

function moveToRightView(){
  return startPosition > endPosition&&
    startPosition - endPosition > distanceToChangeView &&
    !rightLimit();
}

function moveToLeftView(){
  return endPosition > startPosition &&
    endPosition - startPosition > distanceToChangeView &&
    !leftLimit();
}

function calcTranslation(){
  currentTranslate = currentTab * -100;
}

}

})(window);<|endoftext|>


<commit_before>var confWindow = args.getParam(0);
confWindow.window('stylesheet', 'usr/share/css/gconf/categories/softwarerepositories.css').window('dialog', true);

Webos.require('/usr/lib/apt/apt.js', function() {
	var selectedRepo = null;

	var content = $.w.container().addClass('softwarerepositories').appendTo(confWindow.window('content'));

	var repositoriesList = $.w.list(['Name', 'URL', 'Maintainer']).appendTo(content);

	var addButton = $.w.button('Add a repository...').click(function() {
		var addRepositoryWindow = $.w.window.dialog({
			title: 'Add a repository',
			parentWindow: confWindow
		});

		var form = $.w.entryContainer().appendTo(addRepositoryWindow.window('content'));

		var sourceEntry = $.w.textEntry('Repository URL: ').appendTo(form);
		var nameEntry = $.w.textEntry('Repository name: ').appendTo(form);

		var buttonContainer = $.w.buttonContainer().appendTo(form);
		$.w.button('Cancel').click(function() {
			addRepositoryWindow.window('close');
		}).appendTo(buttonContainer);
		$.w.button('Add', true).appendTo(buttonContainer);

		form.submit(function() {
			var repoData = {
				name: nameEntry.textEntry('value'),
				url: sourceEntry.textEntry('value')
			};

			addRepositoryWindow.window('close');
			confWindow.window('loading', true);

			Webos.Confiture.Package.insertRepository(repoData, [function() {
				confWindow.window('loading', false);
				confirmPackageUpdate();
			}, function(res) {
				confWindow.window('loading', false);
				res.triggerError();
			}]);
		});

		addRepositoryWindow.window('open');
	});
	repositoriesList.list('addButton', addButton);
	var removeButton = $.w.button('Remove').click(function() {
		if (!selectedRepo) {
			return;
		}

		confWindow.window('loading', true);

		Webos.Confiture.Package.deleteRepository(selectedRepo.name, [function() {
			selectedRepo.element.remove();
			confWindow.window('loading', false);
			confirmPackageUpdate();
		}, function(res) {
			confWindow.window('loading', false);
			res.triggerError();
		}]);
	});
	repositoriesList.list('addButton', removeButton);

	var displayRepositoriesFn = function() {
		repositoriesList.list('content').empty();
		removeButton.button('disabled', true);

		confWindow.window('loading', true);

		Webos.Confiture.Package.listRepositories([function(repos) {
			confWindow.window('loading', false);

			for (var i in repos) {
				(function(repoData) {
					var item = $.w.listItem([''+repoData.name+'', repoData.url, '-']);

					item.bind('listitemselect', function() {
						selectedRepo = repoData;
						selectedRepo.element = item;
						removeButton.button('disabled', false);
					}).bind('listitemunselect', function() {
						selectedRepo = null;
						removeButton.button('disabled', true);
					});

					item.appendTo(repositoriesList.list('content'));
				})(repos[i]);
			}
		}, function(res) {
			confWindow.window('loading', false);
			res.triggerError();
		}]);
	};

	var confirmPackageUpdate = function() {
		var confirmWindow = $.webos.window.confirm({
			title: 'Update cache',
			label: 'Les informations sur les paquets sont obsolètes. Voulez-vous mettre à jour ces informations maintenant ?',
			parentWindow: confWindow,
			confirm: function() {
				var loadingWindow = $.w.window.dialog({
					title: 'Updating cache...',
					resizable : false,
					closeable: false,
					parentWindow: confWindow
				});

				loadingWindowContent = loadingWindow.window('content');

				$.w.image(new W.Icon('actions/update')).css('float', 'left').appendTo(loadingWindowContent);
				$('').html('Mise à jour du cache').appendTo(loadingWindowContent);
				$.w.label('Le cache est en cours de mise à jour, veuillez patienter quelques instants...').appendTo(loadingWindowContent);

				loadingWindow.window('open');

				Webos.Confiture.Package.updateCache([function(response) {
					loadingWindow.window('close');
					confWindow.window('loading', false);
					displayRepositoriesFn();
				}, function(response) {
					loadingWindow.window('close');
					confWindow.window('loading', false);
					response.triggerError();
				}]);
			},
			confirmLabel: 'Update cache',
			cancelLabel: 'Later'
		});
		confirmWindow.window('open');
	};

	displayRepositoriesFn();
});<commit_msg>Adds a missing lib required by software repositories in gconf.<commit_after>var confWindow = args.getParam(0);
confWindow
	.window('stylesheet', '/usr/share/css/gconf/categories/softwarerepositories.css')
	.window('dialog', true);

Webos.require([
	'/usr/lib/apt/apt.js',
	'/usr/lib/confiture/webos.js'
], function() {
	var selectedRepo = null;

	var content = $.w.container().addClass('softwarerepositories').appendTo(confWindow.window('content'));

	var repositoriesList = $.w.list(['Name', 'URL', 'Maintainer']).appendTo(content);

	var addButton = $.w.button('Add a repository...').click(function() {
		var addRepositoryWindow = $.w.window.dialog({
			title: 'Add a repository',
			parentWindow: confWindow
		});

		var form = $.w.entryContainer().appendTo(addRepositoryWindow.window('content'));

		var sourceEntry = $.w.textEntry('Repository URL: ').appendTo(form);
		var nameEntry = $.w.textEntry('Repository name: ').appendTo(form);

		var buttonContainer = $.w.buttonContainer().appendTo(form);
		$.w.button('Cancel').click(function() {
			addRepositoryWindow.window('close');
		}).appendTo(buttonContainer);
		$.w.button('Add', true).appendTo(buttonContainer);

		form.submit(function() {
			var repoData = {
				name: nameEntry.textEntry('value'),
				url: sourceEntry.textEntry('value')
			};

			addRepositoryWindow.window('close');
			confWindow.window('loading', true);

			Webos.Confiture.Package.insertRepository(repoData, [function() {
				confWindow.window('loading', false);
				confirmPackageUpdate();
			}, function(res) {
				confWindow.window('loading', false);
				res.triggerError();
			}]);
		});

		addRepositoryWindow.window('open');
	});
	repositoriesList.list('addButton', addButton);
	var removeButton = $.w.button('Remove').click(function() {
		if (!selectedRepo) {
			return;
		}

		confWindow.window('loading', true);

		Webos.Confiture.Package.deleteRepository(selectedRepo.name, [function() {
			selectedRepo.element.remove();
			confWindow.window('loading', false);
			confirmPackageUpdate();
		}, function(res) {
			confWindow.window('loading', false);
			res.triggerError();
		}]);
	});
	repositoriesList.list('addButton', removeButton);

	var displayRepositoriesFn = function() {
		repositoriesList.list('content').empty();
		removeButton.button('disabled', true);

		confWindow.window('loading', true);

		Webos.Confiture.Package.listRepositories([function(repos) {
			confWindow.window('loading', false);

			for (var i in repos) {
				(function(repoData) {
					var item = $.w.listItem([''+repoData.name+'', repoData.url, '-']);

					item.bind('listitemselect', function() {
						selectedRepo = repoData;
						selectedRepo.element = item;
						removeButton.button('disabled', false);
					}).bind('listitemunselect', function() {
						selectedRepo = null;
						removeButton.button('disabled', true);
					});

					item.appendTo(repositoriesList.list('content'));
				})(repos[i]);
			}
		}, function(res) {
			confWindow.window('loading', false);
			res.triggerError();
		}]);
	};

	var confirmPackageUpdate = function() {
		var confirmWindow = $.webos.window.confirm({
			title: 'Update cache',
			label: 'Les informations sur les paquets sont obsolètes. Voulez-vous mettre à jour ces informations maintenant ?',
			parentWindow: confWindow,
			confirm: function() {
				var loadingWindow = $.w.window.dialog({
					title: 'Updating cache...',
					resizable : false,
					closeable: false,
					parentWindow: confWindow
				});

				loadingWindowContent = loadingWindow.window('content');

				$.w.image(new W.Icon('actions/update')).css('float', 'left').appendTo(loadingWindowContent);
				$('').html('Mise à jour du cache').appendTo(loadingWindowContent);
				$.w.label('Le cache est en cours de mise à jour, veuillez patienter quelques instants...').appendTo(loadingWindowContent);

				loadingWindow.window('open');

				Webos.Confiture.Package.updateCache([function(response) {
					loadingWindow.window('close');
					confWindow.window('loading', false);
					displayRepositoriesFn();
				}, function(response) {
					loadingWindow.window('close');
					confWindow.window('loading', false);
					response.triggerError();
				}]);
			},
			confirmLabel: 'Update cache',
			cancelLabel: 'Later'
		});
		confirmWindow.window('open');
	};

	displayRepositoriesFn();
});<|endoftext|>


<commit_before>#!/usr/bin/env node

/*
 *  Copyright 2012 Research In Motion Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var path = require("path"),
    exit = require("exit"),
    command = require("commander"),
    os = require("os"),
    utils = require("./utils"),
    signingHelper = require("./signing-helper"),
    bbProperties = utils.getProperties(),
    bbwpArgv = [
        process.argv[0],
        path.resolve(path.join(__dirname, process.argv[1])),
        path.resolve(path.join(__dirname, "..", "..", "www")),
        "-o",
        path.resolve(path.join(__dirname, "..", "..", "build"))
    ],
    async = require("async"),
    childProcess = require("child_process"),
    pkgrUtils = require("./packager-utils"),
    session = require("./session"),
    ERROR_VALUE = 2,
    commandStr;

function copyArgIfExists(arg) {
    if (command[arg]) {
        bbwpArgv.push("--" + arg);
        bbwpArgv.push(command[arg]);
    }
}

command
    .usage('[--debug | --release] [--query] [-k | --keystorepass] [-b <number> | --buildId <number>] [-p <json> | --params <json>] [-ll <level> | --loglevel <level>] [--web-inspector] [--no-signing]')
    .option('--debug', 'build in debug mode.')
    .option('--release', 'build in release mode. This will sign the resulting bar.')
    .option('--query', 'query on the commandline when a password is needed')
    .option('-k, --keystorepass <password>', 'signing key password')
    .option('-b, --buildId <num>', 'specifies the build number for signing (typically incremented from previous signing).')
    .option('-p, --params <params JSON file>', 'specifies additional parameters to pass to downstream tools.')
    .option('-ll, --loglevel <loglevel>', 'set the logging level (error, warn, verbose)')
    .option('--web-inspector', 'enables webinspector. Enabled by default in debug mode.).')
    .option('--no-signing', 'when building in release mode, this will skip signing');

try {
    command.parse(process.argv);

    if (command.debug && command.release) {
        console.error("Invalid build command: cannot specify both debug and release parameters.");
        console.log(command.helpInformation());
        exit(ERROR_VALUE);
    }

    signingHelper.warn();

    utils.series(
        [
            function clean(done) {
                var cmd = utils.isWindows() ? "clean" : "./clean",
                    args = [],
                    opts = { "cwd": path.normalize(__dirname + "/..") };

                utils.exec(cmd, args, opts, done);
            },
            function releaseBuild(allDone) {
                var childTasks = [],
                    keystorepass = session.getKeyStorePass(command),
                    err;

                if (command.release) {
                    copyArgIfExists("buildId");
                    if (command.signing) {
                        //Note: Packager refers to signing password as "password" not "keystorepass"
                        bbwpArgv.push("--password");
                        if (keystorepass) {
                            bbwpArgv.push(keystorepass);
                        } else if (command.query) {
                            childTasks.push(utils.prompt.bind(this, {description: "Please enter your keystore password: ", hidden: true}));
                            childTasks.push(function (password, done) {
                                bbwpArgv.push(password);
                                done();
                            });
                        } else {
                            err = "No signing password provided. Please enter a value for 'keystorepass' in " + pkgrUtils.homedir() + "/.cordova/blackberry10.json or use --keystorepass via command-line";
                        }
                    }
                }

                async.waterfall(childTasks, function (error) { allDone(error || err); });
            },
            function build(done) {
                //enable webinspector in debug mode or if --webinspector was provided
                if (!command.release || command.webInspector) {
                    bbwpArgv.push("-d");
                }

                copyArgIfExists("params");
                copyArgIfExists("loglevel");

                //Overwrite process.argv, before calling packager
                process.argv = bbwpArgv;

                //Delete cached commander object. It will conflict with the packagers commander
                delete require.cache[require.resolve("commander")];
                delete require.cache[require.resolve("commander/lib/commander")];

                require("./packager").start(done);
            }
        ]
    );
} catch (e) {
    console.error(os.EOL + e);
    exit(ERROR_VALUE);
}

<commit_msg>CB-5723 Change build script -ll param to -l<commit_after>#!/usr/bin/env node

/*
 *  Copyright 2012 Research In Motion Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var path = require("path"),
    exit = require("exit"),
    command = require("commander"),
    os = require("os"),
    utils = require("./utils"),
    signingHelper = require("./signing-helper"),
    bbProperties = utils.getProperties(),
    bbwpArgv = [
        process.argv[0],
        path.resolve(path.join(__dirname, process.argv[1])),
        path.resolve(path.join(__dirname, "..", "..", "www")),
        "-o",
        path.resolve(path.join(__dirname, "..", "..", "build"))
    ],
    async = require("async"),
    childProcess = require("child_process"),
    pkgrUtils = require("./packager-utils"),
    session = require("./session"),
    ERROR_VALUE = 2,
    commandStr;

function copyArgIfExists(arg) {
    if (command[arg]) {
        bbwpArgv.push("--" + arg);
        bbwpArgv.push(command[arg]);
    }
}

command
    .usage('[--debug | --release] [--query] [-k | --keystorepass] [-b <number> | --buildId <number>] [-p <json> | --params <json>] [-ll <level> | --loglevel <level>] [--web-inspector] [--no-signing]')
    .option('--debug', 'build in debug mode.')
    .option('--release', 'build in release mode. This will sign the resulting bar.')
    .option('--query', 'query on the commandline when a password is needed')
    .option('-k, --keystorepass <password>', 'signing key password')
    .option('-b, --buildId <num>', 'specifies the build number for signing (typically incremented from previous signing).')
    .option('-p, --params <params JSON file>', 'specifies additional parameters to pass to downstream tools.')
    .option('-l, --loglevel <loglevel>', 'set the logging level (error, warn, verbose)')
    .option('--web-inspector', 'enables webinspector. Enabled by default in debug mode.).')
    .option('--no-signing', 'when building in release mode, this will skip signing');

try {
    command.parse(process.argv);

    if (command.debug && command.release) {
        console.error("Invalid build command: cannot specify both debug and release parameters.");
        console.log(command.helpInformation());
        exit(ERROR_VALUE);
    }

    signingHelper.warn();

    utils.series(
        [
            function clean(done) {
                var cmd = utils.isWindows() ? "clean" : "./clean",
                    args = [],
                    opts = { "cwd": path.normalize(__dirname + "/..") };

                utils.exec(cmd, args, opts, done);
            },
            function releaseBuild(allDone) {
                var childTasks = [],
                    keystorepass = session.getKeyStorePass(command),
                    err;

                if (command.release) {
                    copyArgIfExists("buildId");
                    if (command.signing) {
                        //Note: Packager refers to signing password as "password" not "keystorepass"
                        bbwpArgv.push("--password");
                        if (keystorepass) {
                            bbwpArgv.push(keystorepass);
                        } else if (command.query) {
                            childTasks.push(utils.prompt.bind(this, {description: "Please enter your keystore password: ", hidden: true}));
                            childTasks.push(function (password, done) {
                                bbwpArgv.push(password);
                                done();
                            });
                        } else {
                            err = "No signing password provided. Please enter a value for 'keystorepass' in " + pkgrUtils.homedir() + "/.cordova/blackberry10.json or use --keystorepass via command-line";
                        }
                    }
                }

                async.waterfall(childTasks, function (error) { allDone(error || err); });
            },
            function build(done) {
                //enable webinspector in debug mode or if --webinspector was provided
                if (!command.release || command.webInspector) {
                    bbwpArgv.push("-d");
                }

                copyArgIfExists("params");
                copyArgIfExists("loglevel");

                //Overwrite process.argv, before calling packager
                process.argv = bbwpArgv;

                //Delete cached commander object. It will conflict with the packagers commander
                delete require.cache[require.resolve("commander")];
                delete require.cache[require.resolve("commander/lib/commander")];

                require("./packager").start(done);
            }
        ]
    );
} catch (e) {
    console.error(os.EOL + e);
    exit(ERROR_VALUE);
}

<|endoftext|>


<commit_before>/*
 * grunt-card
 * https://github.com/sdicgdev/grunt-card
 *
 * Copyright (c) 2014 Evan Short
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt, exec) {
	require('load-grunt-tasks')(grunt);

	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		gittag: {
			release:{
				options:{
					tag: '',
					message: ''
				}
			}
		},
		gitpush: {
			release:{
			},
			releaseTags:{
				options:{
					tags: true
				}
			}
		},
		gitcommit: {
			describe: {
				files: {
					src: ['etc/branch_description.json']
				},
				options:{
					message: 'describing the current branch'
				}
			}
			, release: {
				files: {
					src: ['package.json', 'bower.json']
				},
				options:{
					message: 'updating version numbers'
				}
			}
		},
		gitcheckout: {
			branch: {
				options: {
					create: true
				}
			},
			dev: {
				options: {
					branch: 'dev'
				}
			},
			deploy: {
				options: {
					create: false
				}
			}
		},
		gitpull: {
			dev: {
				options: {
					branch: 'dev'
				}
			}
		},
		gitmerge: {
		},
		prompt: {
			startCard: {
				options: {
					questions: [
						{
							config:   'cardDescription',
							type:     'input',
							message:  "What are you working on?"
						},
						{
							config: 'cardType',
							type: 'list',
							message: "What kind of card is it?",
							default: 'feature',
							choices: ['feature', 'bug', 'operations', 'design', 'other']
						}
					]
				}
			},
		}
	});

	grunt.registerTask('card', 'start a new card', [
		'prompt:startCard'     // ask what the user is working on
		, 'gitcheckout:dev'    // check out dev
		, 'gitpull:dev'        // pull dev
		, 'card:start'         // perform git operations to begin a new card
		, 'gitcheckout:branch' // check out the branch
		, 'card:describe'      // create file in repo to describe the current branch
		, 'gitcommit:describe' // commit description to new branch
	]);

	grunt.registerTask('card:submit', 'submit what you are working on for review',
		[ 'branch:note'
		, 'gitcheckout:dev' // check out dev
		, 'gitpull:dev' // pull dev
		, 'branch:review' // merge in the random branch
		, 'gitcheckout:branch'
		, 'gitmerge'
	]);

	grunt.registerTask('card:describe', 'create file in repo to describe the current branch', function(){
		var branchDescription =
		    	{ title: grunt.config('cardDescription')
		    	, type: grunt.config('cardType')
		    	}

		grunt.file.write('./etc/branch_description.json', JSON.stringify(branchDescription , null, "\t"))
	});

	grunt.registerTask('card:start', 'perform git operations to begin a new card', function(){
		// start and check out a new branch whose name is based on user's answer
		var branchTitle = grunt.config('cardDescription')
		    , branchType  = grunt.config('cardType');

		// set the branch title
		grunt.config.set('gitcheckout.branch.options.branch', makeBranchName(branchType, branchTitle));
	});

	grunt.registerTask('branch', 'create and merge random branches to and from dev', function(merge){
		var branch = grunt.file.readJSON('./etc/branch_description.json');;
		switch(merge){
			case 'note':
				grunt.config.set('gitmerge.options.branch', makeBranchName(branch.type, branch.title));
			case 'review':
				grunt.config.set('gitcheckout.branch.options.branch', makeBranchName('review', branch.title, branch.type));
				break;
			default:
				break;
		}
	});

		// pull
		//
		// check out dev
		//
		// pull
		//
		// if not on submit branch
		//  - check out new review branch based on original branch's name
		//  - merge branch user was on into new branch
		//  - if no errors, push to origin
		//
		// if on submit branch
		//  - pull
		//  - commit with message "correcting conflicts" if there is anything to commit
		//  - if no errors, push to origin
		//
		// if errors, tell user to correct conflicts and submit again

	grunt.registerTask('card:review', 'review a branch for submission', function() {
		// user selects branch to review from list of available branches
		//
		// checkout selected branch
		//
		// pull
		//
		// checkout dev
		//
		// pull
		//
		// create new review branch
		//
		// merge selected branch
		//
		// if no errors, tell user to have at it
		//
		// if errors, tell user to either correct conflicts or reject
	});

	grunt.registerTask('card:reject', 'send a branch back for more work', function() {
		// move review branch to holding branch for corrections
		//
		// delete review branch
	});

	grunt.registerTask('card:approve', 'send a branch back for more work', function() {
		// check that on review branch
		//
		// pull
		//
		// checkout dev
		//
		// pull
		//
		// make approval branch
		//
		// merge in review branch
		//
		// if no errors
		//  - co dev and merge in approval branch
		//  - tag branch
		//  - delete approval branch
		//  - delete review branch
		//
		// if errors
		//  - tell user about errors
		//  - allow them to fix and re-approve
		//  - allow them to reject
		//
	});

	grunt.registerTask('card:log', 'see history of approved cards', function(){
		// show changelog of approved cards
	});

};

function camelCaseSentence(input){
	input = input.split(" ");

	input.forEach(function(item, k, ray){
		ray[k] = item.charAt(0).toUpperCase() + item.substring(1);
	});

	return input.join("");
}

function makeBranchName(type, title, descriptor){
	var result = type+"_"+camelCaseSentence(title);
	if(descriptor){
		result += "_"+descriptor;
	}
	return result;
}
<commit_msg>separating where branch info comes from for noting branch vs reviewing branch<commit_after>/*
 * grunt-card
 * https://github.com/sdicgdev/grunt-card
 *
 * Copyright (c) 2014 Evan Short
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt, exec) {
	require('load-grunt-tasks')(grunt);

	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		gittag: {
			release:{
				options:{
					tag: '',
					message: ''
				}
			}
		},
		gitpush: {
			release:{
			},
			releaseTags:{
				options:{
					tags: true
				}
			}
		},
		gitcommit: {
			describe: {
				files: {
					src: ['etc/branch_description.json']
				},
				options:{
					message: 'describing the current branch'
				}
			}
			, release: {
				files: {
					src: ['package.json', 'bower.json']
				},
				options:{
					message: 'updating version numbers'
				}
			}
		},
		gitcheckout: {
			branch: {
				options: {
					create: true
				}
			},
			dev: {
				options: {
					branch: 'dev'
				}
			},
			deploy: {
				options: {
					create: false
				}
			}
		},
		gitpull: {
			dev: {
				options: {
					branch: 'dev'
				}
			}
		},
		gitmerge: {
		},
		prompt: {
			startCard: {
				options: {
					questions: [
						{
							config:   'cardDescription',
							type:     'input',
							message:  "What are you working on?"
						},
						{
							config: 'cardType',
							type: 'list',
							message: "What kind of card is it?",
							default: 'feature',
							choices: ['feature', 'bug', 'operations', 'design', 'other']
						}
					]
				}
			},
		}
	});

	grunt.registerTask('card', 'start a new card', [
		'prompt:startCard'     // ask what the user is working on
		, 'gitcheckout:dev'    // check out dev
		, 'gitpull:dev'        // pull dev
		, 'card:start'         // perform git operations to begin a new card
		, 'gitcheckout:branch' // check out the branch
		, 'card:describe'      // create file in repo to describe the current branch
		, 'gitcommit:describe' // commit description to new branch
	]);

	grunt.registerTask('card:submit', 'submit what you are working on for review',
		[ 'branch:note'
		, 'gitcheckout:dev' // check out dev
		, 'gitpull:dev' // pull dev
		, 'branch:review' // merge in the random branch
		, 'gitcheckout:branch'
		, 'gitmerge'
	]);

	grunt.registerTask('card:describe', 'create file in repo to describe the current branch', function(){
		var branchDescription =
		    	{ title: grunt.config('cardDescription')
		    	, type: grunt.config('cardType')
		    	}

		grunt.file.write('./etc/branch_description.json', JSON.stringify(branchDescription , null, "\t"))
	});

	grunt.registerTask('card:start', 'perform git operations to begin a new card', function(){
		// start and check out a new branch whose name is based on user's answer
		var branchTitle = grunt.config('cardDescription')
		    , branchType  = grunt.config('cardType');

		// set the branch title
		grunt.config.set('gitcheckout.branch.options.branch', makeBranchName(branchType, branchTitle));
	});

	grunt.registerTask('branch', 'create and merge random branches to and from dev', function(merge){
		var branch
		switch(merge){
			case 'note':
				branch = grunt.file.readJSON('./etc/branch_description.json');;
				grunt.config.set('branchInfo', branch);;
				grunt.config.set('gitmerge.options.branch', makeBranchName(branch.type, branch.title));
				break;
			case 'review':
				branch = grunt.config('branchInfo');;
				grunt.config.set('gitcheckout.branch.options.branch', makeBranchName('review', branch.title, branch.type));
				break;
			default:
				break;
		}
	});

		// pull
		//
		// check out dev
		//
		// pull
		//
		// if not on submit branch
		//  - check out new review branch based on original branch's name
		//  - merge branch user was on into new branch
		//  - if no errors, push to origin
		//
		// if on submit branch
		//  - pull
		//  - commit with message "correcting conflicts" if there is anything to commit
		//  - if no errors, push to origin
		//
		// if errors, tell user to correct conflicts and submit again

	grunt.registerTask('card:review', 'review a branch for submission', function() {
		// user selects branch to review from list of available branches
		//
		// checkout selected branch
		//
		// pull
		//
		// checkout dev
		//
		// pull
		//
		// create new review branch
		//
		// merge selected branch
		//
		// if no errors, tell user to have at it
		//
		// if errors, tell user to either correct conflicts or reject
	});

	grunt.registerTask('card:reject', 'send a branch back for more work', function() {
		// move review branch to holding branch for corrections
		//
		// delete review branch
	});

	grunt.registerTask('card:approve', 'send a branch back for more work', function() {
		// check that on review branch
		//
		// pull
		//
		// checkout dev
		//
		// pull
		//
		// make approval branch
		//
		// merge in review branch
		//
		// if no errors
		//  - co dev and merge in approval branch
		//  - tag branch
		//  - delete approval branch
		//  - delete review branch
		//
		// if errors
		//  - tell user about errors
		//  - allow them to fix and re-approve
		//  - allow them to reject
		//
	});

	grunt.registerTask('card:log', 'see history of approved cards', function(){
		// show changelog of approved cards
	});

};

function camelCaseSentence(input){
	input = input.split(" ");

	input.forEach(function(item, k, ray){
		ray[k] = item.charAt(0).toUpperCase() + item.substring(1);
	});

	return input.join("");
}

function makeBranchName(type, title, descriptor){
	var result = type+"_"+camelCaseSentence(title);
	if(descriptor){
		result += "_"+descriptor;
	}
	return result;
}
<|endoftext|>


<commit_before>/*
 * grunt-groc
 * https://github.com/jdcataldo/grunt-groc
 *
 * Copyright (c) 2013 Justin Cataldo
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {
  var groc = require("groc").CLI,
      util    = grunt.util || grunt.utils,
      // Alias for Lo-Dash
      _       = util._;

  grunt.registerMultiTask('groc', 'Generate documenation using groc', function() {
    // Merge options
    var options = this.options ? this.options() : this.data.options,
        files   = this.filesSrc || this.data.src,
        // Set task as async
        done    = this.async(),
        // Array of arguments to pass into groc
        args    = [];

    // Add the files to the arguments
    args.push(files);
    // Loop through the options and add them to args
    _.each(options, function(value, key) {
      // Convert to the key to a switch
      var sw = (key.length > 1 ? '--' : '-') + key;
      // Add the switch and its value
      args.push([sw, value.toString()]);
    });

    // Pass the args to groc
    groc(_.flatten(args), function(error){
      if(error) {
        grunt.warn(error);
        process.exit(1);
        done(false);
        return;
      }
      done();
    });
  });
};<commit_msg>allowed array values in options<commit_after>/*
 * grunt-groc
 * https://github.com/jdcataldo/grunt-groc
 *
 * Copyright (c) 2013 Justin Cataldo
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {
  var groc = require("groc").CLI,
      util    = grunt.util || grunt.utils,
      // Alias for Lo-Dash
      _       = util._;

  grunt.registerMultiTask('groc', 'Generate documenation using groc', function() {
    // Merge options
    var options = this.options ? this.options() : this.data.options,
        files   = this.filesSrc || this.data.src,
        // Set task as async
        done    = this.async(),
        // Array of arguments to pass into groc
        args    = [];

    // Add the files to the arguments
    args.push(files);
    // Loop through the options and add them to args
    _.each(options, function(value, key) {
      // Convert to the key to a switch
      var sw = (key.length > 1 ? '--' : '-') + key;
      // Add the switch and its value
      // If the value is an array, add all array elements to the array.
      if(!_.isArray(value)) {
        value = [value];
      }

      _.each(value, function(value) {
        args.push([sw, value.toString()]);
      });
    });

    // Pass the args to groc
    groc(_.flatten(args), function(error){
      if(error) {
        grunt.warn(error);
        process.exit(1);
        done(false);
        return;
      }
      done();
    });
  });
};<|endoftext|>


<commit_before>document.getElementById("id_logic_level_version").innerHTML="Business level version 2017.11.15.2";

var canvas = document.getElementById("id_canvas");
var context = canvas.getContext("2d");
var rect_canvas = canvas.getBoundingClientRect();
var img = document.getElementById("id_img");
img.onload = function() {

	context.drawImage(img, 100, 100, 100, 100);
	var rect_img = img.getBoundingClientRect();
}

canvas.addEventListener("touchmove", on_touch_move);

//-------------------------------------------------------------
function on_touch_move(e)
{
	e.preventDefault();
	var touches = e.changedTouches;
	for (var i=0; i < touches.length; i++)
	{

	}
}
//---------------------------------------------------------<commit_msg>Move Image<commit_after>document.getElementById("id_logic_level_version").innerHTML="Business level version 2017.11.22.0";

var canvas = document.getElementById("id_canvas");
var context = canvas.getContext("2d");
var rect_canvas = canvas.getBoundingClientRect();
var img = document.getElementById("id_img");

var top_x = 100;
var top_y = 100;

var img_width = 100;
var img_height = 100;

img.onload = function() {

	context.drawImage(img, top_x, top_y, img_width, img_height);
	var rect_img = img.getBoundingClientRect();
}

canvas.addEventListener("touchmove", on_touch_move);

//-------------------------------------------------------------
function on_touch_move(e)
{
	e.preventDefault();
	var touches = e.changedTouches;
	for (var i=0; i < touches.length; i++)
	{
		if(touches[i].pageX < top_x + img_width && touches[i].pageX >= top_x &&
		  touches[i].pageY < top_y + img_height && touches[i].pageY >= top_y) {
			context.clearRect();
			top_x = touches[i].pageX - rect_canvas.left;
			top_y = touches[i].pageY - rect_canvas.top;
			context.drawImage(img, top_x, top_y, img_width, img_height);

		}
	}
}
//---------------------------------------------------------<|endoftext|>


<commit_before>define([], function () {
  'use strict';

	if (typeof String.prototype.endsWith !== 'function') {
    String.prototype.endsWith = function(suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
	}

	//使用require.js加载View类
	var loadViewClass = function(require, ViewClassName, success, fail){
		// var viewLoaded = require.defined(ViewClassName);
		require(ViewClassName, function(){
			success.call(arguments);
		}, fail);
	}

  //获取绑定，以及绑定语法糖
  function getBinding(el, contextPath){
    var bindingName = el.getAttribute('data-window') || el.getAttribute('data-view');
    bindingName = bindingName != null ? bindingName : '$view';

    //patch for '$'
    bindingName = bindingName.replace('$', 'butterfly/')

    //patch for '.' and empty value
    bindingName = (bindingName == '.' || bindingName == '') ? contextPath.replace('.html', '') : bindingName;

    return bindingName;
  }

  //TODO: 如果该html页面页面有两个根节点，例如div.header div.content，则自动创建一个包裹div，并自动赋予id
	var loadViewClassByEL = function(require, view, htmlTemplate, success, fail){
		//只要body内的类容
    //TODO: 目前带上了body标签，改为只要里面的东西
		htmlTemplate = (/<html/i.test(htmlTemplate)) ? htmlTemplate.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0] : htmlTemplate;
		//转换成DOM
		var el = document.createElement('div');
		el.innerHTML = htmlTemplate;
		el = el.firstElementChild;

		//el的绑定类，若没有，默认为最普通的View（框架定义的）
		var elementBinding = getBinding(el, view);

    //el子节点的绑定类集合
		var el_view_bindings = el.querySelectorAll('[data-view]');
		var view_names = _.map(el_view_bindings, function(node){
			return getBinding(node, view);
		});
		view_names.unshift(elementBinding);

		//加载el以及el的子节点的所有绑定类
		require(view_names, function(){

			var TopViewClass = arguments[0];

      //when this proxy class initialize called, the html element will assign to el
			var ProxyViewClass = TopViewClass.extend({

				template: htmlTemplate,

				initialize: function(){

					//转换成DOM
					var el = document.createElement('div');
					el.innerHTML = this.template;
					el = el.firstElementChild;
					//replace element
					this.setElement(el);

					//apply binding
					var me = this;
					_.chain(this.el.querySelectorAll('[data-view]'))
					.foldl(function(mapping, node){
						var binding = node.getAttribute('data-view').replace('$', 'butterfly/');
						if (binding && binding.length > 0) mapping[binding] = node;
						return mapping;
					}, {})
					.each(function(node, bindingName){
						var ViewClass = require(bindingName);
						//TODO: inject parent
						var view = new ViewClass({el: node});
						me.addSubview(view);
					});

					TopViewClass.prototype.initialize.call(this, arguments);
				}
			});

			success(ProxyViewClass);

		}, fail);
	}

	var loadViewClass = function(require, view, success, fail){
		var me = this;
		console.log('loadView: %s', view);
		if (typeof view == 'string' && view.endsWith('html')) {

			require(['text!'+view], function(template){
				loadViewClassByEL(require, view, template, success, fail);
			}, fail);

		} else if (typeof view == 'string') {
			require([view], success, fail);

		} else {
			throw new Error('view loader plugin require a view name of string type');
		}
	}

  var plugin = {
  	load: function(name, req, onLoad, config){
  		loadViewClass(req, name, function(View){
  			onLoad(View);

  		}, function(err){
  			onLoad.error(err);

  		});
  	},

    //for non-amd usage
    loadViewClass: loadViewClass,

    //for non-amd usage
    loadView: function(success, fail){

      loadViewClass(require, name, function(View){

        var view = new View();
        success(view);
      }, fail);
    }
  }

  return plugin;
});
<commit_msg>支持html有多个节点<commit_after>define([], function () {
  'use strict';

	if (typeof String.prototype.endsWith !== 'function') {
    String.prototype.endsWith = function(suffix) {
        return this.indexOf(suffix, this.length - suffix.length) !== -1;
    };
	}

	//使用require.js加载View类
	var loadViewClass = function(require, ViewClassName, success, fail){
		// var viewLoaded = require.defined(ViewClassName);
		require(ViewClassName, function(){
			success.call(arguments);
		}, fail);
	}

  //获取绑定，以及绑定语法糖
  function getBinding(el, contextPath){
    var bindingName = el.getAttribute('data-window') || el.getAttribute('data-view');
    bindingName = bindingName != null ? bindingName : '$view';

    //patch for '$'
    bindingName = bindingName.replace('$', 'butterfly/')

    //patch for '.' and empty value
    bindingName = (bindingName == '.' || bindingName == '') ? contextPath.replace('.html', '') : bindingName;

    return bindingName;
  }

  //TODO: 如果该html页面页面有两个根节点，例如div.header div.content，则自动创建一个包裹div，并自动赋予id
	var loadViewClassByEL = function(require, view, htmlTemplate, success, fail){
		//只要body内的类容
    //TODO: 目前带上了body标签，改为只要里面的东西
		htmlTemplate = (/<html/i.test(htmlTemplate)) ? htmlTemplate.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0] : htmlTemplate;
		//转换成DOM
		var el = document.createElement('div');
		el.innerHTML = htmlTemplate;
		el = el.childElementCount == 1 ? el.firstElementChild : el;

		//el的绑定类，若没有，默认为最普通的View（框架定义的）
		var elementBinding = getBinding(el, view);

    //el子节点的绑定类集合
		var el_view_bindings = el.querySelectorAll('[data-view]');
		var view_names = _.map(el_view_bindings, function(node){
			return getBinding(node, view);
		});
		view_names.unshift(elementBinding);

		//加载el以及el的子节点的所有绑定类
		require(view_names, function(){

			var TopViewClass = arguments[0];

      //when this proxy class initialize called, the html element will assign to el
			var ProxyViewClass = TopViewClass.extend({

				template: htmlTemplate,

				initialize: function(){

					//转换成DOM
					var el = document.createElement('div');
					el.innerHTML = this.template;
					el = el.childElementCount == 1 ? el.firstElementChild : el;
					//replace element
					this.setElement(el);

					//apply binding
					var me = this;
					_.chain(this.el.querySelectorAll('[data-view]'))
					.foldl(function(mapping, node){
						var binding = node.getAttribute('data-view').replace('$', 'butterfly/');
						if (binding && binding.length > 0) mapping[binding] = node;
						return mapping;
					}, {})
					.each(function(node, bindingName){
						var ViewClass = require(bindingName);
						//TODO: inject parent
						var view = new ViewClass({el: node});
						me.addSubview(view);
					});

					TopViewClass.prototype.initialize.call(this, arguments);
				}
			});

			success(ProxyViewClass);

		}, fail);
	}

	var loadViewClass = function(require, view, success, fail){
		var me = this;
		console.log('loadView: %s', view);
		if (typeof view == 'string' && view.endsWith('html')) {

			require(['text!'+view], function(template){
				loadViewClassByEL(require, view, template, success, fail);
			}, fail);

		} else if (typeof view == 'string') {
			require([view], success, fail);

		} else {
			throw new Error('view loader plugin require a view name of string type');
		}
	}

  var plugin = {
  	load: function(name, req, onLoad, config){
  		loadViewClass(req, name, function(View){
  			onLoad(View);

  		}, function(err){
  			onLoad.error(err);

  		});
  	},

    //for non-amd usage
    loadViewClass: loadViewClass,

    //for non-amd usage
    loadView: function(success, fail){

      loadViewClass(require, name, function(View){

        var view = new View();
        success(view);
      }, fail);
    }
  }

  return plugin;
});
<|endoftext|>


<commit_before>'use strict'

const fs = require('fs')
const gulp = require('gulp')
const lessModule = require('less')
const less = require('gulp-less')
const sourcemaps = require('gulp-sourcemaps')
const rename = require('gulp-rename')
const mkdirp = require('mkdirp')

const postcss = require('gulp-postcss')
const autoprefixer = require('autoprefixer')

const config = require('../config').less

const errorHandler = require('../util/error-handler')

lessModule.functions.functionRegistry.addMultiple(config.functions)

const processors = [
  autoprefixer(),
]

if (process.env.NODE_ENV === 'production') {
  const csswring = require('csswring')

  processors.push(csswring())
}

gulp.task('less', () => {
  mkdirp(config.dest)

  if (config.suffix) {
    fs.writeFile(`${config.dest}.json`, JSON.stringify({ suffix: config.suffix }))
  }

  let pipe = gulp.src(config.src)
    .pipe(sourcemaps.init())
    .pipe(less(config.options).on('error', errorHandler))
    .pipe(postcss(processors))

  if (config.suffix) {
    pipe = pipe.pipe(rename({ suffix: config.suffix }))
  }

  return pipe.pipe(sourcemaps.write('./maps'))
    // .on('error', errorHandler)
    .pipe(gulp.dest(config.dest))
})
<commit_msg>Use sync mkdirp<commit_after>'use strict'

const fs = require('fs')
const gulp = require('gulp')
const lessModule = require('less')
const less = require('gulp-less')
const sourcemaps = require('gulp-sourcemaps')
const rename = require('gulp-rename')
const mkdirp = require('mkdirp')

const postcss = require('gulp-postcss')
const autoprefixer = require('autoprefixer')

const config = require('../config').less

const errorHandler = require('../util/error-handler')

lessModule.functions.functionRegistry.addMultiple(config.functions)

const processors = [
  autoprefixer(),
]

if (process.env.NODE_ENV === 'production') {
  const csswring = require('csswring')

  processors.push(csswring())
}

gulp.task('less', () => {
  mkdirp.sync(config.dest)

  if (config.suffix) {
    fs.writeFile(`${config.dest}.json`, JSON.stringify({ suffix: config.suffix }))
  }

  let pipe = gulp.src(config.src)
    .pipe(sourcemaps.init())
    .pipe(less(config.options).on('error', errorHandler))
    .pipe(postcss(processors))

  if (config.suffix) {
    pipe = pipe.pipe(rename({ suffix: config.suffix }))
  }

  return pipe.pipe(sourcemaps.write('./maps'))
    // .on('error', errorHandler)
    .pipe(gulp.dest(config.dest))
})
<|endoftext|>


<commit_before>/*
 * Websensor video stabilization project
 * https://github.com/jessenie-intel/websensor-video
 *
 * Copyright (c) 2017 Jesse Nieminen
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
*/

'use strict';

var constraints = {audio: true,video: {  width: { min: 640, ideal: 640, max: 640 },  height: { min: 480, ideal: 480, max: 480 }}};
var mediaRecorder = null;
var chunks = [];
var videoData = null;
var interval = null;

var accel_sensor = null;
var orientation_sensor = null;
var sensorfreq = 60;

//var roll = null;
//var pitch = null;
//var yaw = null;
var accel = {"x": null, "y": null, "z": null};
var ori = {"roll": null, "pitch": null, "yaw": null, "time": null};
var oriInitial = {"roll": null, "pitch": null, "yaw": null, "time": null};
var initialoriobtained = false;
var orientationData = [];       //array to store all the orientation data
var frameData = {"data": null, "time": null, "ori": null};
var dataArray = [];     //array to store all the combined data
var dataArray2 = [];     //array to store all the combined data

var time = null;
var timestamps = [];
var nFrame = 0; //frame number with which we can combine timestamp and frame data

//canvas
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');

//video element
var videoElement = document.querySelector('video');
videoElement.controls = false;

var ref = null;

class AbsOriSensor {
        constructor() {
        const sensor = new AbsoluteOrientationSensor({ frequency: sensorfreq });
        const mat4 = new Float32Array(16);
        const euler = new Float32Array(3);
        sensor.onreading = () => {
                sensor.populateMatrix(mat4);
                toEulerianAngle(sensor.quaternion, euler);      //From quaternion to Eulerian angles
                this.roll = euler[0];
                this.pitch = euler[1];
                this.yaw = euler[2];
                this.timestamp = sensor.timestamp;
                if (this.onreading) this.onreading();
        };
        sensor.onactivate = () => {
                if (this.onactivate) this.onactivate();
        };
        const start = () => sensor.start();
        Object.assign(this, { start });
        }
}

//WINDOWS 10 HAS DIFFERENT CONVENTION: Yaw z, pitch x, roll y
function toEulerianAngle(quat, out)
{
        const ysqr = quat[1] ** 2;

        // Roll (x-axis rotation).
        const t0 = 2 * (quat[3] * quat[0] + quat[1] * quat[2]);
        const t1 = 1 - 2 * (ysqr + quat[0] ** 2);
        out[0] = Math.atan2(t0, t1);
        // Pitch (y-axis rotation).
        let t2 = 2 * (quat[3] * quat[1] - quat[2] * quat[0]);
        t2 = t2 > 1 ? 1 : t2;
        t2 = t2 < -1 ? -1 : t2;
        out[1] = Math.asin(t2);
        // Yaw (z-axis rotation).
        const t3 = 2 * (quat[3] * quat[2] + quat[0] * quat[1]);
        const t4 = 1 - 2 * (ysqr + quat[2] ** 2);
        out[2] = Math.atan2(t3, t4);
        return out;
}

function errorCallback(error){
	console.log("error: ", error);
}

function startDemo () {
		navigator.getUserMedia(constraints, startRecording, errorCallback);
}

function startRecording(stream) {

                try {
                //Initialize sensors
                /*accel_sensor = new Accelerometer();
                accel_sensor.onreading = () => {
                        accel = {"x": accel_sensor.x, "y": accel_sensor.y, "z": accel_sensor.z};
                };
                accel_sensor.onactivate = () => {
                };
                accel_sensor.start();*/
                orientation_sensor = new AbsOriSensor();
                orientation_sensor.onreading = () => {
                        let roll = orientation_sensor.roll;
                        let pitch = orientation_sensor.pitch;
                        let yaw = orientation_sensor.yaw;
                        time = orientation_sensor.timestamp;
                        if(!initialoriobtained) //obtain initial orientation
                        {
                                oriInitial = {"roll": orientation_sensor.roll, "pitch": orientation_sensor.pitch, "yaw": orientation_sensor.yaw, "time": orientation_sensor.timestamp};
                                initialoriobtained = true;
                        }
                        ori = {"roll": orientation_sensor.roll, "pitch": orientation_sensor.pitch, "yaw": orientation_sensor.yaw, "time": orientation_sensor.timestamp};
                };
                orientation_sensor.onactivate = () => {
                };
                orientation_sensor.start();
                }
                catch(err) {
                        console.log(err.message);
                        console.log("Your browser doesn't seem to support generic sensors. If you are running Chrome, please enable it in about:flags.");
                        //this.innerHTML = "Your browser doesn't seem to support generic sensors. If you are running Chrome, please enable it in about:flags";
                }
	        //var options = {mimeType: 'video/webm;codecs=vp9'};
		//mediaRecorder = new MediaRecorder(stream, options);
		mediaRecorder = new MediaRecorder(stream);

	        mediaRecorder.start(10);

	        var url = window.URL;
	        videoElement.src = url ? url.createObjectURL(stream) : stream;
                //videoElement.play();

	        mediaRecorder.ondataavailable = function(e) {
                        //console.log("Data available", e);
                        //console.log(time);
                        timestamps.push(time);
                        frameData.time = time;
		        chunks.push(e.data);
                        frameData.data = e.data;
                        orientationData.push(ori);
                        frameData.ori = ori;
                        var b = new Object;     //need to push by value
                        Object.assign(b, frameData);
                        dataArray.push(b);
	        };

	        mediaRecorder.onerror = function(e){
		        console.log('Error: ', e);
	        };

	        mediaRecorder.onstart = function(){
                        console.log("Recording started", mediaRecorder.state);
	        };

	        mediaRecorder.onstop = function(){
		        var blob = new Blob(chunks, {type: "video/webm"});
		        chunks = [];

		        var videoURL = window.URL.createObjectURL(blob);

		        videoElement.src = videoURL;
                        //videoElement.load();

                        //resize canvas
videoElement.addEventListener('loadedmetadata', function() {
  canvas.width = videoElement.videoWidth;
  canvas.height = videoElement.videoHeight;
});

                        /*//Read blob data so we can stabilize the video
                        var reader = new FileReader();
                         reader.onload = function(event){
                                let text = reader.result;
                                console.log(text);
                          };
                        reader.readAsText(blob, "video/webm");*/
                        //console.log(orientationData);
                        //console.log(timestamps);
                        //console.log(dataArray);
/*
var blobUrl = URL.createObjectURL(blob);
var x = new XMLHttpRequest();
// set x.responseType = 'blob' if you want to get a Blob object:
// x.responseType = 'blob';
x.onload = function() {
    alert(x.responseText);
};
console.log(x.open('get', blobUrl));*/
                        readFrameData(blob, orientationData);    //reads the video into dataArray2
                        /*videoElement.onended = function() {
                                alert("The video has ended");
                                cancelAnimationFrame(ref);
                        };*/
                        //ctx.clearRect(0, 0, canvas.width, canvas.height);
                        //stabilize(dataArray2);        //now we can operate on it
                        //interval=window.setInterval(stabilize,20);
	        };

	        mediaRecorder.onpause = function(){
	        }

	        mediaRecorder.onresume = function(){
	        }

	        mediaRecorder.onwarning = function(e){
	        };
}

function stopRecording(){
	mediaRecorder.stop();
        //Now stabilize
	videoElement.controls = true;
}
//Idea: copy video to canvas, operate on the video, and then use the canvas with the stabilized video as source for the video element
function readFrameData(blob, oriArray) {     //Read video data from blob to object form with pixel data we can operate on
        //console.log(orientationData);
        //console.log(oriInitial);
        //console.log(timestamps[nFrame] - timestamps[0], videoElement.currentTime);
        //while(!videoElement.ended)
        //{
                //videoElement.playbackRate = 0.5;        //fix playback being too fast
                let ori = orientationData[nFrame];
                let oriDiff = {"roll": ori.roll-oriInitial.roll, "pitch": ori.pitch-oriInitial.pitch, "yaw": ori.yaw-oriInitial.yaw};
                let x = videoElement.videoWidth*(oriDiff.yaw/(2*Math.Pi));
                let y = videoElement.videoWidth*(oriDiff.roll/(2*Math.Pi));     //each 2pi means 1 video height
                let widthR = 100;
                let heightR = 100;
                ctx.drawImage(videoElement,0,0, videoElement.videoWidth, videoElement.videoHeight);
                ctx.beginPath();
                ctx.rect(x,y,widthR,heightR);
                ctx.stroke();

                //ctx.drawImage(videoElement, 0, 0);
                let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
                let pixeldataArray = [];
                //loop through every pixel
                for(let i=0; i<imageData.data.length; i = i+4)
                {
                        let pixeldata = {"red": imageData.data[i], "green":imageData.data[i+1], "blue": imageData.data[i+2], "alpha":imageData.data[i+3]};
                        //pixeldataArray.push(pixeldata);
                }
                //pixeldataArray.push(imageData);
                //if(nFrame < dataArray.length) {
                        let timestamp = dataArray[nFrame].time;
                        let frameData2 = {"imagedata": imageData, "time": timestamp, "oridiff": oriDiff};
                        //var b = new Object;     //need to push by value
                        //Object.assign(b, frameData2);
                        //dataArray2.push(b);
                        dataArray2.push(frameData2);
                        //console.log(pixeldataArray);
                        //newImageData.data = data;
                    // Draw the pixels onto the visible canvas
                    //ctx.putImageData(newImageData,0,0);
                        //ctx.putImageData(imageData, 0, 0)
                        //xD
                //}
        //}
                nFrame = nFrame + 1;
                ref = requestAnimationFrame(readFrameData);
        /*
        if(dataArray2.length === timestamps.length)     //now we have read the whole blob - should use callback here instead of if condition
        {
                console.log("ended");
                cancelAnimationFrame(ref);
                console.log(dataArray2);
                stabilize(dataArray2);
        } */
        if(nFrame >= orientationData.length-1)
        {
                cancelAnimationFrame(ref);
        }
}

function stabilize(dataArrayArg) { //Create a stabilized video from the pixel data given as input
        let frame = dataArrayArg[0];      //first frame
        console.log(frame);
        //ctx.drawImage(frame.imagedata,0,0, videoElement.videoWidth, videoElement.videoHeight);
        //ctx.putImageData(frame.imagedata, 0, 0);
}
<commit_msg>Working on reacting to sensor input<commit_after>/*
 * Websensor video stabilization project
 * https://github.com/jessenie-intel/websensor-video
 *
 * Copyright (c) 2017 Jesse Nieminen
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
*/

'use strict';

var constraints = {audio: true,video: {  width: { min: 640, ideal: 640, max: 640 },  height: { min: 480, ideal: 480, max: 480 }}};
var mediaRecorder = null;
var chunks = [];
var videoData = null;
var interval = null;

var accel_sensor = null;
var orientation_sensor = null;
var sensorfreq = 60;

//var roll = null;
//var pitch = null;
//var yaw = null;
var accel = {"x": null, "y": null, "z": null};
var ori = {"roll": null, "pitch": null, "yaw": null, "time": null};
var oriInitial = {"roll": null, "pitch": null, "yaw": null, "time": null};
var initialoriobtained = false;
var orientationData = [];       //array to store all the orientation data
var frameData = {"data": null, "time": null, "ori": null};
var dataArray = [];     //array to store all the combined data
var dataArray2 = [];     //array to store all the combined data

var time = null;
var timestamps = [];
var nFrame = 0; //frame number with which we can combine timestamp and frame data

//canvas
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');

//video element
var videoElement = document.querySelector('video');
videoElement.controls = false;

var ref = null;

class AbsOriSensor {
        constructor() {
        const sensor = new AbsoluteOrientationSensor({ frequency: sensorfreq });
        const mat4 = new Float32Array(16);
        const euler = new Float32Array(3);
        sensor.onreading = () => {
                sensor.populateMatrix(mat4);
                toEulerianAngle(sensor.quaternion, euler);      //From quaternion to Eulerian angles
                this.roll = euler[0];
                this.pitch = euler[1];
                this.yaw = euler[2];
                this.timestamp = sensor.timestamp;
                if (this.onreading) this.onreading();
        };
        sensor.onactivate = () => {
                if (this.onactivate) this.onactivate();
        };
        const start = () => sensor.start();
        Object.assign(this, { start });
        }
}

//WINDOWS 10 HAS DIFFERENT CONVENTION: Yaw z, pitch x, roll y
function toEulerianAngle(quat, out)
{
        const ysqr = quat[1] ** 2;

        // Roll (x-axis rotation).
        const t0 = 2 * (quat[3] * quat[0] + quat[1] * quat[2]);
        const t1 = 1 - 2 * (ysqr + quat[0] ** 2);
        out[0] = Math.atan2(t0, t1);
        // Pitch (y-axis rotation).
        let t2 = 2 * (quat[3] * quat[1] - quat[2] * quat[0]);
        t2 = t2 > 1 ? 1 : t2;
        t2 = t2 < -1 ? -1 : t2;
        out[1] = Math.asin(t2);
        // Yaw (z-axis rotation).
        const t3 = 2 * (quat[3] * quat[2] + quat[0] * quat[1]);
        const t4 = 1 - 2 * (ysqr + quat[2] ** 2);
        out[2] = Math.atan2(t3, t4);
        return out;
}

function errorCallback(error){
	console.log("error: ", error);
}

function startDemo () {
		navigator.getUserMedia(constraints, startRecording, errorCallback);
}

function startRecording(stream) {

                try {
                //Initialize sensors
                /*accel_sensor = new Accelerometer();
                accel_sensor.onreading = () => {
                        accel = {"x": accel_sensor.x, "y": accel_sensor.y, "z": accel_sensor.z};
                };
                accel_sensor.onactivate = () => {
                };
                accel_sensor.start();*/
                orientation_sensor = new AbsOriSensor();
                orientation_sensor.onreading = () => {
                        let roll = orientation_sensor.roll;
                        let pitch = orientation_sensor.pitch;
                        let yaw = orientation_sensor.yaw;
                        time = orientation_sensor.timestamp;
                        if(!initialoriobtained) //obtain initial orientation
                        {
                                oriInitial = {"roll": orientation_sensor.roll, "pitch": orientation_sensor.pitch, "yaw": orientation_sensor.yaw, "time": orientation_sensor.timestamp};
                                initialoriobtained = true;
                        }
                        ori = {"roll": orientation_sensor.roll, "pitch": orientation_sensor.pitch, "yaw": orientation_sensor.yaw, "time": orientation_sensor.timestamp};
                };
                orientation_sensor.onactivate = () => {
                };
                orientation_sensor.start();
                }
                catch(err) {
                        console.log(err.message);
                        console.log("Your browser doesn't seem to support generic sensors. If you are running Chrome, please enable it in about:flags.");
                        //this.innerHTML = "Your browser doesn't seem to support generic sensors. If you are running Chrome, please enable it in about:flags";
                }
	        //var options = {mimeType: 'video/webm;codecs=vp9'};
		//mediaRecorder = new MediaRecorder(stream, options);
		mediaRecorder = new MediaRecorder(stream);

	        mediaRecorder.start(10);

	        var url = window.URL;
	        videoElement.src = url ? url.createObjectURL(stream) : stream;
                //videoElement.play();

	        mediaRecorder.ondataavailable = function(e) {
                        //console.log("Data available", e);
                        //console.log(time);
                        timestamps.push(time);
                        frameData.time = time;
		        chunks.push(e.data);
                        frameData.data = e.data;
                        orientationData.push(ori);
                        frameData.ori = ori;
                        var b = new Object;     //need to push by value
                        Object.assign(b, frameData);
                        dataArray.push(b);
	        };

	        mediaRecorder.onerror = function(e){
		        console.log('Error: ', e);
	        };

	        mediaRecorder.onstart = function(){
                        console.log("Recording started", mediaRecorder.state);
                        //resize canvas
videoElement.addEventListener('loadedmetadata', function() {
  canvas.width = videoElement.videoWidth;
  canvas.height = videoElement.videoHeight;
});
readFrameData(blob, orientationData);    //reads the video into dataArray2
	        };

	        mediaRecorder.onstop = function(){
		        var blob = new Blob(chunks, {type: "video/webm"});
		        chunks = [];

		        var videoURL = window.URL.createObjectURL(blob);

		        videoElement.src = videoURL;
                        //videoElement.load();

                        //resize canvas
videoElement.addEventListener('loadedmetadata', function() {
  canvas.width = videoElement.videoWidth;
  canvas.height = videoElement.videoHeight;
});

                        /*//Read blob data so we can stabilize the video
                        var reader = new FileReader();
                         reader.onload = function(event){
                                let text = reader.result;
                                console.log(text);
                          };
                        reader.readAsText(blob, "video/webm");*/
                        //console.log(orientationData);
                        //console.log(timestamps);
                        //console.log(dataArray);
/*
var blobUrl = URL.createObjectURL(blob);
var x = new XMLHttpRequest();
// set x.responseType = 'blob' if you want to get a Blob object:
// x.responseType = 'blob';
x.onload = function() {
    alert(x.responseText);
};
console.log(x.open('get', blobUrl));*/
                        //readFrameData(blob, orientationData);    //reads the video into dataArray2
                        /*videoElement.onended = function() {
                                alert("The video has ended");
                                cancelAnimationFrame(ref);
                        };*/
                        //ctx.clearRect(0, 0, canvas.width, canvas.height);
                        //stabilize(dataArray2);        //now we can operate on it
                        //interval=window.setInterval(stabilize,20);
	        };

	        mediaRecorder.onpause = function(){
	        }

	        mediaRecorder.onresume = function(){
	        }

	        mediaRecorder.onwarning = function(e){
	        };
}

function stopRecording(){
	mediaRecorder.stop();
        //Now stabilize
	videoElement.controls = true;
}
//Idea: copy video to canvas, operate on the video, and then use the canvas with the stabilized video as source for the video element
function readFrameData(blob, oriArray) {     //Read video data from blob to object form with pixel data we can operate on
        //console.log(orientationData);
        //console.log(oriInitial);
        //console.log(timestamps[nFrame] - timestamps[0], videoElement.currentTime);
        //while(!videoElement.ended)
        //{
                //videoElement.playbackRate = 0.5;        //fix playback being too fast
                let ori = orientationData[nFrame];
                let oriDiff = {"roll": ori.roll-oriInitial.roll, "pitch": ori.pitch-oriInitial.pitch, "yaw": ori.yaw-oriInitial.yaw};
                let x = videoElement.videoWidth*(oriDiff.yaw/(2*Math.Pi));
                let y = videoElement.videoWidth*(oriDiff.roll/(2*Math.Pi));     //each 2pi means 1 video height
                let widthR = 100;
                let heightR = 100;
                ctx.drawImage(videoElement,0,0, videoElement.videoWidth, videoElement.videoHeight);
                /*ctx.beginPath();
                ctx.rect(x,y,widthR,heightR);
                ctx.stroke();
*/
                //ctx.drawImage(videoElement, 0, 0);
                let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
                /*let pixeldataArray = [];
                //loop through every pixel
                for(let i=0; i<imageData.data.length; i = i+4)
                {
                        let pixeldata = {"red": imageData.data[i], "green":imageData.data[i+1], "blue": imageData.data[i+2], "alpha":imageData.data[i+3]};
                        //pixeldataArray.push(pixeldata);
                }
                //pixeldataArray.push(imageData);*/
                //if(nFrame < dataArray.length) {
                        let timestamp = dataArray[nFrame].time;
                        let frameData2 = {"imagedata": imageData, "time": timestamp, "oridiff": oriDiff};
                        //var b = new Object;     //need to push by value
                        //Object.assign(b, frameData2);
                        //dataArray2.push(b);
                        dataArray2.push(frameData2);
                        //console.log(pixeldataArray);
                        //newImageData.data = data;
                    // Draw the pixels onto the visible canvas
                    //ctx.putImageData(newImageData,0,0);
                        //ctx.putImageData(imageData, 0, 0)
                        //xD
                //}
        //}
                nFrame = nFrame + 1;
                ref = requestAnimationFrame(readFrameData);
        /*
        if(dataArray2.length === timestamps.length)     //now we have read the whole blob - should use callback here instead of if condition
        {
                console.log("ended");
                cancelAnimationFrame(ref);
                console.log(dataArray2);
                stabilize(dataArray2);
        } */
        if(nFrame >= orientationData.length-1)
        {
                cancelAnimationFrame(ref);
        }
}

function stabilize(dataArrayArg) { //Create a stabilized video from the pixel data given as input
        let frame = dataArrayArg[0];      //first frame
        console.log(frame);
        //ctx.drawImage(frame.imagedata,0,0, videoElement.videoWidth, videoElement.videoHeight);
        //ctx.putImageData(frame.imagedata, 0, 0);
}
<|endoftext|>