<commit_before>function injectedScript() {

	'use strict';

	var ViveData = {
		name: 'Emulated HTC Vive DVT',
		resolution: { width: 1512, height: 1680 },
		features: { canPresent: true, hasExternalDisplay: true, hasOrientation: true, hasPosition: true },
		leftEye: { offset: -0.032, up: 41.653, down: 48.008, left: 43.977, right: 35.575 },
		rightEye: { offset: 0.032, up: 41.653, down: 48.008, left: 35.575, right: 43.977 }
	}

	var RiftData = {
		name: 'Emulated Oculus Rift CV1',
		resolution: { width: 1332, height: 1586 },
		features: { canPresent: true, hasExternalDisplay: true, hasOrientation: true, hasPosition: true },
		leftEye: { offset: -0.032, up: 55.814, down: 55.728, left: 54.429, right: 51.288 },
		rightEye: { offset: 0.032, up: 55.687, down: 55.658, left: 51.110, right: 54.397 }
	}

	var CardboardData = {
		name: 'Emulated Google, Inc. Cardboard v1',
		resolution: { width: 960, height: 1080 },
		features: { canPresent: true, hasExternalDisplay: false, hasOrientation: true, hasPosition: false },
		leftEye: { offset: -0.030, up: 40, down: 40, left: 40, right: 40 },
		rightEye: { offset: 0.030, up: 40, down: 40, left: 40, right: 40 }
	}

	var startDate = Date.now();
	var startPerfNow = performance.now();

	// WebVR 1.0

	function VRDisplayCapabilities () {

		this.canPresent = true;
		this.hasExternalDisplay = true;
		this.hasOrientation = true;
		this.hasPosition = true;
		this.maxLayers = 1

	}

	function VRStageParameters() {

		this.sittingToStandingTransform = new Float32Array( [
			1, 0, 0, 0,
			0, 1, 0, 0,
			0, 0, 1, 0,
			0, 0, 0, 1
		] );

		this.sizeX = 5;
		this.sizeZ = 3;

	}

	function VRPose() {

		this.timestamp = startDate + ( performance.now() - startPerfNow );
		this.position = new Float32Array( [ 0, 0, 0 ] );
		this.linearVelocity = new Float32Array( [ 0, 0, 0 ] );
		this.linearAcceleration = null;
		this.orientation = new Float32Array( [ 0, 0, 0, 1 ] );
		this.angularVelocity = new Float32Array( [ 0, 0, 0 ] );
		this.angularAcceleration = null;

	}

	function VRFieldOfView() {

		this.upDegrees = 0;
		this.downDegrees = 0;
		this.leftDegrees = 0;
		this.rightDegrees = 0;

	}

	function VREyeParameters() {

		this.offset = new Float32Array( [ 0, 0, 0 ] );
		this.fieldOfView = new VRFieldOfView();
		this.renderWidth = 0;
		this.renderHeight = 0;

	}

	function createVRDisplayEvent( type, display, reason ) {

		var event = new CustomEvent( type );
		event.display = display;
		event.reason = reason;

		return event;

	}

	function VRDisplay( model ) {

		this.depthFar = 1000;
		this.depthNear = .1;
		this.displayId = 1;
		this.displayName = model.name;
		this.isConnected = true;
		this.isPresenting = false;
		this.__currentLayers = [];

		this.stageParameters = new VRStageParameters();

		this.capabilities = new VRDisplayCapabilities();
		this.capabilities.canPresent = model.features.canPresent;
		this.capabilities.hasExternalDisplay = model.features.hasExternalDisplay;
		this.capabilities.hasOrientation = model.features.hasOrientation;
		this.capabilities.hasPosition = model.features.hasPosition;

		this.pose = new VRPose();

		this.leftEyeParameters = new VREyeParameters();
		this.leftEyeParameters.fieldOfView.upDegrees = model.leftEye.up;
		this.leftEyeParameters.fieldOfView.downDegrees = model.leftEye.down;
		this.leftEyeParameters.fieldOfView.leftDegrees = model.leftEye.left;
		this.leftEyeParameters.fieldOfView.rightDegrees = model.leftEye.right;
		this.leftEyeParameters.renderWidth = model.resolution.width;
		this.leftEyeParameters.renderHeight = model.resolution.height;
		this.leftEyeParameters.offset[ 0 ] = model.leftEye.offset;

		this.rightEyeParameters = new VREyeParameters();
		this.rightEyeParameters.fieldOfView.upDegrees = model.rightEye.up;
		this.rightEyeParameters.fieldOfView.downDegrees = model.rightEye.down;
		this.rightEyeParameters.fieldOfView.leftDegrees = model.rightEye.left;
		this.rightEyeParameters.fieldOfView.rightDegrees = model.rightEye.right;
		this.rightEyeParameters.renderWidth = model.resolution.width;
		this.rightEyeParameters.renderHeight = model.resolution.height;
		this.rightEyeParameters.offset[ 0 ] = model.rightEye.offset;

		window.addEventListener( 'webvr-pose', function( e ) {

			this.pose.linearVelocity[ 0 ] = e.detail.position.x - this.pose.position[ 0 ];
			this.pose.linearVelocity[ 1 ] = e.detail.position.y - this.pose.position[ 1 ];
			this.pose.linearVelocity[ 2 ] = e.detail.position.z - this.pose.position[ 2 ];

			this.pose.position[ 0 ] = e.detail.position.x;
			this.pose.position[ 1 ] = e.detail.position.y;
			this.pose.position[ 2 ] = e.detail.position.z;

			this.pose.orientation[ 0 ] = e.detail.rotation.x;
			this.pose.orientation[ 1 ] = e.detail.rotation.y;
			this.pose.orientation[ 2 ] = e.detail.rotation.z;
			this.pose.orientation[ 3 ] = e.detail.rotation.w;

		}.bind( this ) );

		window.addEventListener( 'webvr-hmd-activate', function( e ) {

			if( e.detail.state ){
				var event = createVRDisplayEvent( 'vrdisplayactivate', this, 'HMD activated' );
				window.dispatchEvent(event);
			} else {
				var event = createVRDisplayEvent( 'vrdisplaydeactivate', this, 'HMD deactivated' );
				window.dispatchEvent(event);
			}

		}.bind( this ) );

	}

	VRDisplay.prototype.requestAnimationFrame = function( c ) {

		return requestAnimationFrame( c );

	}

	VRDisplay.prototype.cancelAnimationFrame = function(handle) {

		cancelAnimationFrame(handle);

	}

	VRDisplay.prototype.getEyeParameters = function( id ) {

		if( id === 'left' ) return this.leftEyeParameters;
		return this.rightEyeParameters;

	}

	VRDisplay.prototype.getPose = function() {

		this.pose.timestamp = startDate + ( performance.now() - startPerfNow );

		return this.pose;

	}

	VRDisplay.prototype.requestPresent = function(layers) {

		return new Promise( function( resolve, reject ) {

			this.isPresenting = true;

			this.__currentLayers = layers;

			var event = createVRDisplayEvent( 'vrdisplaypresentchange', this, 'Presenting requested' );
			window.dispatchEvent(event);

			resolve();

		}.bind( this ) );

	}

	VRDisplay.prototype.exitPresent = function() {

		return new Promise( function( resolve, reject ) {

			this.isPresenting = false;

			this.__currentLayers = [];

			var event = createVRDisplayEvent( 'vrdisplaypresentchange', this, 'Presenting exited' );
			window.dispatchEvent(event);

			resolve();

		}.bind( this ) );

	}

	VRDisplay.prototype.submitFrame = function( pose ) {
	}

	VRDisplay.prototype.resetPose = function() {

		var event = new Event( 'webvr-resetpose' );
		window.dispatchEvent( event );

	}

	VRDisplay.prototype.getLayers = function() {

		return currentLayers;

	}

	window.VRDisplay = VRDisplay;

	( function() {

		var vrD = new VRDisplay( ViveData )

		navigator.getVRDisplays = function() {

			return new Promise( function( resolve, reject ) {

				resolve( [ vrD ] );

			} );

		}

	} )();

	// LEGACY

	function HMDVRDevice( model ) {

		this.deviceName = model.name;

		this.leftEyeParameters = new VREyeParameters();
		this.leftEyeParameters.fieldOfView.upDegrees = model.leftEye.up;
		this.leftEyeParameters.fieldOfView.downDegrees = model.leftEye.down;
		this.leftEyeParameters.fieldOfView.leftDegrees = model.leftEye.left;
		this.leftEyeParameters.fieldOfView.rightDegrees = model.leftEye.right;
		this.leftEyeParameters.renderWidth = model.resolution.width;
		this.leftEyeParameters.renderHeight = model.resolution.height;
		this.leftEyeParameters.offset[ 0 ] = model.leftEye.offset;

		this.rightEyeParameters = new VREyeParameters();
		this.rightEyeParameters.fieldOfView.upDegrees = model.rightEye.up;
		this.rightEyeParameters.fieldOfView.downDegrees = model.rightEye.down;
		this.rightEyeParameters.fieldOfView.leftDegrees = model.rightEye.left;
		this.rightEyeParameters.fieldOfView.rightDegrees = model.rightEye.right;
		this.rightEyeParameters.renderWidth = model.resolution.width;
		this.rightEyeParameters.renderHeight = model.resolution.height;
		this.rightEyeParameters.offset[ 0 ] = model.rightEye.offset;

		this.leftRecommendedFOV = new VREyeParameters();
		this.leftRecommendedFOV.fieldOfView.upDegrees = model.leftEye.up;
		this.leftRecommendedFOV.fieldOfView.downDegrees = model.leftEye.down;
		this.leftRecommendedFOV.fieldOfView.leftDegrees = model.leftEye.left;
		this.leftRecommendedFOV.fieldOfView.rightDegrees = model.leftEye.right;
		this.leftRecommendedFOV.renderWidth = model.resolution.width;
		this.leftRecommendedFOV.renderHeight = model.resolution.height;
		this.leftRecommendedFOV.offset[ 0 ] = model.leftEye.offset;

		this.rightRecommendedFOV = new VREyeParameters();
		this.rightRecommendedFOV.fieldOfView.upDegrees = model.rightEye.up;
		this.rightRecommendedFOV.fieldOfView.downDegrees = model.rightEye.down;
		this.rightRecommendedFOV.fieldOfView.leftDegrees = model.rightEye.left;
		this.rightRecommendedFOV.fieldOfView.rightDegrees = model.rightEye.right;
		this.rightRecommendedFOV.renderWidth = model.resolution.width;
		this.rightRecommendedFOV.renderHeight = model.resolution.height;
		this.rightRecommendedFOV.offset[ 0 ] = model.rightEye.offset;

	}

	HMDVRDevice.prototype.getEyeTranslation = function( eye ) {

		return 3;

	}

	HMDVRDevice.prototype.getRecommendedEyeFieldOfView = function( eye ) {

		if( eye === 'left' ) return this.leftRecommendedFOV;
		return this.rightRecommendedFOV;

	}

	function VRFieldOfView() {

		this.upDegrees = 0;
		this.downDegrees = 0;
		this.leftDegrees = 0;
		this.rightDegrees = 0;

	}

	function VREyeParameters() {

		this.eyeTranslation = 0;
		this.recommendedFieldOfView = new VRFieldOfView();
		this.offset = new Float32Array( [ 0, 0, 0 ] );
		this.fieldOfView = new VRFieldOfView();
		this.renderWidth = 0;
		this.renderHeight = 0;

	}

	HMDVRDevice.prototype.getEyeParameters = function( eye ) {

		if( eye === 'left' ) return this.leftEyeParameters;
		return this.rightEyeParameters;

	}

	function PositionSensorVRDevice( model ) {

		this.deviceName = model.name;

		this.state = new VRPositionState( model );

		window.addEventListener( 'webvr-pose', function( e ) {

			this.state.linearVelocity.x = e.detail.position.x - this.state.position.x;
			this.state.linearVelocity.y = e.detail.position.y - this.state.position.y;
			this.state.linearVelocity.z = e.detail.position.z - this.state.position.z;

			this.state.position.x = e.detail.position.x;
			this.state.position.y = e.detail.position.y;
			this.state.position.z = e.detail.position.z;

			this.state.orientation.x = e.detail.rotation.x;
			this.state.orientation.y = e.detail.rotation.y;
			this.state.orientation.z = e.detail.rotation.z;
			this.state.orientation.w = e.detail.rotation.w;

		}.bind( this ) );

	}

	function VRPositionState( model ) {

		this.angularAcceleration = new DOMPoint();
		this.angularVelocity = new DOMPoint();
		this.linearAcceleration = new DOMPoint();
		this.linearVelocity = new DOMPoint();
		this.orientation = new DOMPoint();
		this.position = new DOMPoint();
		this.timestamp = null;

		this.hasPosition = model.features.hasPosition;
		this.hasOrientation = model.features.hasOrientation;

	}

	function DOMPoint() {
		this.x = 0;
		this.y = 0;
		this.z = 0;
		this.w = 0;
	}

	PositionSensorVRDevice.prototype.getState = function() {

		this.state.timestamp = startDate + ( performance.now() - startPerfNow );

		return this.state;

	}

	window.HMDVRDevice = HMDVRDevice;
	window.PositionSensorVRDevice = PositionSensorVRDevice;

	window.VRDisplay = VRDisplay;

	( function() {

		var vrD = new HMDVRDevice( ViveData );
		var vrP = new PositionSensorVRDevice( ViveData );

		navigator.getVRDevices = function() {

			return new Promise( function( resolve, reject ) {

				resolve( [ vrD, vrP ] );

			} );

		}

	} )();

	var event = new Event( 'webvr-ready' );
	window.dispatchEvent( event );

}
<commit_msg>added VRLayer object and methods<commit_after>function injectedScript() {

	'use strict';

	var ViveData = {
		name: 'Emulated HTC Vive DVT',
		resolution: { width: 1512, height: 1680 },
		features: { canPresent: true, hasExternalDisplay: true, hasOrientation: true, hasPosition: true },
		leftEye: { offset: -0.032, up: 41.653, down: 48.008, left: 43.977, right: 35.575 },
		rightEye: { offset: 0.032, up: 41.653, down: 48.008, left: 35.575, right: 43.977 }
	}

	var RiftData = {
		name: 'Emulated Oculus Rift CV1',
		resolution: { width: 1332, height: 1586 },
		features: { canPresent: true, hasExternalDisplay: true, hasOrientation: true, hasPosition: true },
		leftEye: { offset: -0.032, up: 55.814, down: 55.728, left: 54.429, right: 51.288 },
		rightEye: { offset: 0.032, up: 55.687, down: 55.658, left: 51.110, right: 54.397 }
	}

	var CardboardData = {
		name: 'Emulated Google, Inc. Cardboard v1',
		resolution: { width: 960, height: 1080 },
		features: { canPresent: true, hasExternalDisplay: false, hasOrientation: true, hasPosition: false },
		leftEye: { offset: -0.030, up: 40, down: 40, left: 40, right: 40 },
		rightEye: { offset: 0.030, up: 40, down: 40, left: 40, right: 40 }
	}

	var startDate = Date.now();
	var startPerfNow = performance.now();

	// WebVR 1.0

	function VRDisplayCapabilities () {

		this.canPresent = true;
		this.hasExternalDisplay = true;
		this.hasOrientation = true;
		this.hasPosition = true;
		this.maxLayers = 1

	}

	function VRStageParameters() {

		this.sittingToStandingTransform = new Float32Array( [
			1, 0, 0, 0,
			0, 1, 0, 0,
			0, 0, 1, 0,
			0, 0, 0, 1
		] );

		this.sizeX = 5;
		this.sizeZ = 3;

	}

	function VRPose() {

		this.timestamp = startDate + ( performance.now() - startPerfNow );
		this.position = new Float32Array( [ 0, 0, 0 ] );
		this.linearVelocity = new Float32Array( [ 0, 0, 0 ] );
		this.linearAcceleration = null;
		this.orientation = new Float32Array( [ 0, 0, 0, 1 ] );
		this.angularVelocity = new Float32Array( [ 0, 0, 0 ] );
		this.angularAcceleration = null;

	}

	function VRFieldOfView() {

		this.upDegrees = 0;
		this.downDegrees = 0;
		this.leftDegrees = 0;
		this.rightDegrees = 0;

	}

	function VREyeParameters() {

		this.offset = new Float32Array( [ 0, 0, 0 ] );
		this.fieldOfView = new VRFieldOfView();
		this.renderWidth = 0;
		this.renderHeight = 0;

	}

	function VRLayer() {

		this.leftBounds = null;
		this.rightBounds = null;
		this.source = null;

	}

	function createVRDisplayEvent( type, display, reason ) {

		var event = new CustomEvent( type );
		event.display = display;
		event.reason = reason;

		return event;

	}

	function VRDisplay( model ) {

		this.depthFar = 1000;
		this.depthNear = .1;
		this.displayId = 1;
		this.displayName = model.name;
		this.isConnected = true;
		this.isPresenting = false;

		this.layers = [];

		this.stageParameters = new VRStageParameters();

		this.capabilities = new VRDisplayCapabilities();
		this.capabilities.canPresent = model.features.canPresent;
		this.capabilities.hasExternalDisplay = model.features.hasExternalDisplay;
		this.capabilities.hasOrientation = model.features.hasOrientation;
		this.capabilities.hasPosition = model.features.hasPosition;

		this.pose = new VRPose();

		this.leftEyeParameters = new VREyeParameters();
		this.leftEyeParameters.fieldOfView.upDegrees = model.leftEye.up;
		this.leftEyeParameters.fieldOfView.downDegrees = model.leftEye.down;
		this.leftEyeParameters.fieldOfView.leftDegrees = model.leftEye.left;
		this.leftEyeParameters.fieldOfView.rightDegrees = model.leftEye.right;
		this.leftEyeParameters.renderWidth = model.resolution.width;
		this.leftEyeParameters.renderHeight = model.resolution.height;
		this.leftEyeParameters.offset[ 0 ] = model.leftEye.offset;

		this.rightEyeParameters = new VREyeParameters();
		this.rightEyeParameters.fieldOfView.upDegrees = model.rightEye.up;
		this.rightEyeParameters.fieldOfView.downDegrees = model.rightEye.down;
		this.rightEyeParameters.fieldOfView.leftDegrees = model.rightEye.left;
		this.rightEyeParameters.fieldOfView.rightDegrees = model.rightEye.right;
		this.rightEyeParameters.renderWidth = model.resolution.width;
		this.rightEyeParameters.renderHeight = model.resolution.height;
		this.rightEyeParameters.offset[ 0 ] = model.rightEye.offset;

		window.addEventListener( 'webvr-pose', function( e ) {

			this.pose.linearVelocity[ 0 ] = e.detail.position.x - this.pose.position[ 0 ];
			this.pose.linearVelocity[ 1 ] = e.detail.position.y - this.pose.position[ 1 ];
			this.pose.linearVelocity[ 2 ] = e.detail.position.z - this.pose.position[ 2 ];

			this.pose.position[ 0 ] = e.detail.position.x;
			this.pose.position[ 1 ] = e.detail.position.y;
			this.pose.position[ 2 ] = e.detail.position.z;

			this.pose.orientation[ 0 ] = e.detail.rotation.x;
			this.pose.orientation[ 1 ] = e.detail.rotation.y;
			this.pose.orientation[ 2 ] = e.detail.rotation.z;
			this.pose.orientation[ 3 ] = e.detail.rotation.w;

		}.bind( this ) );

		window.addEventListener( 'webvr-hmd-activate', function( e ) {

			if( e.detail.state ){
				var event = createVRDisplayEvent( 'vrdisplayactivate', this, 'HMD activated' );
				window.dispatchEvent(event);
			} else {
				var event = createVRDisplayEvent( 'vrdisplaydeactivate', this, 'HMD deactivated' );
				window.dispatchEvent(event);
			}

		}.bind( this ) );

	}

	VRDisplay.prototype.requestAnimationFrame = function( c ) {

		return requestAnimationFrame( c );

	}

	VRDisplay.prototype.cancelAnimationFrame = function(handle) {

		cancelAnimationFrame(handle);

	}

	VRDisplay.prototype.getEyeParameters = function( id ) {

		if( id === 'left' ) return this.leftEyeParameters;
		return this.rightEyeParameters;

	}

	VRDisplay.prototype.getPose = function() {

		this.pose.timestamp = startDate + ( performance.now() - startPerfNow );

		return this.pose;

	}

	VRDisplay.prototype.requestPresent = function(layers) {

		return new Promise( function( resolve, reject ) {

			this.isPresenting = true;

			this.layers = [];
			layers.forEach( function( l ) {
				var layer = new VRLayer();
				layer.source = l.source;
				if( l.leftBounds ) layer.leftBounds = l.leftBounds;
				if( l.rightBounds ) layer.rightBounds = l.rightBounds;
				this.layers.push( layer );
			}.bind(this));

			var event = createVRDisplayEvent( 'vrdisplaypresentchange', this, 'Presenting requested' );
			window.dispatchEvent(event);

			resolve();

		}.bind( this ) );

	}

	VRDisplay.prototype.exitPresent = function() {

		return new Promise( function( resolve, reject ) {

			this.isPresenting = false;

			this.layers = [];

			var event = createVRDisplayEvent( 'vrdisplaypresentchange', this, 'Presenting exited' );
			window.dispatchEvent(event);

			resolve();

		}.bind( this ) );

	}

	VRDisplay.prototype.submitFrame = function( pose ) {
	}

	VRDisplay.prototype.resetPose = function() {

		var event = new Event( 'webvr-resetpose' );
		window.dispatchEvent( event );

	}

	VRDisplay.prototype.getLayers = function() {

		return this.layers;

	}

	window.VRDisplay = VRDisplay;

	( function() {

		var vrD = new VRDisplay( ViveData )

		navigator.getVRDisplays = function() {

			return new Promise( function( resolve, reject ) {

				resolve( [ vrD ] );

			} );

		}

	} )();

	// LEGACY

	function HMDVRDevice( model ) {

		this.deviceName = model.name;

		this.leftEyeParameters = new VREyeParameters();
		this.leftEyeParameters.fieldOfView.upDegrees = model.leftEye.up;
		this.leftEyeParameters.fieldOfView.downDegrees = model.leftEye.down;
		this.leftEyeParameters.fieldOfView.leftDegrees = model.leftEye.left;
		this.leftEyeParameters.fieldOfView.rightDegrees = model.leftEye.right;
		this.leftEyeParameters.renderWidth = model.resolution.width;
		this.leftEyeParameters.renderHeight = model.resolution.height;
		this.leftEyeParameters.offset[ 0 ] = model.leftEye.offset;

		this.rightEyeParameters = new VREyeParameters();
		this.rightEyeParameters.fieldOfView.upDegrees = model.rightEye.up;
		this.rightEyeParameters.fieldOfView.downDegrees = model.rightEye.down;
		this.rightEyeParameters.fieldOfView.leftDegrees = model.rightEye.left;
		this.rightEyeParameters.fieldOfView.rightDegrees = model.rightEye.right;
		this.rightEyeParameters.renderWidth = model.resolution.width;
		this.rightEyeParameters.renderHeight = model.resolution.height;
		this.rightEyeParameters.offset[ 0 ] = model.rightEye.offset;

		this.leftRecommendedFOV = new VREyeParameters();
		this.leftRecommendedFOV.fieldOfView.upDegrees = model.leftEye.up;
		this.leftRecommendedFOV.fieldOfView.downDegrees = model.leftEye.down;
		this.leftRecommendedFOV.fieldOfView.leftDegrees = model.leftEye.left;
		this.leftRecommendedFOV.fieldOfView.rightDegrees = model.leftEye.right;
		this.leftRecommendedFOV.renderWidth = model.resolution.width;
		this.leftRecommendedFOV.renderHeight = model.resolution.height;
		this.leftRecommendedFOV.offset[ 0 ] = model.leftEye.offset;

		this.rightRecommendedFOV = new VREyeParameters();
		this.rightRecommendedFOV.fieldOfView.upDegrees = model.rightEye.up;
		this.rightRecommendedFOV.fieldOfView.downDegrees = model.rightEye.down;
		this.rightRecommendedFOV.fieldOfView.leftDegrees = model.rightEye.left;
		this.rightRecommendedFOV.fieldOfView.rightDegrees = model.rightEye.right;
		this.rightRecommendedFOV.renderWidth = model.resolution.width;
		this.rightRecommendedFOV.renderHeight = model.resolution.height;
		this.rightRecommendedFOV.offset[ 0 ] = model.rightEye.offset;

	}

	HMDVRDevice.prototype.getEyeTranslation = function( eye ) {

		return 3;

	}

	HMDVRDevice.prototype.getRecommendedEyeFieldOfView = function( eye ) {

		if( eye === 'left' ) return this.leftRecommendedFOV;
		return this.rightRecommendedFOV;

	}

	function VRFieldOfView() {

		this.upDegrees = 0;
		this.downDegrees = 0;
		this.leftDegrees = 0;
		this.rightDegrees = 0;

	}

	function VREyeParameters() {

		this.eyeTranslation = 0;
		this.recommendedFieldOfView = new VRFieldOfView();
		this.offset = new Float32Array( [ 0, 0, 0 ] );
		this.fieldOfView = new VRFieldOfView();
		this.renderWidth = 0;
		this.renderHeight = 0;

	}

	HMDVRDevice.prototype.getEyeParameters = function( eye ) {

		if( eye === 'left' ) return this.leftEyeParameters;
		return this.rightEyeParameters;

	}

	function PositionSensorVRDevice( model ) {

		this.deviceName = model.name;

		this.state = new VRPositionState( model );

		window.addEventListener( 'webvr-pose', function( e ) {

			this.state.linearVelocity.x = e.detail.position.x - this.state.position.x;
			this.state.linearVelocity.y = e.detail.position.y - this.state.position.y;
			this.state.linearVelocity.z = e.detail.position.z - this.state.position.z;

			this.state.position.x = e.detail.position.x;
			this.state.position.y = e.detail.position.y;
			this.state.position.z = e.detail.position.z;

			this.state.orientation.x = e.detail.rotation.x;
			this.state.orientation.y = e.detail.rotation.y;
			this.state.orientation.z = e.detail.rotation.z;
			this.state.orientation.w = e.detail.rotation.w;

		}.bind( this ) );

	}

	function VRPositionState( model ) {

		this.angularAcceleration = new DOMPoint();
		this.angularVelocity = new DOMPoint();
		this.linearAcceleration = new DOMPoint();
		this.linearVelocity = new DOMPoint();
		this.orientation = new DOMPoint();
		this.position = new DOMPoint();
		this.timestamp = null;

		this.hasPosition = model.features.hasPosition;
		this.hasOrientation = model.features.hasOrientation;

	}

	function DOMPoint() {
		this.x = 0;
		this.y = 0;
		this.z = 0;
		this.w = 0;
	}

	PositionSensorVRDevice.prototype.getState = function() {

		this.state.timestamp = startDate + ( performance.now() - startPerfNow );

		return this.state;

	}

	window.HMDVRDevice = HMDVRDevice;
	window.PositionSensorVRDevice = PositionSensorVRDevice;

	window.VRDisplay = VRDisplay;

	( function() {

		var vrD = new HMDVRDevice( ViveData );
		var vrP = new PositionSensorVRDevice( ViveData );

		navigator.getVRDevices = function() {

			return new Promise( function( resolve, reject ) {

				resolve( [ vrD, vrP ] );

			} );

		}

	} )();

	var event = new Event( 'webvr-ready' );
	window.dispatchEvent( event );

}
<|endoftext|>


<commit_before>//var Hub = require("node-xiaomi-smart-home").Hub;
var Hub = require("./../src/Hub").Hub;

let hub = new Hub();
hub.listen();

hub.on('message', function (message) {
    // raw message received from the xiaomi smart hub
});

hub.on('error', function (e) {

});

hub.on('data.button', function (sid, type, battery) {
    // type can be click, double_click, long_click_press, long_click_release
    if (type == hub.clickTypes.double_click)
    {
        // do something
    }
    console.info('BUTTON', sid, type);
});

hub.on('data.magnet', function (sid, closed, battery) {
    console.info('MAGNET', sid, closed, battery);

});

hub.on('data.motion', function (sid, motion, battery) {
    console.info('motion', sid, motion, battery);
});

hub.on('data.motionAq2', function (sid, motion, light, inactivity, battery) {
    console.info('motion', sid, motion, light, inactivity, battery);
});

hub.on('data.th', function (sid, temperature, humidity, battery) {
    console.info('th', sid, temperature, humidity, battery);
});

hub.on('data.plug', function (sid, on) {
    console.info('plug', sid, on);
});

hub.on('data.weather', function (sid, temperature, humidity, pressure, battery) {
    console.info('th', sid, temperature, humidity, pressure, battery);
});

<commit_msg>Prepare to production<commit_after>var Hub = require("node-xiaomi-smart-home").Hub;
//var Hub = require("./../src/Hub").Hub;

let hub = new Hub();
hub.listen();

hub.on('message', function (message) {
    // raw message received from the xiaomi smart hub
});

hub.on('error', function (e) {

});

hub.on('data.button', function (sid, type, battery) {
    // type can be click, double_click, long_click_press, long_click_release
    if (type == hub.clickTypes.double_click)
    {
        // do something
    }
    console.info('BUTTON', sid, type);
});

hub.on('data.magnet', function (sid, closed, battery) {
    console.info('MAGNET', sid, closed, battery);

});

hub.on('data.motion', function (sid, motion, battery) {
    console.info('motion', sid, motion, battery);
});

hub.on('data.motionAq2', function (sid, motion, light, inactivity, battery) {
    console.info('motion', sid, motion, light, inactivity, battery);
});

hub.on('data.th', function (sid, temperature, humidity, battery) {
    console.info('th', sid, temperature, humidity, battery);
});

hub.on('data.plug', function (sid, on) {
    console.info('plug', sid, on);
});

hub.on('data.weather', function (sid, temperature, humidity, pressure, battery) {
    console.info('th', sid, temperature, humidity, pressure, battery);
});

<|endoftext|>


<commit_before>function Middle(cb, ctx, init){
    "use strict";
    if (!(this instanceof Middle))
        throw new Error("Middle needs to be called with the new keyword");

    if(!init){
        var middleInstance = new Middle(cb, ctx, 'init'),
            bindedRun = middleInstance.run.bind(middleInstance),
            useInstance = new Middle(middleInstance.use, middleInstance, 'init'),
            useInstancebindedRun = useInstance.run.bind(useInstance);

        useInstancebindedRun.use = useInstance.use.bind(useInstance);
        bindedRun.use = useInstancebindedRun;
        return bindedRun;
    }

    if(typeof cb == 'function')
        this.callback = cb.bind(ctx == 'middleInstance' ? this : ctx || null);
    else
        this.callback = function () {};

    this._stack = [];
    this.id = Math.random(); // dev: contexts identification
}

Middle.prototype.run = function () {
    new Runner(this._stack, this.callback, arguments);
};

Middle.prototype.use = function (fn) {
    this._stack.push(fn);
};

Runner = function(stack, cb, args){
    this._stack = stack;
    this.callback = cb;

    if(!this._stack.length)
        return this.callback.apply(null, args);

    this._stackIndex = 0;
    this._stackLen = this._stack.length;
    return this.next.apply(this, args);
};

Runner.prototype.next = function() {
    if(this._stackIndex < this._stackLen){
        this._stackIndex++;
        this._stack[this._stackIndex - 1]
            .bind(null, this.next.bind(this))
            .apply(null, arguments);
    }else{
        this.callback.apply(null, arguments);
    }
};

// function argsToArray(argums) {
//     // https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/arguments
//      return (argums.length === 1 ? [argums[0]] : Array.apply(null, argums));
// }

// TEST: ===============================================================================

var myCallback = function (input) {
        input *= 10;
        console.log('myCallback result:', input, this.test);
    },
    cbCtx = {test: 'blue'},
    myCtx = {test: 'red'},
    mw = new Middle(myCallback, cbCtx),
    fn1 = function(next, input){
        input++;
        console.log('fn1', input, this.test);
        next(input);
    },
    fn2 = function(next, input){
        input++;
        console.log('fn2', input, this.test);
        setTimeout(function () {
            next(input); // simulating async task
        }, 1500);
    },
    fn3 = function(next, input){
        input++;
        console.log('fn3', input, this.test);
        next(input);
    };

mw.use.use(function (next, fn) {
    console.log('you added new middleware: ', fn);
    next(fn);
});
mw.use(fn1.bind(myCtx));
mw.use(fn2); // test is undefined
mw.use(fn3.bind(myCtx));
mw(10);
mw(10);
mw(15);<commit_msg>Middle can be used as method returning non primitive value, but only if you dont use middlewares :/ will solve this by MiddlePromise plugin<commit_after>function Middle(cb, ctx, init){
    "use strict";
    if (!(this instanceof Middle))
        throw new Error("Middle needs to be called with the new keyword");

    if(!init){
        var middleInstance = new Middle(cb, ctx, 'init'),
            bindedRun = middleInstance.run.bind(middleInstance),
            useInstance = new Middle(middleInstance.use, middleInstance, 'init'),
            useInstancebindedRun = useInstance.run.bind(useInstance);

        useInstancebindedRun.use = useInstance.use.bind(useInstance);
        bindedRun.use = useInstancebindedRun;
        return bindedRun;
    }

    if(typeof cb == 'function')
        this.callback = cb.bind(ctx == 'middleInstance' ? this : ctx || null);
    else
        this.callback = function () {};

    this._stack = [];
    this.id = Math.random(); // dev: contexts identification
}

Middle.prototype.run = function () {
    return new Runner(this._stack, this.callback, arguments);
};

Middle.prototype.use = function (fn) {
    this._stack.push(fn);
};

Runner = function(stack, cb, args){
    this._stack = stack;
    this.callback = cb;

    if(!this._stack.length)
        return this.callback.apply(null, args);

    this._stackIndex = 0;
    this._stackLen = this._stack.length;
    return this.next.apply(this, args);
};

Runner.prototype.next = function() {
    if(this._stackIndex < this._stackLen){
        this._stackIndex++;
        this._stack[this._stackIndex - 1]
            .bind(null, this.next.bind(this))
            .apply(null, arguments);
    }else{
        this.callback.apply(null, arguments);
    }
};

// TEST: ===============================================================================

var myCallback = function (input) {
        input *= 10;
        console.log('myCallback result:', input, this.test);
    },
    cbCtx = {test: 'blue'},
    myCtx = {test: 'red'},
    mw = new Middle(myCallback, cbCtx),
    fn1 = function(next, input){
        input++;
        console.log('fn1', input, this.test);
        next(input);
    },
    fn2 = function(next, input){
        input++;
        console.log('fn2', input, this.test);
        setTimeout(function () {
            next(input); // simulating async task
        }, 1500);
    },
    fn3 = function(next, input){
        input++;
        console.log('fn3', input, this.test);
        next(input);
    };

mw.use.use(function (next, fn) {
    console.log('you added new middleware: ', fn);
    next(fn);
});
mw.use(fn1.bind(myCtx));
mw.use(fn2); // test is undefined
mw.use(fn3.bind(myCtx));
mw(10);
mw(10);
mw(15);

var testObj = {
        someConstant: 10
    };

testObj.sum = new Middle(function(a, b){
    return {result: a+b+this.someConstant};
}, testObj);

console.log('returns result 18: ', testObj.sum(3, 5).result);<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import {
    TreeTable,
    TreeHeadCol
} from '../../lib/Index.js';
import {
    noKeyData,
    data,
    list
} from './fackData';

const Component = React.Component;

class Main extends Component {
    constructor() {
        super();
        this.state = {
            page: 1,
            list: [],
            length: 10,
            data: data,
            selected: [],
            expandRowKeys: []
        }
    }

    componentWillMount() {
        fetch('http://localhost:3000/list').then(res => {
            return res.json();
        }).then(json => {
            this.setState({
                list: json
            })
        })
    }

    handleClick(display, data, callback) {
        if (!display) {
            fetch('http://localhost:3000/get?a=8').then(res => {
                return res.json();
            }).then(json => {
                data.list.push(json[0]);
                callback(data);
            })
        } else {
            callback(data);
        }
    }

    handleArrowClick(display, data, cb) {
        if (!display && data.chdatalist && !data.chdatalist.length) {
            this.setState(old => {
                old.loading = true;
                return old;
            });
            fetch(`http://localhost:3000/detail?year=${data.year}&time=${data.time}&datatype=0`).then(res => {
                return res.json();
            }).then(json => {
                data.chdatalist = json;
                cb(data);
                this.setState(old => {
                    old.loading = false;
                    old.expandRowKeys.push(data.uniqueKey);
                    return old;
                });
            });
        } else {
            cb(data);
            if (display) {
                this.setState(old => {
                    old.expandRowKeys.splice(old.expandRowKeys.indexOf(data.uniqueKey), 1);
                    return old;
                });
            } else {
                this.setState(old => {
                    old.expandRowKeys.push(data.uniqueKey);
                    return old;
                });
            }
        }
    }

    headRender() {
        return [{
            id: 'columnName',
            name: ' '
        }, {
            id: 'rate',
            name: '提货费率'
        }, {
            id: 'averageCost',
            name: '提货单均成本'
        }, {
            id: 'cost',
            name: '提货成本'
        }, {
            id: 'orderMoney',
            name: '提货订单金额'
        }, {
            id: 'orderNum',
            name: '提货订单量'
        }, {
            id: 'customerNum',
            name: '提货客户数'
        }, {
            id: 'volume',
            name: '提货体积'
        }, {
            id: 'weight',
            name: '提货重量'
        }];
    }

    showArrow(cell, level, row, index, col) {
        if (row.a == 1) {
            return false
        }
        return true;
    }

    render() {
        const dataFormat = {
            "a": function (cell, level, row) {
                return cell + ' I am level ' + level
            },
            "b": function (cell, level, row, index, col) {
                if (level != 0) {
                    // let key = col[index - 1];
                    // return row[key.id || key];
                    return '';
                } else {
                    return cell + ' I am row b'
                }
            },
            "c": function (cell, level, row, index, col) {
                if (level != 0) {
                    let key = col[index - 2];
                    return row[key.id || key];
                } else {
                    return cell
                }
            },
            "d": function (cell, level, row, index, col) {
                if (level != 0) {
                    let key = col[index - 1];
                    return row[key.id || key];
                } else {
                    return cell + 1
                }
            }
        };
        const options = {
            page: 1,
            sizePerPage: 1,
            sizePageList: [10, 20, 30],
            paginationShowsTotal: true,
            onPageChange: function (page, sizePerPage) {

            }
        };

        const selectRow = {
            mode: "checkbox",
            bgColor: "rgb(238, 193, 213)",
            selected: this.state.selected,
            hideSelectColumn: false,
            onSelectAll: (checked, currentSelected) => {
                if (checked) {
                    let checkedList = currentSelected.map(item => {
                        return item.id;
                    });
                    this.setState(old => {
                        old.selected = checkedList;
                        return old;
                    })
                } else {
                    this.setState(old => {
                        old.selected = [];
                        return old;
                    })
                }
            },
            onSelect: (checked, row) => {
                if (checked) {
                    this.setState(old => {
                        old.selected.push(row.id);
                        return old
                    })
                } else {
                    this.setState(old => {
                        old.selected.splice(old.selected.indexOf(row.id), 1);
                        return old;
                    })
                }
            }
        };
        const style = {
            margin: "20px",
            background: "#fff"
        };
        return (

                    <TreeTable
                        iskey="a"
                        data={data}
                        nestedHead={[[{
                            label: '全国',
                            colspan: 4,
                            rowspan: 2
                        }, 'a', 'a', 'a', 'a'], ['b', 'b', 'b', 'b']]}
                    >
                        <TreeHeadCol width={200} dataField="a" dataFormat={dataFormat.a}>第一列</TreeHeadCol>
                        <TreeHeadCol dataField="b" dataSort={true} width={200}
                                     dataFormat={dataFormat.a}>第二列</TreeHeadCol>
                        <TreeHeadCol width={200} dataField="c" dataSort={true}
                                     dataFormat={dataFormat.a}>第三列</TreeHeadCol>
                        <TreeHeadCol width={200} dataField="d" hidden={false}>第四列</TreeHeadCol>
                        <TreeHeadCol width={200} dataField="d" hidden={false}>第五列</TreeHeadCol>
                        <TreeHeadCol dataField="d" hidden={false}>第六列</TreeHeadCol>
                        <TreeHeadCol dataField="d" hidden={true}>第七列</TreeHeadCol>
                        <TreeHeadCol width={150} dataFormat={()=> {
                            return freedom!
                        }}>操作</TreeHeadCol>
                    </TreeTable>

                    <TreeTable
                        height="auto"
                        hashKey={true}
                        data={noKeyData}
                        pagination={true}
                        options={options}
                        onArrowClick={this.handleClick.bind(this)}
                    >
                        <TreeHeadCol dataField="a">第一列</TreeHeadCol>
                        <TreeHeadCol dataField="b">第二列</TreeHeadCol>
                        <TreeHeadCol dataField="c">第三列</TreeHeadCol>
                        <TreeHeadCol dataField="d">第四列</TreeHeadCol>
                    </TreeTable>

                    <TreeTable
                        iskey="id"
                        data={list}
                        isTree={false}
                        pagination={false}
                        selectRow={selectRow}
                    >
                        <TreeHeadCol dataField="id" dataAlign="center" dataFixed="left">id</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='regionRoleName'
                                     dataFixed="left">区域角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataSort={true}
                                     dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='region'
                                     dataFixed="left">区域</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='description'
                                     dataFixed="right">描述</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataFormat={()=> {
                            return freedom!
                        }}>操作</TreeHeadCol>
                    </TreeTable>

                    <TreeTable iskey='uniqueKey'
                               childrenPropertyName='chdatalist'
                               data={this.state.list} hover={false} onArrowClick={this.handleArrowClick.bind(this)}
                    >
                        {
                            this.headRender().map((item, index)=> {
                                return <TreeHeadCol key={index} dataAlign='center' showArrow={true}
                                                    dataField={item.id}>{item.name}</TreeHeadCol>
                            })
                        }
                    </TreeTable>

        )
    }
}

ReactDOM.render(, document.querySelector('.main'));<commit_msg>Update index.js<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import {
    TreeTable,
    TreeHeadCol
} from '../../lib/Index.js';
import {
    noKeyData,
    data,
    list
} from './fackData';

const Component = React.Component;

class Main extends Component {
    constructor() {
        super();
        this.state = {
            page: 1,
            list: [],
            length: 10,
            data: data,
            selected: [],
            expandRowKeys: []
        }
    }

    componentWillMount() {
        fetch('http://localhost:3000/list').then(res => {
            return res.json();
        }).then(json => {
            this.setState({
                list: json
            })
        })
    }

    handleClick(display, data, callback) {
        if (!display) {
            fetch('http://localhost:3000/get?a=8').then(res => {
                return res.json();
            }).then(json => {
                data.list.push(json[0]);
                callback(data);
            })
        } else {
            callback(data);
        }
    }

    handleArrowClick(display, data, cb) {
        if (!display && data.chdatalist && !data.chdatalist.length) {
            this.setState(old => {
                old.loading = true;
                return old;
            });
            fetch(`http://localhost:3000/detail?year=${data.year}&time=${data.time}&datatype=0`).then(res => {
                return res.json();
            }).then(json => {
                data.chdatalist = json;
                cb(data);
                this.setState(old => {
                    old.loading = false;
                    old.expandRowKeys.push(data.uniqueKey);
                    return old;
                });
            });
        } else {
            cb(data);
            if (display) {
                this.setState(old => {
                    old.expandRowKeys.splice(old.expandRowKeys.indexOf(data.uniqueKey), 1);
                    return old;
                });
            } else {
                this.setState(old => {
                    old.expandRowKeys.push(data.uniqueKey);
                    return old;
                });
            }
        }
    }

    headRender() {
        return [{
            id: 'columnName',
            name: ' '
        }, {
            id: 'rate',
            name: '提货费率'
        }, {
            id: 'averageCost',
            name: '提货单均成本'
        }, {
            id: 'cost',
            name: '提货成本'
        }, {
            id: 'orderMoney',
            name: '提货订单金额'
        }, {
            id: 'orderNum',
            name: '提货订单量'
        }, {
            id: 'customerNum',
            name: '提货客户数'
        }, {
            id: 'volume',
            name: '提货体积'
        }, {
            id: 'weight',
            name: '提货重量'
        }];
    }

    showArrow(cell, level, row, index, col) {
        if (row.a == 1) {
            return false
        }
        return true;
    }

    render() {
        const dataFormat = {
            "a": function (cell, level, row) {
                return cell + ' I am level ' + level
            },
            "b": function (cell, level, row, index, col) {
                if (level != 0) {
                    // let key = col[index - 1];
                    // return row[key.id || key];
                    return '';
                } else {
                    return cell + ' I am row b'
                }
            },
            "c": function (cell, level, row, index, col) {
                if (level != 0) {
                    let key = col[index - 2];
                    return row[key.id || key];
                } else {
                    return cell
                }
            },
            "d": function (cell, level, row, index, col) {
                if (level != 0) {
                    let key = col[index - 1];
                    return row[key.id || key];
                } else {
                    return cell + 1
                }
            }
        };
        const options = {
            page: 1,
            sizePerPage: 1,
            sizePageList: [10, 20, 30],
            paginationShowsTotal: true,
            onPageChange: function (page, sizePerPage) {

            }
        };

        const selectRow = {
            mode: "checkbox",
            bgColor: "rgb(238, 193, 213)",
            selected: this.state.selected,
            hideSelectColumn: false,
            onSelectAll: (checked, currentSelected) => {
                if (checked) {
                    let checkedList = currentSelected.map(item => {
                        return item.id;
                    });
                    this.setState(old => {
                        old.selected = checkedList;
                        return old;
                    })
                } else {
                    this.setState(old => {
                        old.selected = [];
                        return old;
                    })
                }
            },
            onSelect: (checked, row) => {
                if (checked) {
                    this.setState(old => {
                        old.selected.push(row.id);
                        return old
                    })
                } else {
                    this.setState(old => {
                        old.selected.splice(old.selected.indexOf(row.id), 1);
                        return old;
                    })
                }
            }
        };
        const style = {
            margin: "20px",
            background: "#fff"
        };
        return (

                    <TreeTable
                        iskey="a"
                        data={data}
                        nestedHead={[[{
                            label: '全国',
                            colspan: 4,
                            rowspan: 2
                        }, 'a', 'a', 'a', 'a'], ['b', 'b', 'b', 'b']]}
                    >
                        <TreeHeadCol width={200} dataField="a" dataFormat={dataFormat.a}>第一列</TreeHeadCol>
                        <TreeHeadCol dataField="b" dataSort={true} width={200}
                                     dataFormat={dataFormat.a}>第二列</TreeHeadCol>
                        <TreeHeadCol width={200} dataField="c" dataSort={true}
                                     dataFormat={dataFormat.a}>第三列</TreeHeadCol>
                        <TreeHeadCol width={200} dataField="d" hidden={false}>第四列</TreeHeadCol>
                        <TreeHeadCol width={200} dataField="d" hidden={false}>第五列</TreeHeadCol>
                        <TreeHeadCol dataField="d" hidden={false}>第六列</TreeHeadCol>
                        <TreeHeadCol dataField="d" hidden={true}>第七列</TreeHeadCol>
                        <TreeHeadCol width={150} dataFormat={()=> {
                            return freedom!
                        }}>操作</TreeHeadCol>
                    </TreeTable>

                    <TreeTable
                        height="auto"
                        hashKey={true}
                        data={noKeyData}
                        pagination={true}
                        options={options}
                        onArrowClick={this.handleClick.bind(this)}
                    >
                        <TreeHeadCol dataField="a">第一列</TreeHeadCol>
                        <TreeHeadCol dataField="b">第二列</TreeHeadCol>
                        <TreeHeadCol dataField="c">第三列</TreeHeadCol>
                        <TreeHeadCol dataField="d">第四列</TreeHeadCol>
                    </TreeTable>

                    <TreeTable
                        iskey="id"
                        data={list}
                        isTree={false}
                        pagination={false}
                        selectRow={selectRow}
                    >
                        <TreeHeadCol dataField="id" dataAlign="center" dataFixed="left">id</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='regionRoleName'
                                     dataFixed="left">区域角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataSort={true}
                                     dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='systemRoleName'>系统角色</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='region'
                                     dataFixed="left">区域</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='createTime'>创建时间</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataField='description'
                                     dataFixed="right">描述</TreeHeadCol>
                        <TreeHeadCol dataAlign='center' width="150px" dataFormat={()=> {
                            return freedom!
                        }}>操作</TreeHeadCol>
                    </TreeTable>

                    <TreeTable iskey='uniqueKey'
                               childrenPropertyName='chdatalist' expandRowKeys={this.state.expandRowKeys}
                               data={this.state.list} hover={false} onArrowClick={this.handleArrowClick.bind(this)}
                    >
                        {
                            this.headRender().map((item, index)=> {
                                return <TreeHeadCol key={index} dataAlign='center' showArrow={true}
                                                    dataField={item.id}>{item.name}</TreeHeadCol>
                            })
                        }
                    </TreeTable>

        )
    }
}

ReactDOM.render(, document.querySelector('.main'));
<|endoftext|>


<commit_before>function load_js( uri, id ) {
    var script_tag = document.getElementById( id );
    if( script_tag ) {
        script_tag.parentNode.removeChild( script_tag );
    }

    /* To force browser cache update */
    $.get( uri );

    var script  = document.createElement( 'SCRIPT' );
    script.type = 'text/javascript';
    script.src  = uri;
    script.id   = id;
    document.getElementsByTagName('head')[0].appendChild( script );
}

( function() {
    load_js( 'http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js', 'selfmarks-jquery' );
    var href = '#{Selfmarks::HOST}/uri/add_window.js?uri=' + encodeURIComponent( window.location.href ) +
        '&title=' + encodeURIComponent( document.title );
    load_js( href, 'selfmarks-javascript' );
} )();
<commit_msg>Only use jQuery object if defined/loaded.<commit_after>function load_js( uri, id ) {
    var script_tag = document.getElementById( id );
    if( script_tag ) {
        script_tag.parentNode.removeChild( script_tag );
    }

    if( typeof( jQuery ) != 'undefined' ) {
        /* To force browser cache update */
        jQuery.get( uri );
    }

    var script  = document.createElement( 'SCRIPT' );
    script.type = 'text/javascript';
    script.src  = uri;
    script.id   = id;
    document.getElementsByTagName('head')[0].appendChild( script );
}

( function() {
    load_js( 'http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js', 'selfmarks-jquery' );
    var href = '#{Selfmarks::HOST}/uri/add_window.js?uri=' + encodeURIComponent( window.location.href ) +
        '&title=' + encodeURIComponent( document.title );
    load_js( href, 'selfmarks-javascript' );
} )();
<|endoftext|>


<commit_before>const now = require('performance-now');

function write(key, execTimeMs, graphiteClient) {
    const result = {};
    result[key] = execTimeMs;

    graphiteClient.write(result, function(err) {
        if (err) {
            console.error('graphite client write error', err);
        }
    });
}

module.exports = function Metered(key, graphiteClient) {
    return function(object, name, descriptor) {
        const originalMethod = descriptor.value;
        descriptor.value = function(...args) {
            const start = now();
            let result = originalMethod.apply(object, args);
            if (result && typeof result.then === 'function') {
                return result.then((val) => {
                    const execTimeMs = (now() - start).toFixed(3);
                    write(key, execTimeMs, graphiteClient);

                    return val;
                });
            }

            const execTimeMs = (now() - start).toFixed(3);
            write(key, execTimeMs, graphiteClient);
            return result;
        };
    }
};<commit_msg>fixed context in Metered method<commit_after>const now = require('performance-now');

function write(key, execTimeMs, graphiteClient) {
    const result = {};
    result[key] = execTimeMs;

    graphiteClient.write(result, function(err) {
        if (err) {
            console.error('graphite client write error', err);
        }
    });
}

module.exports = function Metered(key, graphiteClient) {
    return function(object, name, descriptor) {
        const originalMethod = descriptor.value;
        descriptor.value = function(...args) {
            const start = now();
            let result = originalMethod.apply(this, args);
            if (result && typeof result.then === 'function') {
                return result.then((val) => {
                    const execTimeMs = (now() - start).toFixed(3);
                    write(key, execTimeMs, graphiteClient);

                    return val;
                });
            }

            const execTimeMs = (now() - start).toFixed(3);
            write(key, execTimeMs, graphiteClient);
            return result;
        };
    }
};<|endoftext|>


<commit_before>var startTest = top.startTest;
var test = top.test;
var endTest = top.endTest;
var prep = top.prep;
<commit_msg>Added some dummy functions for the HTML runner (for testing).<commit_after>var startTest = top.startTest || function(){};
var test = top.test || function(name, fn){ fn(); };
var endTest = top.endTest || function(){};
var prep = top.prep || function(fn){ fn(); };
<|endoftext|>


<commit_before>/*

Uses the Google Sheets API to pull data from Sheets and load it onto shared
state. Writes the data out to JSON for later reference. Does not currently
check for existing data to merge--it does a fresh pull every time.

Sheets must be both A) shared publicly and B) "published to web" before they
can be accessed by this task.

*/

var project = require("../project.json");
var async = require("async");
var sheets = require("google-spreadsheets");

var camelCase = function(str) {
  return str.replace(/[^\w]+(\w)/g, function(all, match) {
    return match.toUpperCase();
  });
};

var cast = function(str) {
  if (typeof str !== "string") return str;
  if (str.match(/^[\d\.,]+$/)) {
    //number
    return Number(str.replace(/,/g, ""));
  }
  if (str.toLowerCase() == "true" || str.toLowerCase() == "false") {
    return str.toLowerCase() == "true" ? true : false;
  }
  return str;
};

module.exports = function(grunt) {

  grunt.registerTask("sheets", "Downloads from Google Sheets -> JSON", function() {

    var auth = {};
    try {
      auth = require("../auth.json");
    } catch (_) { /* no auth.json, that's fine */ }
    var sheetKeys = project.sheets || (auth.google && auth.google.sheets);

    if (!sheetKeys || !sheetKeys.length) {
      return grunt.fail.fatal("You must specify a spreadsheet key in project.json or auth.json!");
    }

    var done = this.async();

    async.each(sheetKeys, function(key, bookDone) {
      sheets({
        key: key,
        worksheet: 1
      }, function(err, book) {
        if (err || !book) {
          grunt.fail.warn("Unable to access book for " + key + ", is it 'published' in Sheets?");
          return bookDone();
        }
        //download each worksheet
        async.each(book.worksheets, function(page, pageDone) {
          page.rows({}, function(err, rows) {
            if (err) {
              grunt.fail.warn("Couldn't load sheet for " + book.title);
              return pageDone();
            }
            //don't break on zero-length sheets
            if (rows.length === 0) return pageDone();
            //remove extraneous GApps detail
            rows.forEach(function(row) {
              delete row.updated;
              delete row.content;
              if (typeof row.id == "object") delete row.id;
              //eliminate empty cells, which get a weird placeholder object
              for (var key in row) {
                var prop = row[key];
                if (typeof prop == "object" && "$t" in prop && prop.$t === "") {
                  prop = "";
                }
                row[key] = cast(prop);
              }
            });
            //is this a keyed sheet, instead of a numbered list?
            if ("key" in rows[0]) {
              var obj = {};
              rows.forEach(function(row) {
                obj[row.key] = row;
                //sheets adds a title for some reason
                if (row.title == row.key) delete row.title;
                delete row.key;
              });
              rows = obj;
            }
            var filename = "data/" + camelCase(book.title) + "_" + camelCase(page.title) + ".sheet.json";
            grunt.file.write(filename, JSON.stringify(rows, null, 2));
            pageDone();
          });
        }, function() {
          //when done with all sheets, continue
          bookDone();
        });
      });
    }, function() {
      return done();
    });

  });

};
<commit_msg>Respect uppercase/whitespace column names in Sheets<commit_after>/*

Uses the Google Sheets API to pull data from Sheets and load it onto shared
state. Writes the data out to JSON for later reference. Does not currently
check for existing data to merge--it does a fresh pull every time.

Sheets must be both A) shared publicly and B) "published to web" before they
can be accessed by this task.

*/

var project = require("../project.json");
var async = require("async");
var sheets = require("google-spreadsheets");

var camelCase = function(str) {
  return str.replace(/[^\w]+(\w)/g, function(all, match) {
    return match.toUpperCase();
  });
};

var cast = function(str) {
  if (typeof str !== "string") {
    if (typeof str.value == "string") {
      str = str.value;
    } else {
      return str;
    }
  }
  if (str.match(/^[\d\.,]+$/)) {
    //number
    return Number(str.replace(/,/g, ""));
  }
  if (str.toLowerCase() == "true" || str.toLowerCase() == "false") {
    return str.toLowerCase() == "true" ? true : false;
  }
  return str;
};

module.exports = function(grunt) {

  grunt.registerTask("sheets", "Downloads from Google Sheets -> JSON", function() {

    var auth = {};
    try {
      auth = require("../auth.json");
    } catch (_) { /* no auth.json, that's fine */ }
    var sheetKeys = project.sheets || (auth.google && auth.google.sheets);

    if (!sheetKeys || !sheetKeys.length) {
      return grunt.fail.fatal("You must specify a spreadsheet key in project.json or auth.json!");
    }

    var done = this.async();

    async.each(sheetKeys, function(key, bookDone) {
      sheets({
        key: key,
        worksheet: 1
      }, function(err, book) {
        if (err || !book) {
          grunt.fail.warn("Unable to access book for " + key + ", is it 'published' in Sheets?");
          return bookDone();
        }
        //download each worksheet
        async.each(book.worksheets, function(page, pageDone) {
          sheets.cells({ key: key, worksheet: page.id }, function(err, cells) {
            if (err) {
              grunt.fail.warn("Couldn't load sheet for " + book.title);
              return pageDone();
            }
            cells = cells.cells;

            //get the header row
            var rowNumbers = Object.keys(cells);
            var headerNumber = rowNumbers.shift();
            var headers = cells[headerNumber];
            var isKeyed = false;
            for (var cell in headers) {
              headers[cell] = headers[cell].value;
              if (headers[cell] == "key") {
                isKeyed = true;
              }
            }

            var output = isKeyed ? {} : [];

            //create the rows
            rowNumbers.forEach(function(rowNum) {
              var line = cells[rowNum];
              var columnNumbers = Object.keys(line);
              var row = {};
              columnNumbers.forEach(function(colNum) {
                var value = line[colNum];
                var key = headers[colNum];
                row[key] = cast(value);
              });
              if (isKeyed) {
                output[row.key] = row;
                delete row.key;
              } else {
                output.push(row);
              }
            });

            var filename = "data/" + camelCase(book.title) + "_" + camelCase(page.title) + ".sheet.json";
            grunt.file.write(filename, JSON.stringify(output, null, 2));
            pageDone();
          });
        }, function() {
          //when done with all sheets, continue
          bookDone();
        });
      });
    }, function() {
      return done();
    });

  });

};
<|endoftext|>


<commit_before>function init(maxLevel) {
    initRotationPanel(maxLevel);
    car.setMaxLevel(maxLevel);
    initEvent();
}

function rotate(element, angle) {
    element.style.transform = "rotate(" + angle + "deg)";
}

function findPos(element) {
    if (element) {
        var parentPos = findPos(element.offsetParent);
        return [
            parentPos[0]+ element.offsetLeft,
            parentPos[0]+ element.offsetTop
        ];
    } else {
        return [0, 0];
    }
}

function calAngle(pointA, pointB, pointO) {
    var aox = pointA[0] - pointO[0];
    var aoy = pointA[1] - pointO[1];
    var box = pointB[0] - pointO[0];
    var boy = pointB[1] - pointO[1];

    var part1 = aox * box + aoy * boy;
    var part2 = Math.sqrt((aox * aox + aoy * aoy) * (box * box + boy * boy));
    var angleAOB = Math.acos(part1 / part2) / Math.PI * 180;
    var msg = "A:" + pointA + " B:" + pointB + " O:" + pointO + " angle:" + Math.floor(angleAOB) + " md:" + car.getMd();
    showMsg(msg);

    var otherAoy = aox * boy / box;
    if (otherAoy > aoy) {
        angleAOB = -angleAOB;
    }
    return angleAOB;
}

function findCenterPos(element) {
    var pos = findPos(element);
    return [
        element.offsetWidth / 2 + pos[0],
        element.offsetHeight / 2 + pos[1]
    ];
}

function initEvent() {
    var innerCycle = document.getElementById("inner_cycle");
    var pos = findCenterPos(innerCycle);
    var centerOfSelectorContainerX = pos[0], centerOfSelectorContainerY = pos[1];
    pos = findCenterPos(document.getElementById("selector"));
    var selectorStartX = pos[0], selectorStartY = pos[1];

    function preventEvent(event) {
        var e = event || window.event;
        e.preventDefault && e.preventDefault();
        e.stopPropagation && e.stopPropagation();
        e.cancelBubble = true;
        e.returnValue = false;
        return false;
    }

    function findTouchById(touches, id) {
        for (var i = 0; i < touches.length; ++i) {
            if (touches[i].target.id == id) {
                return touches[i];
            }
        }
        return null;
    }

    function onSelectorDown(event) {
        return preventEvent(event);
    }

    function onSelectorUp(event) {
        rotate(innerCycle, 0);
        car.setRl(0);
        return preventEvent(event);
    }

    function onSelectorMove(event) {
        var touchPoint = findTouchById(event.changedTouches, event.target.id);
        if (touchPoint != null) {
            var selectorStartX1 = parseInt(touchPoint.clientX);
            var selectorStartY1 = parseInt(touchPoint.clientY);
            var angle = calAngle([selectorStartX1, selectorStartY1], [selectorStartX, selectorStartY], [centerOfSelectorContainerX, centerOfSelectorContainerY]);
            rotate(innerCycle, angle);
            var level = angle / (360 / (car.getMaxLevel() * 2 + 1));
            car.setRl(level > 0 ? Math.floor(level): Math.ceil(level));
        }
        return preventEvent(event);
    }

    function onForwardBtnDown(event) {
        car.goForward();
        return preventEvent(event);
    }

    function onForwardBtnUp(event) {
        car.stop();
        return preventEvent(event);
    }

    function onBackwardBtnDown(event) {
        car.goBackward();
        return preventEvent(event);
    }

    function onBackwardBtnUp(event) {
        car.stop();
        return preventEvent(event);
    }

    var selector = document.getElementById("selector");
    selector.ontouchstart = onSelectorDown;
    selector.ontouchend = onSelectorUp;
    selector.ontouchmove = onSelectorMove;

    var forwardBtn = document.getElementById("forward_btn");
    forwardBtn.ontouchstart = onForwardBtnDown;
    forwardBtn.ontouchend = onForwardBtnUp;

    var backwardBtn = document.getElementById("backward_btn");
    backwardBtn.ontouchstart = onBackwardBtnDown;
    backwardBtn.ontouchend = onBackwardBtnUp;
}

function initRotationPanel(maxLevel) {
    var amount = 2 * maxLevel + 1;
    var angle = 360 / amount;
    var template = document.getElementById("number_cycle_template");
    var container = template.parentNode;
    container.removeChild(template);

    for (var i = 1; i <= amount; ++i) {
        var pos = i - amount + maxLevel;
        var newNumber = template.cloneNode(true);
        newNumber.id = "number_cycle_" + i;
        rotate(newNumber, pos * angle);
        newNumber.style.backgroundColor = "transparent";
        var number = newNumber.getElementsByClassName("number")[0];
        rotate(number, -pos * angle);
        number.innerHTML = pos;
        container.appendChild(newNumber);
    }

    var innerCycle = document.getElementById("inner_cycle");
    container.removeChild(innerCycle);
    container.appendChild(innerCycle);
}

Car.prototype = {

    _init: function() {
        this._md = 0;
        this._rl = 0;
        this._xmlHttp = new XMLHttpRequest();
        this._xmlHttp.onreadystatechange = null;
    },

    setMaxLevel: function(maxLevel) {
        this._maxLevel = maxLevel
    },

    getMaxLevel: function() {
        return this._maxLevel;
    },

    getMd: function() {
        return this._md;
    },

    goForward: function() {
        this._md = 1;
        this.flush();
    },

    goBackward: function() {
        this._md = 2;
        this.flush();
    },

    stop: function() {
        this._md = 0;
        this.flush();
    },

    setRl: function(level) {
        if (level <= this._maxLevel && level >= -this._maxLevel && this._rl != level) {
            this._rl = level;
            this.flush();
        }
    },

    flush: function() {
        var tmpCar = this
        if (this._xmlHttp.onreadystatechange == null) {
            this._xmlHttp.onreadystatechange = function() {
                if (this.readyState == 4) {
                    // 4 = "loaded"
                    var error = true;
                    if (this.status == 200) {
                        // 200 = OK
                        var retObj = JSON.parse(this.responseText);
                        if (retObj.retcode == "0") {
                            msg = "md: " + tmpCar._md + " rl: " + tmpCar._rl;
                            error = false;
                        }
                        else {
                            msg = this.responseText;
                        }
                    }
                    else {
                        msg = "Http Error: " + this.status;
                    }
                    if (error) {
                        showErrMsg(msg);
                    }
                    else {
                        showMsg(msg);
                    }
                }
            }
        }
        url = "/control?rl=" + this._rl + "&md=" + this._md;
        this._xmlHttp.open("GET", url, true);
        this._xmlHttp.send(null);
    },
}

function showMsg(msg) {
    var msgContent = document.getElementById("msg_content");
    msgContent.innerHTML = msg;
    msgContent.classList.remove("error");
}

function showErrMsg(msg) {
    var msgContent = document.getElementById("msg_content");
    msgContent.innerHTML = msg;
    msgContent.classList.add("error");
}

function Car() {
    this._init();
}

car = new Car();
<commit_msg>optimized: avoid level jumpping too far away.<commit_after>function init(maxLevel) {
    initRotationPanel(maxLevel);
    car.setMaxLevel(maxLevel);
    initEvent();
}

function rotate(element, angle) {
    element.style.transform = "rotate(" + angle + "deg)";
}

function findPos(element) {
    if (element) {
        var parentPos = findPos(element.offsetParent);
        return [
            parentPos[0]+ element.offsetLeft,
            parentPos[0]+ element.offsetTop
        ];
    } else {
        return [0, 0];
    }
}

function calAngle(pointA, pointB, pointO) {
    var aox = pointA[0] - pointO[0];
    var aoy = pointA[1] - pointO[1];
    var box = pointB[0] - pointO[0];
    var boy = pointB[1] - pointO[1];

    var part1 = aox * box + aoy * boy;
    var part2 = Math.sqrt((aox * aox + aoy * aoy) * (box * box + boy * boy));
    var angleAOB = Math.acos(part1 / part2) / Math.PI * 180;
    var msg = "A:" + pointA + " B:" + pointB + " O:" + pointO + " angle:" + Math.floor(angleAOB) + " md:" + car.getMd() + " rl:" + car.getRl();
    showMsg(msg);

    var otherAoy = aox * boy / box;
    if (otherAoy > aoy) {
        angleAOB = -angleAOB;
    }
    return angleAOB;
}

function findCenterPos(element) {
    var pos = findPos(element);
    return [
        element.offsetWidth / 2 + pos[0],
        element.offsetHeight / 2 + pos[1]
    ];
}

function initEvent() {
    var innerCycle = document.getElementById("inner_cycle");
    var pos = findCenterPos(innerCycle);
    var centerOfSelectorContainerX = pos[0], centerOfSelectorContainerY = pos[1];
    pos = findCenterPos(document.getElementById("selector"));
    var selectorStartX = pos[0], selectorStartY = pos[1];

    function preventEvent(event) {
        var e = event || window.event;
        e.preventDefault && e.preventDefault();
        e.stopPropagation && e.stopPropagation();
        e.cancelBubble = true;
        e.returnValue = false;
        return false;
    }

    function findTouchById(touches, id) {
        for (var i = 0; i < touches.length; ++i) {
            if (touches[i].target.id == id) {
                return touches[i];
            }
        }
        return null;
    }

    function onSelectorDown(event) {
        return preventEvent(event);
    }

    function onSelectorUp(event) {
        rotate(innerCycle, 0);
        car.setRl(0);
        return preventEvent(event);
    }

    function onSelectorMove(event) {
        var touchPoint = findTouchById(event.changedTouches, event.target.id);
        if (touchPoint != null) {
            var selectorStartX1 = parseInt(touchPoint.clientX);
            var selectorStartY1 = parseInt(touchPoint.clientY);
            var angle = calAngle([selectorStartX1, selectorStartY1], [selectorStartX, selectorStartY], [centerOfSelectorContainerX, centerOfSelectorContainerY]);
            var level = angle / (360 / (car.getMaxLevel() * 2 + 1));
            if (level - car.getRl() <= 2 && level - car.getRl() >= -2) {
                rotate(innerCycle, angle);
                car.setRl(level > 0 ? Math.floor(level): Math.ceil(level));
            }
        }
        return preventEvent(event);
    }

    function onForwardBtnDown(event) {
        car.goForward();
        return preventEvent(event);
    }

    function onForwardBtnUp(event) {
        car.stop();
        return preventEvent(event);
    }

    function onBackwardBtnDown(event) {
        car.goBackward();
        return preventEvent(event);
    }

    function onBackwardBtnUp(event) {
        car.stop();
        return preventEvent(event);
    }

    var selector = document.getElementById("selector");
    selector.ontouchstart = onSelectorDown;
    selector.ontouchend = onSelectorUp;
    selector.ontouchmove = onSelectorMove;

    var forwardBtn = document.getElementById("forward_btn");
    forwardBtn.ontouchstart = onForwardBtnDown;
    forwardBtn.ontouchend = onForwardBtnUp;

    var backwardBtn = document.getElementById("backward_btn");
    backwardBtn.ontouchstart = onBackwardBtnDown;
    backwardBtn.ontouchend = onBackwardBtnUp;
}

function initRotationPanel(maxLevel) {
    var amount = 2 * maxLevel + 1;
    var angle = 360 / amount;
    var template = document.getElementById("number_cycle_template");
    var container = template.parentNode;
    container.removeChild(template);

    for (var i = 1; i <= amount; ++i) {
        var pos = i - amount + maxLevel;
        var newNumber = template.cloneNode(true);
        newNumber.id = "number_cycle_" + i;
        rotate(newNumber, pos * angle);
        newNumber.style.backgroundColor = "transparent";
        var number = newNumber.getElementsByClassName("number")[0];
        rotate(number, -pos * angle);
        number.innerHTML = pos;
        container.appendChild(newNumber);
    }

    var innerCycle = document.getElementById("inner_cycle");
    container.removeChild(innerCycle);
    container.appendChild(innerCycle);
}

Car.prototype = {

    _init: function() {
        this._md = 0;
        this._rl = 0;
        this._xmlHttp = new XMLHttpRequest();
        this._xmlHttp.onreadystatechange = null;
    },

    setMaxLevel: function(maxLevel) {
        this._maxLevel = maxLevel
    },

    getMaxLevel: function() {
        return this._maxLevel;
    },

    getMd: function() {
        return this._md;
    },

    goForward: function() {
        this._md = 1;
        this.flush();
    },

    goBackward: function() {
        this._md = 2;
        this.flush();
    },

    stop: function() {
        this._md = 0;
        this.flush();
    },

    setRl: function(level) {
        if (level <= this._maxLevel && level >= -this._maxLevel && this._rl != level) {
            this._rl = level;
            this.flush();
        }
    },

    getRl: function() {
        return this._rl;
    },

    flush: function() {
        var tmpCar = this
        if (this._xmlHttp.onreadystatechange == null) {
            this._xmlHttp.onreadystatechange = function() {
                if (this.readyState == 4) {
                    // 4 = "loaded"
                    var error = true;
                    if (this.status == 200) {
                        // 200 = OK
                        var retObj = JSON.parse(this.responseText);
                        if (retObj.retcode == "0") {
                            msg = "md: " + tmpCar._md + " rl: " + tmpCar._rl;
                            error = false;
                        }
                        else {
                            msg = this.responseText;
                        }
                    }
                    else {
                        msg = "Http Error: " + this.status;
                    }
                    if (error) {
                        showErrMsg(msg);
                    }
                    else {
                        showMsg(msg);
                    }
                }
            }
        }
        url = "/control?rl=" + this._rl + "&md=" + this._md;
        this._xmlHttp.open("GET", url, true);
        this._xmlHttp.send(null);
    },
}

function showMsg(msg) {
    var msgContent = document.getElementById("msg_content");
    msgContent.innerHTML = msg;
    msgContent.classList.remove("error");
}

function showErrMsg(msg) {
    var msgContent = document.getElementById("msg_content");
    msgContent.innerHTML = msg;
    msgContent.classList.add("error");
}

function Car() {
    this._init();
}

car = new Car();
<|endoftext|>


<commit_before>function getInput() {
    var input =prompt("Please choose either rock, paper, or scissors.");
    console.log(input);
    return input;
    }
function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber <= 0.33) {
        return "rock";
    } else if (randomNumber <= 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
}
//console.log(getInput());
//console.log(randomPlay());
function getPlayerMove(move) {
    // If a `move` has a value, your expression should evaluate to that value
    if ((move===undefined)||(move===null)){
        return getInput();
    } else {
        //console.log("hmm I'm not understanding something!");
        return getInput();
    }
}
function getComputerMove(move) {
    //If `move` is not specified / is null, your expression should equal `randomPlay()`.
    if (move==undefined){
        return randomPlay();
    } else if ((move==="rock")||(move==="paper")||(move==="scissors")){
        return move;
    } else {
        //console.log("hmm I'm not understanding something!");
        return "errorofcomp";
    }
}
//console.log(getComputerMove())
function getWinner(playerMove,computerMove) {
    var winner;
    // Write code that will set winner to either 'player', 'computer', or 'tie' based on the values of playerMove and computerMove.
    if (playerMove===computerMove){
        winner='tie';
    } else if (playerMove==="rock"){
        if (computerMove==="paper"){
            winner='computer';
        } else if (computerMove==="scissors"){
            winner='player';
        }
    } else if (playerMove==="paper"){
        if (computerMove==="scissors"){
            //console.log("computerps");
            winner='computer';
        } else if (computerMove==="rock"){
            winner='player';
        }
    } else if (playerMove==="scissors"){
        if (computerMove==="rock"){
            //console.log("computersr");
            winner='computer';
        } else if (computerMove==="paper"){
            winner='player';
        }
    } else {
        winner='errorgetwinner';
    }
    //console.log(winner);
    return winner;
}
//if (getWinner(getPlayerMove(),getComputerMove())==="player"){console.log("yes");}
//console.log(getWinner(getPlayerMove(),getComputerMove()));

function playTo(x) {
    console.log("Let's play Rock, Paper, Scissors");
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    var compWins=0;
    var playerWins=0;
    var ties=0;
    do {
        if (getWinner(getPlayerMove(null),getComputerMove(null) )==='player'){
            //console.log("player");
            playerWins=playerWins+1;
        } else if (getWinner(getPlayerMove(null),getComputerMove(null))==='computer'){
            //console.log("computer");
            compWins=compWins+1;
        } else if (getWinner(getPlayerMove(null), getComputerMove(null))==='tie') {
            //console.log("tie");
            ties=ties+1;
        }
        else {
            return 'errorPlayto';
        }

    } while ((playerWins<x)||(compWins<x));
    return [playerWins, compWins, ties];
}
playTo(5);<commit_msg>annotated what each function does and made touch ups if possible.<commit_after>function getInput() {
    var input =prompt("Please choose either rock, paper, or scissors.");
    if ((input==="rock")|| (input==="paper") || (input==="scissors")){
        return input;
    } else {
        return getInput();
    }
} //simple function which yields the result of the user's prompt

function randomPlay() {
    var randomNumber = Math.random();
    if (randomNumber <= 0.33) {
        return "rock";
    } else if (randomNumber <= 0.66) {
        return "paper";
    } else {
        return "scissors";
    }
} //simple function which yields either rock paper or scissors

//console.log(getInput());
//console.log(randomPlay());

function getPlayerMove(move) {
    // If a `move` has a value, your expression should evaluate to that value
    if ((move===undefined)||(move===null)){
        return getInput();
    } else {
        //console.log("hmm I'm not understanding something!");
        return move;
    }
} //function which takes getInput's yield and uses it to say the player's move assuming that was not entered.

function getComputerMove(move) {
    //If `move` is not specified / is null, your expression should equal `randomPlay()`.
    if ((move===undefined) || (move===null)){
        return randomPlay();
    } else if ((move==="rock")||(move==="paper")||(move==="scissors")){
        return move;
    } else {
        //console.log("hmm I'm not understanding something!");
        return "errorofcomp";
    }
} //function which takes randomPlay and uses it to determine what the computer will do assuming it wasn't entered.

//console.log(getComputerMove())

function getWinner(playerMove,computerMove) {
    var winner;
    // Write code that will set winner to either 'player', 'computer', or 'tie' based on the values of playerMove and computerMove.
    if (playerMove === computerMove){
        winner="tie";
    } else if (playerMove==="rock"){
        if (computerMove==="paper"){
            winner="computer";
        } else if (computerMove==="scissors"){
            winner="player";
        }
    } else if (playerMove==="paper"){
        if (computerMove==="scissors"){
            //console.log("computerps");
            winner="computer";
        } else if (computerMove==="rock"){
            winner="player";
        }
    } else if (playerMove==="scissors"){
        if (computerMove==="rock"){
            //console.log("computersr");
            winner="computer";
        } else if (computerMove==="paper"){
            winner="player";
        }
    } else {
        winner="errorgetwinner";
    }
    //console.log(winner);
    return winner;
}//function which returns variable winner (which should be either player, computer, or tie)
//if (getWinner(getPlayerMove(),getComputerMove())==="player"){console.log("yes");}
//console.log(getWinner(getPlayerMove(),getComputerMove()));

function playTo(x) {
    console.log("Let's play Rock, Paper, Scissors");
    // Write code that plays 'Rock, Paper, Scissors' until either the player or the computer has won five times.
    /* YOUR CODE HERE */
    var compWins=0;
    var playerWins=0;
    var ties=0;
    while ( (compWins<x) || (playerWins<x) ) {
        if (getWinner(getPlayerMove(null),getComputerMove(null) )==='player'){
            //console.log("player");
            playerWins=playerWins+1;
        } else if (getWinner(getPlayerMove(null),getComputerMove(null))==='computer'){
            //console.log("computer");
            compWins=compWins+1;
        } else if (getWinner(getPlayerMove(null), getComputerMove(null))==='tie') {
            //console.log("tie");
            ties=ties+1;
        }
        else {
            return 'errorPlayto';
        }
    }
    return [compWins, playerWins];
}
playTo(5);<|endoftext|>