<commit_before>'use strict';

const Application = require('./documentModels/application');
const ApplicationAccess = require('./documentModels/applicationAccess');
const ioServer = require('socket.io');
const redis = require('redis');
const methods = require('methods');

module.exports = (http, directoryRouter, subscribers, db, config) => {
	const ioServerToClient = ioServer(http);

	const checkAuthorization = async (clientManager, applicationKey, accessKey) => {
		if (applicationKey == null) {
			clientManager.stream('authorization', {success: false, message: 'applicationKey parameter is empty'});
			return null;
		}

		if (accessKey == null) {
			clientManager.stream('authorization', {success: false, message: 'accessKey parameter is empty'});
			return null;
		}

		if (!await Application.verifyKeyAsync(applicationKey, db, config)) {
			clientManager.stream('authorization', {success: false, message: 'applicationKey parameter is invalid'});
			return null;
		}

		if (!await ApplicationAccess.verifyKeyAsync(accessKey, db, config)) {
			clientManager.stream('authorization', {success: false, message: 'accessKey parameter is invalid'});
			return null;
		}

		clientManager.stream('authorization', {success: true, message: 'successful authorization'});
		return {
			applicationId: Application.splitKey(applicationKey, db, config).applicationId,
			userId: ApplicationAccess.splitKey(accessKey, db, config).userId
		};
	};

	const timelineTypes = ['public', 'home'];

	ioServerToClient.sockets.on('connection', ioServerToClientSocket => {
		(async () => {
			const clientManager = new (require('./helpers/server-streaming-manager'))(ioServerToClient, ioServerToClientSocket, {});

			const applicationKey = ioServerToClientSocket.handshake.query.applicationKey;
			const accessKey = ioServerToClientSocket.handshake.query.accessKey;
			const checkResult = await checkAuthorization(clientManager, applicationKey, accessKey);
			if (checkResult == null) {
				return clientManager.disconnect();
			}
			const userId = checkResult.userId;
			const applicationId = checkResult.applicationId;

			ioServerToClientSocket.application = (await db.applications.findByIdAsync(applicationId));
			ioServerToClientSocket.user = (await db.users.findByIdAsync(userId));

			// クライアント側からRESTリクエストを受信したとき
			clientManager.on('rest', data => {
				(async () => {
					const method = data.request.method.toLowerCase();
					const endpoint = data.request.endpoint;
					const query = data.request.query;
					const headers = data.request.headers;
					const body = data.request.body;

					if (method == null || endpoint == null) {
						return clientManager.stream('rest', {success: false, message: 'request format is invalid'});
					}

					if (endpoint.indexOf('..') != -1)
						return clientManager.stream('rest', {success: false, message: '\'endpoint\' parameter is invalid'});

					if (methods.find(i => i.toLowerCase() === method) == null)
						return clientManager.stream('rest', {success: false, message: '\'method\' parameter is invalid'});

					let routeFuncAsync;
					let params = [];
					try {
						const route = directoryRouter.findRoute(method, endpoint);
						routeFuncAsync = (require(route.getMoludePath()))[method];
						params = route.getParams(endpoint);
					}
					catch(e) {
						console.log('error: faild to parse route info');
						console.log('reason: ' + e);
					}

					if (routeFuncAsync == null)
						return clientManager.stream('rest', {success: false, message: '\'endpoint\' parameter is invalid'});

					const req = {
						method: method,
						endpoint: endpoint,
						query: query,
						params: params,
						headers: headers,
						body: body,
						db: db,
						config: config,
						user: ioServerToClientSocket.user,
						application: ioServerToClientSocket.application
					};

					require('./helpers/middlewares/checkRequest')(req);

					const apiResult = await routeFuncAsync(req);

					if (apiResult.statusCode == null)
						apiResult.statusCode = 200;

					let sendData;
					if (typeof apiResult.data == 'string')
						sendData = {message: apiResult.data};
					else if (apiResult.data != null)
						sendData = apiResult.data;
					else
						sendData = {};

					console.log('rest event:', method, endpoint, 'res code:', apiResult.statusCode);
					return clientManager.stream('rest', {success: true, request: data.request, response: sendData, statusCode: apiResult.statusCode});
				})();
			});

			let publicSubscriber = null;
			let homeSubscriber = null;

			// クライアント側からタイムラインの購読リクエストを受信したとき
			clientManager.on('timeline-connect', data => {
				const timelineType = data.type;

				if (timelineType == null)
					return clientManager.stream('timeline-connect', {success: false, message: '\'type\' parameter is require'});

				if (!timelineTypes.some(i => i == timelineType))
					return clientManager.stream('timeline-connect', {success: false, message: '\'type\' parameter is invalid'});

				// Redis: 購読状態の初期化
				if (timelineType == timelineTypes[0]) { // public
					if (publicSubscriber != null)
						return clientManager.stream('timeline-connect', {success: false, message: 'public timeline is already subscribed'});

					publicSubscriber = redis.createClient(6379, 'localhost');
					publicSubscriber.subscribe('public:status'); // パブリックを購読
					publicSubscriber.on('message', (ch, jsonData) => {
						const chInfo = ch.split(':');
						const dataType = chInfo[1];

						clientManager.data(`public:${dataType}`, JSON.parse(jsonData));
					});
					publicSubscriber.on('error', function(err) {
						console.log('redis_err(publicSubscriber): ' + String(err));
					});

					clientManager.stream('timeline-connect', {success: true, message: 'connected public timeline'});
				}

				if (timelineType == timelineTypes[1]) { // home
					if (homeSubscriber != null)
						return clientManager.stream('timeline-connect', {success: false, message: 'home timeline is already subscribed'});

					homeSubscriber = redis.createClient(6379, 'localhost');
					subscribers.set(userId.toString(), homeSubscriber);
					homeSubscriber.subscribe(`${userId.toString()}:status`); // 自身を購読
					// subscriber.subscribe(`status:${}`); // TODO: フォローしている全ユーザーを購読
					homeSubscriber.on('message', (ch, jsonData) => {
						const chInfo = ch.split(':');
						const dataType = chInfo[1];

						clientManager.data(`home:${dataType}`, JSON.parse(jsonData));
					});
					homeSubscriber.on('error', function(err) {
						console.log('redis_err(homeSubscriber): ' + String(err));
					});

					clientManager.stream('timeline-connect', {success: true, message: 'connected home timeline'});
				}
			});

			clientManager.on('timeline-disconnect', data => {
				const timelineType = data.type;

				if (timelineType == null)
					return clientManager.stream('error:timeline-disconnect', {message: '\'type\' parameter is require'});

				if (!timelineTypes.some(i => i == timelineType))
					return clientManager.stream('error:timeline-disconnect', {message: '\'type\' parameter is invalid'});

				if (timelineType == timelineTypes[0]) {
					if (homeSubscriber != null)
						return clientManager.stream('error:timeline-disconnect', {message: 'public timeline is not subscribed'});

					publicSubscriber.quit([], () => {
						publicSubscriber = null;
						clientManager.stream('success:timeline-disconnect', {message: 'disconnected public timeline'});
					});
				}

				if (timelineType == timelineTypes[1]) {
					if (homeSubscriber != null)
						return clientManager.stream('error:timeline-disconnect', {message: 'home timeline is not subscribed'});

					homeSubscriber.quit([], () => {
						homeSubscriber = null;
						clientManager.stream('success:timeline-disconnect', {message: 'disconnected home timeline'});
					});
				}
			});

			clientManager.onDisconnect((err, res) => {
				if (homeSubscriber != null) {
					homeSubscriber.quit(() => {
						homeSubscriber = null;
					});
				}
				if (publicSubscriber != null) {
					publicSubscriber.quit((err, res) => {
						publicSubscriber = null;
					});
				}
			});
		})();
	});
};
<commit_msg>add log<commit_after>'use strict';

const Application = require('./documentModels/application');
const ApplicationAccess = require('./documentModels/applicationAccess');
const ioServer = require('socket.io');
const redis = require('redis');
const methods = require('methods');

module.exports = (http, directoryRouter, subscribers, db, config) => {
	const ioServerToClient = ioServer(http);

	const checkAuthorization = async (clientManager, applicationKey, accessKey) => {
		if (applicationKey == null) {
			clientManager.stream('authorization', {success: false, message: 'applicationKey parameter is empty'});
			return null;
		}

		if (accessKey == null) {
			clientManager.stream('authorization', {success: false, message: 'accessKey parameter is empty'});
			return null;
		}

		if (!await Application.verifyKeyAsync(applicationKey, db, config)) {
			clientManager.stream('authorization', {success: false, message: 'applicationKey parameter is invalid'});
			return null;
		}

		if (!await ApplicationAccess.verifyKeyAsync(accessKey, db, config)) {
			clientManager.stream('authorization', {success: false, message: 'accessKey parameter is invalid'});
			return null;
		}

		clientManager.stream('authorization', {success: true, message: 'successful authorization'});
		return {
			applicationId: Application.splitKey(applicationKey, db, config).applicationId,
			userId: ApplicationAccess.splitKey(accessKey, db, config).userId
		};
	};

	const timelineTypes = ['public', 'home'];

	ioServerToClient.sockets.on('connection', ioServerToClientSocket => {
		(async () => {
			const clientManager = new (require('./helpers/server-streaming-manager'))(ioServerToClient, ioServerToClientSocket, {});

			const applicationKey = ioServerToClientSocket.handshake.query.applicationKey;
			const accessKey = ioServerToClientSocket.handshake.query.accessKey;
			const checkResult = await checkAuthorization(clientManager, applicationKey, accessKey);
			if (checkResult == null) {
				return clientManager.disconnect();
			}
			const userId = checkResult.userId;
			const applicationId = checkResult.applicationId;

			ioServerToClientSocket.application = (await db.applications.findByIdAsync(applicationId));
			ioServerToClientSocket.user = (await db.users.findByIdAsync(userId));

			// クライアント側からRESTリクエストを受信したとき
			clientManager.on('rest', data => {
				(async () => {
					const method = data.request.method.toLowerCase();
					const endpoint = data.request.endpoint;
					const query = data.request.query;
					const headers = data.request.headers;
					const body = data.request.body;

					if (method == null || endpoint == null) {
						return clientManager.stream('rest', {success: false, message: 'request format is invalid'});
					}

					console.log('[>client] rest:', method, endpoint);

					if (endpoint.indexOf('..') != -1)
						return clientManager.stream('rest', {success: false, message: '\'endpoint\' parameter is invalid'});

					if (methods.find(i => i.toLowerCase() === method) == null)
						return clientManager.stream('rest', {success: false, message: '\'method\' parameter is invalid'});

					let routeFuncAsync;
					let params = [];
					try {
						const route = directoryRouter.findRoute(method, endpoint);
						routeFuncAsync = (require(route.getMoludePath()))[method];
						params = route.getParams(endpoint);
					}
					catch(e) {
						console.log('error: faild to parse route info');
						console.log('reason: ' + e);
					}

					if (routeFuncAsync == null)
						return clientManager.stream('rest', {success: false, message: '\'endpoint\' parameter is invalid'});

					const req = {
						method: method,
						endpoint: endpoint,
						query: query,
						params: params,
						headers: headers,
						body: body,
						db: db,
						config: config,
						user: ioServerToClientSocket.user,
						application: ioServerToClientSocket.application
					};

					require('./helpers/middlewares/checkRequest')(req);

					const apiResult = await routeFuncAsync(req);

					if (apiResult.statusCode == null)
						apiResult.statusCode = 200;

					let sendData;
					if (typeof apiResult.data == 'string')
						sendData = {message: apiResult.data};
					else if (apiResult.data != null)
						sendData = apiResult.data;
					else
						sendData = {};

					console.log('[client<] rest:', method, endpoint, 'res code:', apiResult.statusCode);
					return clientManager.stream('rest', {success: true, request: data.request, response: sendData, statusCode: apiResult.statusCode});
				})();
			});

			let publicSubscriber = null;
			let homeSubscriber = null;

			// クライアント側からタイムラインの購読リクエストを受信したとき
			clientManager.on('timeline-connect', data => {
				const timelineType = data.type;

				if (timelineType == null)
					return clientManager.stream('timeline-connect', {success: false, message: '\'type\' parameter is require'});

				if (!timelineTypes.some(i => i == timelineType))
					return clientManager.stream('timeline-connect', {success: false, message: '\'type\' parameter is invalid'});

				// Redis: 購読状態の初期化
				if (timelineType == timelineTypes[0]) { // public
					if (publicSubscriber != null)
						return clientManager.stream('timeline-connect', {success: false, message: 'public timeline is already subscribed'});

					publicSubscriber = redis.createClient(6379, 'localhost');
					publicSubscriber.subscribe('public:status'); // パブリックを購読
					publicSubscriber.on('message', (ch, jsonData) => {
						const chInfo = ch.split(':');
						const dataType = chInfo[1];

						clientManager.data(`public:${dataType}`, JSON.parse(jsonData));
					});
					publicSubscriber.on('error', function(err) {
						console.log('redis_err(publicSubscriber): ' + String(err));
					});

					clientManager.stream('timeline-connect', {success: true, message: 'connected public timeline'});
				}

				if (timelineType == timelineTypes[1]) { // home
					if (homeSubscriber != null)
						return clientManager.stream('timeline-connect', {success: false, message: 'home timeline is already subscribed'});

					homeSubscriber = redis.createClient(6379, 'localhost');
					subscribers.set(userId.toString(), homeSubscriber);
					homeSubscriber.subscribe(`${userId.toString()}:status`); // 自身を購読
					// subscriber.subscribe(`status:${}`); // TODO: フォローしている全ユーザーを購読
					homeSubscriber.on('message', (ch, jsonData) => {
						const chInfo = ch.split(':');
						const dataType = chInfo[1];

						clientManager.data(`home:${dataType}`, JSON.parse(jsonData));
					});
					homeSubscriber.on('error', function(err) {
						console.log('redis_err(homeSubscriber): ' + String(err));
					});

					clientManager.stream('timeline-connect', {success: true, message: 'connected home timeline'});
				}
			});

			clientManager.on('timeline-disconnect', data => {
				const timelineType = data.type;

				if (timelineType == null)
					return clientManager.stream('error:timeline-disconnect', {message: '\'type\' parameter is require'});

				if (!timelineTypes.some(i => i == timelineType))
					return clientManager.stream('error:timeline-disconnect', {message: '\'type\' parameter is invalid'});

				if (timelineType == timelineTypes[0]) {
					if (homeSubscriber != null)
						return clientManager.stream('error:timeline-disconnect', {message: 'public timeline is not subscribed'});

					publicSubscriber.quit([], () => {
						publicSubscriber = null;
						clientManager.stream('success:timeline-disconnect', {message: 'disconnected public timeline'});
					});
				}

				if (timelineType == timelineTypes[1]) {
					if (homeSubscriber != null)
						return clientManager.stream('error:timeline-disconnect', {message: 'home timeline is not subscribed'});

					homeSubscriber.quit([], () => {
						homeSubscriber = null;
						clientManager.stream('success:timeline-disconnect', {message: 'disconnected home timeline'});
					});
				}
			});

			clientManager.onDisconnect((err, res) => {
				if (homeSubscriber != null) {
					homeSubscriber.quit(() => {
						homeSubscriber = null;
					});
				}
				if (publicSubscriber != null) {
					publicSubscriber.quit((err, res) => {
						publicSubscriber = null;
					});
				}
			});
		})();
	});
};
<|endoftext|>


<commit_before>import { EventDispatcher } from '../core/EventDispatcher';
import { UVMapping } from '../constants';
import { MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, LinearEncoding, UnsignedByteType, RGBAFormat, LinearMipMapLinearFilter, LinearFilter } from '../constants';
import { _Math } from '../math/Math';
import { Vector2 } from '../math/Vector2';

/**
 * @author mrdoob / http://mrdoob.com/
 * @author alteredq / http://alteredqualia.com/
 * @author szimek / https://github.com/szimek/
 */

function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {

	Object.defineProperty( this, 'id', { value: TextureIdCount() } );

	this.uuid = _Math.generateUUID();

	this.name = '';

	this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;
	this.mipmaps = [];

	this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;

	this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;
	this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;

	this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
	this.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;

	this.anisotropy = anisotropy !== undefined ? anisotropy : 1;

	this.format = format !== undefined ? format : RGBAFormat;
	this.type = type !== undefined ? type : UnsignedByteType;

	this.offset = new Vector2( 0, 0 );
	this.repeat = new Vector2( 1, 1 );

	this.generateMipmaps = true;
	this.premultiplyAlpha = false;
	this.flipY = true;
	this.unpackAlignment = 4;	// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)

	// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.
	//
	// Also changing the encoding after already used by a Material will not automatically make the Material
	// update.  You need to explicitly call Material.needsUpdate to trigger it to recompile.
	this.encoding = encoding !== undefined ? encoding :  LinearEncoding;

	this.version = 0;
	this.onUpdate = null;

}

Texture.DEFAULT_IMAGE = undefined;
Texture.DEFAULT_MAPPING = UVMapping;

Texture.prototype = {

	constructor: Texture,

	isTexture: true,

	set needsUpdate( value ) {

		if ( value === true ) this.version ++;

	},

	clone: function () {

		return new this.constructor().copy( this );

	},

	copy: function ( source ) {

		this.image = source.image;
		this.mipmaps = source.mipmaps.slice( 0 );

		this.mapping = source.mapping;

		this.wrapS = source.wrapS;
		this.wrapT = source.wrapT;

		this.magFilter = source.magFilter;
		this.minFilter = source.minFilter;

		this.anisotropy = source.anisotropy;

		this.format = source.format;
		this.type = source.type;

		this.offset.copy( source.offset );
		this.repeat.copy( source.repeat );

		this.generateMipmaps = source.generateMipmaps;
		this.premultiplyAlpha = source.premultiplyAlpha;
		this.flipY = source.flipY;
		this.unpackAlignment = source.unpackAlignment;
		this.encoding = source.encoding;

		// TODO (abelnation): this was added as something causes texture constants to be "copied" before they are properly uploaded to GPU
		this.needsUpdate = source.needsUpdate;
		this.version = source.version;

		return this;

	},

	toJSON: function ( meta ) {

		if ( meta.textures[ this.uuid ] !== undefined ) {

			return meta.textures[ this.uuid ];

		}

		function getDataURL( image ) {

			var canvas;

			if ( image.toDataURL !== undefined ) {

				canvas = image;

			} else {

				canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
				canvas.width = image.width;
				canvas.height = image.height;

				canvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );

			}

			if ( canvas.width > 2048 || canvas.height > 2048 ) {

				return canvas.toDataURL( 'image/jpeg', 0.6 );

			} else {

				return canvas.toDataURL( 'image/png' );

			}

		}

		var output = {
			metadata: {
				version: 4.4,
				type: 'Texture',
				generator: 'Texture.toJSON'
			},

			uuid: this.uuid,
			name: this.name,

			mapping: this.mapping,

			repeat: [ this.repeat.x, this.repeat.y ],
			offset: [ this.offset.x, this.offset.y ],
			wrap: [ this.wrapS, this.wrapT ],

			minFilter: this.minFilter,
			magFilter: this.magFilter,
			anisotropy: this.anisotropy,

			flipY: this.flipY
		};

		if ( this.image !== undefined ) {

			// TODO: Move to THREE.Image

			var image = this.image;

			if ( image.uuid === undefined ) {

				image.uuid = _Math.generateUUID(); // UGH

			}

			if ( meta.images[ image.uuid ] === undefined ) {

				meta.images[ image.uuid ] = {
					uuid: image.uuid,
					url: getDataURL( image )
				};

			}

			output.image = image.uuid;

		}

		meta.textures[ this.uuid ] = output;

		return output;

	},

	dispose: function () {

		this.dispatchEvent( { type: 'dispose' } );

	},

	transformUv: function ( uv ) {

		if ( this.mapping !== UVMapping )  return;

		uv.multiply( this.repeat );
		uv.add( this.offset );

		if ( uv.x < 0 || uv.x > 1 ) {

			switch ( this.wrapS ) {

				case RepeatWrapping:

					uv.x = uv.x - Math.floor( uv.x );
					break;

				case ClampToEdgeWrapping:

					uv.x = uv.x < 0 ? 0 : 1;
					break;

				case MirroredRepeatWrapping:

					if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {

						uv.x = Math.ceil( uv.x ) - uv.x;

					} else {

						uv.x = uv.x - Math.floor( uv.x );

					}
					break;

			}

		}

		if ( uv.y < 0 || uv.y > 1 ) {

			switch ( this.wrapT ) {

				case RepeatWrapping:

					uv.y = uv.y - Math.floor( uv.y );
					break;

				case ClampToEdgeWrapping:

					uv.y = uv.y < 0 ? 0 : 1;
					break;

				case MirroredRepeatWrapping:

					if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {

						uv.y = Math.ceil( uv.y ) - uv.y;

					} else {

						uv.y = uv.y - Math.floor( uv.y );

					}
					break;

			}

		}

		if ( this.flipY ) {

			uv.y = 1 - uv.y;

		}

	}

};

Object.assign( Texture.prototype, EventDispatcher.prototype );

var count = 0;
function TextureIdCount() { return count++; };

export { TextureIdCount, Texture };
<commit_msg>only png needed<commit_after>import { EventDispatcher } from '../core/EventDispatcher';
import { UVMapping } from '../constants';
import { MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, LinearEncoding, UnsignedByteType, RGBAFormat, LinearMipMapLinearFilter, LinearFilter } from '../constants';
import { _Math } from '../math/Math';
import { Vector2 } from '../math/Vector2';

/**
 * @author mrdoob / http://mrdoob.com/
 * @author alteredq / http://alteredqualia.com/
 * @author szimek / https://github.com/szimek/
 */

function Texture( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding ) {

	Object.defineProperty( this, 'id', { value: TextureIdCount() } );

	this.uuid = _Math.generateUUID();

	this.name = '';

	this.image = image !== undefined ? image : Texture.DEFAULT_IMAGE;
	this.mipmaps = [];

	this.mapping = mapping !== undefined ? mapping : Texture.DEFAULT_MAPPING;

	this.wrapS = wrapS !== undefined ? wrapS : ClampToEdgeWrapping;
	this.wrapT = wrapT !== undefined ? wrapT : ClampToEdgeWrapping;

	this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
	this.minFilter = minFilter !== undefined ? minFilter : LinearMipMapLinearFilter;

	this.anisotropy = anisotropy !== undefined ? anisotropy : 1;

	this.format = format !== undefined ? format : RGBAFormat;
	this.type = type !== undefined ? type : UnsignedByteType;

	this.offset = new Vector2( 0, 0 );
	this.repeat = new Vector2( 1, 1 );

	this.generateMipmaps = true;
	this.premultiplyAlpha = false;
	this.flipY = true;
	this.unpackAlignment = 4;	// valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)

	// Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.
	//
	// Also changing the encoding after already used by a Material will not automatically make the Material
	// update.  You need to explicitly call Material.needsUpdate to trigger it to recompile.
	this.encoding = encoding !== undefined ? encoding :  LinearEncoding;

	this.version = 0;
	this.onUpdate = null;

}

Texture.DEFAULT_IMAGE = undefined;
Texture.DEFAULT_MAPPING = UVMapping;

Texture.prototype = {

	constructor: Texture,

	isTexture: true,

	set needsUpdate( value ) {

		if ( value === true ) this.version ++;

	},

	clone: function () {

		return new this.constructor().copy( this );

	},

	copy: function ( source ) {

		this.image = source.image;
		this.mipmaps = source.mipmaps.slice( 0 );

		this.mapping = source.mapping;

		this.wrapS = source.wrapS;
		this.wrapT = source.wrapT;

		this.magFilter = source.magFilter;
		this.minFilter = source.minFilter;

		this.anisotropy = source.anisotropy;

		this.format = source.format;
		this.type = source.type;

		this.offset.copy( source.offset );
		this.repeat.copy( source.repeat );

		this.generateMipmaps = source.generateMipmaps;
		this.premultiplyAlpha = source.premultiplyAlpha;
		this.flipY = source.flipY;
		this.unpackAlignment = source.unpackAlignment;
		this.encoding = source.encoding;

		// TODO (abelnation): this was added as something causes texture constants to be "copied" before they are properly uploaded to GPU
		this.needsUpdate = source.needsUpdate;
		this.version = source.version;

		return this;

	},

	toJSON: function ( meta ) {

		if ( meta.textures[ this.uuid ] !== undefined ) {

			return meta.textures[ this.uuid ];

		}

		function getDataURL( image ) {

			var canvas;

			if ( image.toDataURL !== undefined ) {

				canvas = image;

			} else {

				canvas = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'canvas' );
				canvas.width = image.width;
				canvas.height = image.height;

				canvas.getContext( '2d' ).drawImage( image, 0, 0, image.width, image.height );

			}

			return canvas.toDataURL( 'image/png' );

		}

		var output = {
			metadata: {
				version: 4.4,
				type: 'Texture',
				generator: 'Texture.toJSON'
			},

			uuid: this.uuid,
			name: this.name,

			mapping: this.mapping,

			repeat: [ this.repeat.x, this.repeat.y ],
			offset: [ this.offset.x, this.offset.y ],
			wrap: [ this.wrapS, this.wrapT ],

			minFilter: this.minFilter,
			magFilter: this.magFilter,
			anisotropy: this.anisotropy,

			flipY: this.flipY
		};

		if ( this.image !== undefined ) {

			// TODO: Move to THREE.Image

			var image = this.image;

			if ( image.uuid === undefined ) {

				image.uuid = _Math.generateUUID(); // UGH

			}

			if ( meta.images[ image.uuid ] === undefined ) {

				meta.images[ image.uuid ] = {
					uuid: image.uuid,
					url: getDataURL( image )
				};

			}

			output.image = image.uuid;

		}

		meta.textures[ this.uuid ] = output;

		return output;

	},

	dispose: function () {

		this.dispatchEvent( { type: 'dispose' } );

	},

	transformUv: function ( uv ) {

		if ( this.mapping !== UVMapping )  return;

		uv.multiply( this.repeat );
		uv.add( this.offset );

		if ( uv.x < 0 || uv.x > 1 ) {

			switch ( this.wrapS ) {

				case RepeatWrapping:

					uv.x = uv.x - Math.floor( uv.x );
					break;

				case ClampToEdgeWrapping:

					uv.x = uv.x < 0 ? 0 : 1;
					break;

				case MirroredRepeatWrapping:

					if ( Math.abs( Math.floor( uv.x ) % 2 ) === 1 ) {

						uv.x = Math.ceil( uv.x ) - uv.x;

					} else {

						uv.x = uv.x - Math.floor( uv.x );

					}
					break;

			}

		}

		if ( uv.y < 0 || uv.y > 1 ) {

			switch ( this.wrapT ) {

				case RepeatWrapping:

					uv.y = uv.y - Math.floor( uv.y );
					break;

				case ClampToEdgeWrapping:

					uv.y = uv.y < 0 ? 0 : 1;
					break;

				case MirroredRepeatWrapping:

					if ( Math.abs( Math.floor( uv.y ) % 2 ) === 1 ) {

						uv.y = Math.ceil( uv.y ) - uv.y;

					} else {

						uv.y = uv.y - Math.floor( uv.y );

					}
					break;

			}

		}

		if ( this.flipY ) {

			uv.y = 1 - uv.y;

		}

	}

};

Object.assign( Texture.prototype, EventDispatcher.prototype );

var count = 0;
function TextureIdCount() { return count++; };

export { TextureIdCount, Texture };
<|endoftext|>


<commit_before>/*
//Defaults can be overwritten in $tyle
$.fn.transForm.defaults.useIdOnEmptyName = false;
//Methods can be chained
$('div').transForm('deserialize', {library: 'jQuery/Zepto'}).transForm('submit');
//Return value of serialize is an array of objects
var test = $('div').transForm('serialize');
//TODO:
- Tests
- MOAR $$$ functions!
*/

(function ($) {

    var methods = {
        serialize: serialize,
        deserialize: deserialize,
        clear: clear,
        submit: submit,
    };

    $.extend($.fn, {
        transForm: function (methodOrOptions) {
            if (methods[methodOrOptions]) {
                var args = Array.prototype.slice.call(arguments, 1);
                if (methodOrOptions === 'serialize') {
                    var result = [];
                    this.each(function () {
                        result.push(methods[methodOrOptions].apply(this, args));
                    });
                    return result;
                } else
                    return this.each(function () {
                        methods[methodOrOptions].apply(this, args);
                    });
            } else {
                error('Method ' + methodOrOptions + ' does not exist on transForm.js');
            }
        }
    });

    $.fn.transForm.defaults = {
        delimiter: '.',
        skipDisabled: true,
        skipReadOnly: false,
        skipFalsy: false,
        useIdOnEmptyName: true,
        triggerChange: false
    };

    /* Serialize */
    function serialize(options, nodeCallback) {
        var result = {},
            opts = getOptions(options),
            inputs = getFields(this, opts.skipDisabled, opts.skipReadOnly),
            skipFalsy = opts.skipFalsy,
            delimiter = opts.delimiter,
            useIdOnEmptyName = opts.useIdOnEmptyName;

        for (var i = 0, l = inputs.length; i < l; i++) {
            var input = inputs[i],
                key = input.name || useIdOnEmptyName && input.id;

            if (!key) continue;

            var entry = null;
            if (nodeCallback) entry = nodeCallback(input);
            if (!entry) entry = getEntryFromInput(input, key);

            if (typeof entry.value === 'undefined' || entry.value === null
                || (skipFalsy && (!entry.value || (isArray(entry.value) && !entry.value.length))))
                continue;
            saveEntryToResult(result, entry, input, delimiter);
        }
        return result;
    }

    function getEntryFromInput(input, key) {
        var nodeType = input.type && input.type.toLowerCase(),
            entry = { name: key, value: null };

        switch (nodeType) {
            case 'radio':
                if (input.checked)
                    entry.value = input.value === 'on' ? true : input.value;
                break;
            case 'checkbox':
                entry.value = input.checked ? (input.value === 'on' ? true : input.value) : false;
                break;
            case 'select-multiple':
                entry.value = [];
                for (var i = 0, l = input.options.length; i < l; i++)
                    if (input.options[i].selected) entry.value.push(input.options[i].value);
                break;
            case 'file':
                //Only interested in the filename (Chrome adds C:\fakepath\ for security anyway)
                entry.value = input.value.split('\\').pop();
                break;
            case 'button':
            case 'submit':
            case 'reset':
                break;
            default:
                entry.value = input.value;
        }
        return entry;
    }

    function parseString(str, delimiter) {
        var result = [],
            split = str.split(delimiter),
            len = split.length;
        for (var i = 0; i < len; i++) {
            var s = split[i].split('['),
                l = s.length;
            for (var j = 0; j < l; j++) {
                var key = s[j];
                if (!key) {
                    //if the first one is empty, continue
                    if (j === 0) continue;
                    //if the undefined key is not the last part of the string, throw error
                    if (j !== l - 1)
                        error('Undefined key is not the last part of the name > ' + str);
                }
                //strip "]" if its there
                if (key && key[key.length - 1] === ']')
                    key = key.slice(0, -1);
                result.push(key);
            }
        }
        return result;
    }

    function saveEntryToResult(parent, entry, input, delimiter) {
        //not not accept falsy values in array collections
        if (/\[\]$/.test(entry.name) && !entry.value) return;
        var parts = parseString(entry.name, delimiter);
        for (var i = 0, l = parts.length; i < l; i++) {
            var part = parts[i];
            //if last
            if (i === l - 1) {
                parent[part] = entry.value;
            } else {
                var index = parts[i + 1];
                if (!index || isNumber(index)) {
                    if (!isArray(parent[part]))
                        parent[part] = [];
                    //if second last
                    if (i === l - 2) {
                        parent[part].push(entry.value);
                    } else {
                        if (!isObject(parent[part][index]))
                            parent[part][index] = {};
                        parent = parent[part][index];
                    }
                    i++;
                } else {
                    if (!isObject(parent[part]))
                        parent[part] = {};
                    parent = parent[part];
                }
            }
        }
    }

    /* Deserialize */
    function deserialize(data, options, nodeCallback) {
        var opts = getOptions(options),
            triggerChange = opts.triggerChange,
            inputs = getFields(this, opts.skipDisabled, opts.skipReadOnly);

        if (!isObject(data)) {
            if (!isString(data)) return;
            try { //Try to parse the passed data as JSON
                data = JSON.parse(data);
            } catch (e) {
                error('Passed string is not a JSON string > ' + data);
            }
        }

        for (var i = 0, l = inputs.length; i < l; i++) {
            var input = inputs[i],
                key = input.name || opts.useIdOnEmptyName && input.id,
                value = getFieldValue(key, opts.delimiter, data);

            if (typeof value === 'undefined' || value === null) {
                clearInput(input, triggerChange);
                continue;
            }
            var mutated = nodeCallback && nodeCallback(input, value);
            if (!mutated) setValueToInput(input, value, triggerChange);
        }
    }

    function getFieldValue(key, delimiter, ref) {
        if (!key) return;
        var parts = parseString(key, delimiter);
        for (var i = 0, l = parts.length; i < l; i++) {
            if (!ref) return;
            var part = ref[parts[i]];

            if (typeof part === 'undefined' || part === null) return;
            //if last
            if (i === l - 1) {
                return part;
            } else {
                var index = parts[i + 1];
                if (index === '') {
                    return part;
                } else if (isNumber(index)) {
                    //if second last
                    if (i === l - 2)
                        return part[index];
                    else
                        ref = part[index];
                    i++;
                } else {
                    ref = part;
                }
            }
        }
    }

    function contains(array, value) {
        for (var i = array.length; i--;)
            if (array[i] == value) return true;
        return false;
    }

    function setValueToInput(input, value, triggerChange) {
        var nodeType = input.type && input.type.toLowerCase();

        switch (nodeType) {
            case 'radio':
                if (value == input.value) input.checked = true;
                break;
            case 'checkbox':
                input.checked = isArray(value)
                    ? contains(value, input.value)
                    : value === true || value == input.value;
                break;
            case 'select-multiple':
                if (isArray(value))
                    for (var i = input.options.length; i--;)
                        input.options[i].selected = contains(value, input.options[i].value);
                else
                    input.value = value;
                break;
            case 'button':
            case 'submit':
            case 'reset':
            case 'file':
                break;
            default:
                input.value = value;
        }
        if (triggerChange)
            $(input).change();
    }

    /* Clear */
    function clear(options) {
        var opts = getOptions(options),
            triggerChange = opts.triggerChange,
            inputs = getFields(this, opts.skipDisabled, opts.skipReadOnly);

        for (var i = 0, l = inputs.length; i < l; i++)
            clearInput(inputs[i], triggerChange);
    }

    function clearInput(input, triggerChange) {
        var nodeType = input.type && input.type.toLowerCase();

        switch (nodeType) {
            case 'select-one':
                input.selectedIndex = 0;
                break;
			case 'select-multiple':
				for (var i = input.options.length; i--;)
					input.options[i].selected = false;
				break;
            case 'radio':
            case 'checkbox':
                if (input.checked) input.checked = false;
                break;
            case 'button':
            case 'submit':
            case 'reset':
            case 'file':
                break;
            default:
                input.value = '';
        }
        if (triggerChange)
            $(input).change();
    }

    /* Submit */
    function submit(html5Submit) {
        var el = this;
        if (!html5Submit) {
            if (isFunction(el.submit))
                el.submit();
            return;
        }

        var clean, btn = el.querySelector('[type="submit"]');
        if (!btn) {
            clean = true;
            btn = document.createElement('button');
            btn.type = 'submit';
            btn.style.display = 'none';
            el.appendChild(btn);
        }
        $(btn).click();
        if (clean) el.removeChild(btn);
    }

    /* Helper functions */
    function isObject(obj) {
        return $.type(s) === 'object';
    }
    function isNumber(n) {
        return $.type(s) === 'number';
    }
    function isArray(arr) {
        return $.type(s) === 'array';
    }
    function isFunction(fn) {
        return $.type(s) === 'function';
    }
    function isString(s) {
        return $.type(s) === 'string';
    }

    function getFields(parent, skipDisabled, skipReadOnly) {
        var fields = ['input', 'select', 'textarea'];
        for (var i = 0; i < fields.length; i++) {
            var field = fields[i];
            if (skipDisabled) field += ':not([disabled])';
            if (skipReadOnly) field += ':not([readonly])';
            field += ':not([data-trans-form="ignore"])';
            fields[i] = field;
        }
        return parent.querySelectorAll(fields.join(','));
    }

    function getOptions(options) {
        var _defaults = $.fn.transForm.defaults;
        if (!isObject(options)) return _defaults;
        var o, opts = {};
        for (o in _defaults) opts[o] = _defaults[o];
        for (o in options) opts[o] = options[o];
        return opts;
    }

    function error(e) {
        $.error('transForm.js ♦ ' + e);
    }
})(window.Zepto || window.jQuery);
<commit_msg>Fix error in type-checking helper functions<commit_after>/*
//Defaults can be overwritten in $tyle
$.fn.transForm.defaults.useIdOnEmptyName = false;
//Methods can be chained
$('div').transForm('deserialize', {library: 'jQuery/Zepto'}).transForm('submit');
//Return value of serialize is an array of objects
var test = $('div').transForm('serialize');
//TODO:
- Tests
- MOAR $$$ functions!
*/

(function ($) {

    var methods = {
        serialize: serialize,
        deserialize: deserialize,
        clear: clear,
        submit: submit,
    };

    $.extend($.fn, {
        transForm: function (methodOrOptions) {
            if (methods[methodOrOptions]) {
                var args = Array.prototype.slice.call(arguments, 1);
                if (methodOrOptions === 'serialize') {
                    var result = [];
                    this.each(function () {
                        result.push(methods[methodOrOptions].apply(this, args));
                    });
                    return result;
                } else
                    return this.each(function () {
                        methods[methodOrOptions].apply(this, args);
                    });
            } else {
                error('Method ' + methodOrOptions + ' does not exist on transForm.js');
            }
        }
    });

    $.fn.transForm.defaults = {
        delimiter: '.',
        skipDisabled: true,
        skipReadOnly: false,
        skipFalsy: false,
        useIdOnEmptyName: true,
        triggerChange: false
    };

    /* Serialize */
    function serialize(options, nodeCallback) {
        var result = {},
            opts = getOptions(options),
            inputs = getFields(this, opts.skipDisabled, opts.skipReadOnly),
            skipFalsy = opts.skipFalsy,
            delimiter = opts.delimiter,
            useIdOnEmptyName = opts.useIdOnEmptyName;

        for (var i = 0, l = inputs.length; i < l; i++) {
            var input = inputs[i],
                key = input.name || useIdOnEmptyName && input.id;

            if (!key) continue;

            var entry = null;
            if (nodeCallback) entry = nodeCallback(input);
            if (!entry) entry = getEntryFromInput(input, key);

            if (typeof entry.value === 'undefined' || entry.value === null
                || (skipFalsy && (!entry.value || (isArray(entry.value) && !entry.value.length))))
                continue;
            saveEntryToResult(result, entry, input, delimiter);
        }
        return result;
    }

    function getEntryFromInput(input, key) {
        var nodeType = input.type && input.type.toLowerCase(),
            entry = { name: key, value: null };

        switch (nodeType) {
            case 'radio':
                if (input.checked)
                    entry.value = input.value === 'on' ? true : input.value;
                break;
            case 'checkbox':
                entry.value = input.checked ? (input.value === 'on' ? true : input.value) : false;
                break;
            case 'select-multiple':
                entry.value = [];
                for (var i = 0, l = input.options.length; i < l; i++)
                    if (input.options[i].selected) entry.value.push(input.options[i].value);
                break;
            case 'file':
                //Only interested in the filename (Chrome adds C:\fakepath\ for security anyway)
                entry.value = input.value.split('\\').pop();
                break;
            case 'button':
            case 'submit':
            case 'reset':
                break;
            default:
                entry.value = input.value;
        }
        return entry;
    }

    function parseString(str, delimiter) {
        var result = [],
            split = str.split(delimiter),
            len = split.length;
        for (var i = 0; i < len; i++) {
            var s = split[i].split('['),
                l = s.length;
            for (var j = 0; j < l; j++) {
                var key = s[j];
                if (!key) {
                    //if the first one is empty, continue
                    if (j === 0) continue;
                    //if the undefined key is not the last part of the string, throw error
                    if (j !== l - 1)
                        error('Undefined key is not the last part of the name > ' + str);
                }
                //strip "]" if its there
                if (key && key[key.length - 1] === ']')
                    key = key.slice(0, -1);
                result.push(key);
            }
        }
        return result;
    }

    function saveEntryToResult(parent, entry, input, delimiter) {
        //not not accept falsy values in array collections
        if (/\[\]$/.test(entry.name) && !entry.value) return;
        var parts = parseString(entry.name, delimiter);
        for (var i = 0, l = parts.length; i < l; i++) {
            var part = parts[i];
            //if last
            if (i === l - 1) {
                parent[part] = entry.value;
            } else {
                var index = parts[i + 1];
                if (!index || isNumber(index)) {
                    if (!isArray(parent[part]))
                        parent[part] = [];
                    //if second last
                    if (i === l - 2) {
                        parent[part].push(entry.value);
                    } else {
                        if (!isObject(parent[part][index]))
                            parent[part][index] = {};
                        parent = parent[part][index];
                    }
                    i++;
                } else {
                    if (!isObject(parent[part]))
                        parent[part] = {};
                    parent = parent[part];
                }
            }
        }
    }

    /* Deserialize */
    function deserialize(data, options, nodeCallback) {
        var opts = getOptions(options),
            triggerChange = opts.triggerChange,
            inputs = getFields(this, opts.skipDisabled, opts.skipReadOnly);

        if (!isObject(data)) {
            if (!isString(data)) return;
            try { //Try to parse the passed data as JSON
                data = JSON.parse(data);
            } catch (e) {
                error('Passed string is not a JSON string > ' + data);
            }
        }

        for (var i = 0, l = inputs.length; i < l; i++) {
            var input = inputs[i],
                key = input.name || opts.useIdOnEmptyName && input.id,
                value = getFieldValue(key, opts.delimiter, data);

            if (typeof value === 'undefined' || value === null) {
                clearInput(input, triggerChange);
                continue;
            }
            var mutated = nodeCallback && nodeCallback(input, value);
            if (!mutated) setValueToInput(input, value, triggerChange);
        }
    }

    function getFieldValue(key, delimiter, ref) {
        if (!key) return;
        var parts = parseString(key, delimiter);
        for (var i = 0, l = parts.length; i < l; i++) {
            if (!ref) return;
            var part = ref[parts[i]];

            if (typeof part === 'undefined' || part === null) return;
            //if last
            if (i === l - 1) {
                return part;
            } else {
                var index = parts[i + 1];
                if (index === '') {
                    return part;
                } else if (isNumber(index)) {
                    //if second last
                    if (i === l - 2)
                        return part[index];
                    else
                        ref = part[index];
                    i++;
                } else {
                    ref = part;
                }
            }
        }
    }

    function contains(array, value) {
        for (var i = array.length; i--;)
            if (array[i] == value) return true;
        return false;
    }

    function setValueToInput(input, value, triggerChange) {
        var nodeType = input.type && input.type.toLowerCase();

        switch (nodeType) {
            case 'radio':
                if (value == input.value) input.checked = true;
                break;
            case 'checkbox':
                input.checked = isArray(value)
                    ? contains(value, input.value)
                    : value === true || value == input.value;
                break;
            case 'select-multiple':
                if (isArray(value))
                    for (var i = input.options.length; i--;)
                        input.options[i].selected = contains(value, input.options[i].value);
                else
                    input.value = value;
                break;
            case 'button':
            case 'submit':
            case 'reset':
            case 'file':
                break;
            default:
                input.value = value;
        }
        if (triggerChange)
            $(input).change();
    }

    /* Clear */
    function clear(options) {
        var opts = getOptions(options),
            triggerChange = opts.triggerChange,
            inputs = getFields(this, opts.skipDisabled, opts.skipReadOnly);

        for (var i = 0, l = inputs.length; i < l; i++)
            clearInput(inputs[i], triggerChange);
    }

    function clearInput(input, triggerChange) {
        var nodeType = input.type && input.type.toLowerCase();

        switch (nodeType) {
            case 'select-one':
                input.selectedIndex = 0;
                break;
			case 'select-multiple':
				for (var i = input.options.length; i--;)
					input.options[i].selected = false;
				break;
            case 'radio':
            case 'checkbox':
                if (input.checked) input.checked = false;
                break;
            case 'button':
            case 'submit':
            case 'reset':
            case 'file':
                break;
            default:
                input.value = '';
        }
        if (triggerChange)
            $(input).change();
    }

    /* Submit */
    function submit(html5Submit) {
        var el = this;
        if (!html5Submit) {
            if (isFunction(el.submit))
                el.submit();
            return;
        }

        var clean, btn = el.querySelector('[type="submit"]');
        if (!btn) {
            clean = true;
            btn = document.createElement('button');
            btn.type = 'submit';
            btn.style.display = 'none';
            el.appendChild(btn);
        }
        $(btn).click();
        if (clean) el.removeChild(btn);
    }

    /* Helper functions */
    function isObject(obj) {
        return $.type(obj) === 'object';
    }
    function isNumber(n) {
        return $.type(n) === 'number';
    }
    function isArray(arr) {
        return $.type(arr) === 'array';
    }
    function isFunction(fn) {
        return $.type(fn) === 'function';
    }
    function isString(s) {
        return $.type(s) === 'string';
    }

    function getFields(parent, skipDisabled, skipReadOnly) {
        var fields = ['input', 'select', 'textarea'];
        for (var i = 0; i < fields.length; i++) {
            var field = fields[i];
            if (skipDisabled) field += ':not([disabled])';
            if (skipReadOnly) field += ':not([readonly])';
            field += ':not([data-trans-form="ignore"])';
            fields[i] = field;
        }
        return parent.querySelectorAll(fields.join(','));
    }

    function getOptions(options) {
        var _defaults = $.fn.transForm.defaults;
        if (!isObject(options)) return _defaults;
        var o, opts = {};
        for (o in _defaults) opts[o] = _defaults[o];
        for (o in options) opts[o] = options[o];
        return opts;
    }

    function error(e) {
        $.error('transForm.js ♦ ' + e);
    }
})(window.Zepto || window.jQuery);
<|endoftext|>


<commit_before>import {
  name as LIB_NAME,
  version as LIB_VERSION
} from '../../package.json';

const {
  toString
} = Object.prototype;

function _isBasicObject(val) {
  return typeof val === 'object' &&
    val !== null &&
    val.__proto__ === undefined;
}

function _argsStr(count, name = 'arg') {
  let names = [];

  for (let i = 0; i < count; i++) {
    names.push(`${name}${i + 1}`);
  }

  return names.join(', ');
}

function typeStr(val, k = undefined) {
  let t = (_isBasicObject(val)) ?
    'BasicObject' :
    toString.call(val).match(/^\[object ([^\]]*)\]$/)[1];

  if (t === 'Object') {
    if (val.constructor && (
      (val.constructor.name && val.constructor.name !== t)
    )) {
      t = val.constructor.name;
    }
  }

  if (val instanceof Function) {
    if (val.name && val.name !== t && (
      val.name.match(/^[A-Z]/) ||
      (k &&
        ['__apivis__chain_link',
          'constructor',
          'prototype',
          '__proto__'
        ].includes(k)
      )
    )) {
      t = val.name;
    }

    t = `${t}(${_argsStr(val.length)})`;
  }

  if (val && (
    (val.hasOwnProperty && val.hasOwnProperty('constructor'))
  )) {
    if (!t.endsWith('Prototype')) {
      if (t === 'Object' && val !== Object.prototype) {
        t = 'Anonymous.prototype';
      } else {
        t = `${t}.prototype`;
      }
    }
  }

  if (val instanceof Error) {
    if (val.message) {
      t = `${t}("${val.message}")`;
    }
  }

  return t;
}

function descStr(val, k) {
  if (val === undefined || val === null) {
    return 'n/a';
  }

  let desc = Object.getOwnPropertyDescriptor(val, k);
  let d1 = '';
  let d2 = '';

  if (desc === undefined) {
    return 'n/a';
  }

  if (desc.hasOwnProperty('value')) { d1 += 'v'; }
  if (desc.writable) { d1 += 'w'; }
  if (desc.get) { d1 += 'g'; }
  if (desc.set) { d1 += 's'; }
  if (desc.enumerable) { d2 += 'e'; }
  if (desc.configurable) { d2 += 'c'; }

  return (d2) ?
    `${d1} ${d2}` :
    d1;
}

function members(val) {
  let symbols = Object.getOwnPropertySymbols(val).sort((a, b) => {
    let sa = String(a);
    let sb = String(b);

    return (sa < sb) ? -1 :
      (sa > sb) ? 1 :
        0;
  });
  let names = Object.getOwnPropertyNames(val).sort();

  return symbols.concat(names);
}

function membersStr(val, indent = '  ', level = 0, leaf = val) {
  return members(val).
    map(k => {
      // Do not attempt to resolve these
      let skip = [
        'arguments',
        'callee',
        'caller'
      ];
      // Only resolve these in the context of leaf
      let leafOnly = [
        '__proto__'
      ];
      let v;
      let sv = '';
      let smax = 101;

      // First resolve k in the context of leaf (like it would be normally)
      try {
        if (!skip.includes(k)) {
          v = leaf[k];
        }
      } catch (err) {
        v = err; // Make the error visible in the dump
      }

      // Then try resolving k in the context of val (reached through
      // following __proto__) to eventually get a shadowed value (some
      // props only make sense when resolved in the context of leaf
      // and an exception will be thrown upon trying to access them through val)
      try {
        if ( !(val === leaf || leafOnly.includes(k) || skip.includes(k)) ) {
          v = val[k];
        }
      } catch (err) {
        // Leave v as set by trying to resolve k in the context of leaf
      }

      // Show the values of primitive booleans, numbers and strings
      switch (typeof v) {
      case 'boolean':
      case 'number':
        sv = `(${v})`;

        break;
      case 'string':
        if (v.length > smax) {
          sv = `("${v.substr(0, smax)}...")`;
        } else {
          sv = `("${v}")`;
        }

        break;
      }

      return `${indent.repeat(level)}${String(k)}{${descStr(val, k)}}: ${typeStr(v, k)}${sv}`;
    }).
    join('\n');
}

function chain(val) {
  let links = [val];

  for (let link = Object.getPrototypeOf(val);
    link;
    link = Object.getPrototypeOf(link)
  ) {
    links.push(link);
  }

  return links;
}

function chainStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]`).
    join('\n');
}

function apiStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]\n${membersStr(v, indent, i + 1, val)}`).
    join('\n');
}

// peek42 plugin
function peek42(fnOutput, fnComment) {
  return {
    type(val, comment, opts) {
      fnOutput(
        typeStr(val),
        fnComment(comment, val, 'type'),
        opts
      );
    },
    desc(val, k, comment, opts) {
      fnOutput(
        descStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'desc'),
        opts
      );
    },
    members(val, comment, opts) {
      fnOutput(
        membersStr(val,
          (opts.indent === undefined) ? undefined : opts.indent,
          (opts.indentLevel === undefined) ? undefined : opts.indentLevel
        ),
        fnComment(comment, typeStr(val), 'members'),
        opts
      );
    },
    chain(val, comment, opts) {
      fnOutput(
        chainStr(val,
          (opts.indent === undefined) ? undefined : opts.indent
        ),
        fnComment(comment, typeStr(val), 'chain'),
        opts
      );
    },
    api(val, comment, opts) {
      fnOutput(
        apiStr(val,
          (opts.indent === undefined) ? undefined : opts.indent
        ),
        fnComment(comment, typeStr(val), 'api'),
        opts
      );
    }
  };
}

const apivis = {
  get [Symbol.toStringTag]() {
    return LIB_NAME;
  },
  version: LIB_VERSION,
  typeStr,
  descStr,
  members,
  membersStr,
  chain,
  chainStr,
  apiStr,
  peek42
};

export {typeStr, descStr, members, membersStr, chain, chainStr, apiStr};
export default apivis;
<commit_msg>Tweak typeStr logic<commit_after>import {
  name as LIB_NAME,
  version as LIB_VERSION
} from '../../package.json';

const {
  toString
} = Object.prototype;

function _isBasicObject(val) {
  return typeof val === 'object' &&
    val !== null &&
    val.__proto__ === undefined;
}

function _argsStr(count, name = 'arg') {
  let names = [];

  for (let i = 0; i < count; i++) {
    names.push(`${name}${i + 1}`);
  }

  return names.join(', ');
}

function typeStr(val, k = undefined) {
  let t = (_isBasicObject(val)) ?
    'BasicObject' :
    toString.call(val).match(/^\[object ([^\]]*)\]$/)[1];

  if (t === 'Object') {
    if (val.constructor && (
      (val.constructor.name && val.constructor.name !== t)
    )) {
      t = val.constructor.name;
    }
  }

  if (val instanceof Function) {
    if (val.name && val.name !== t && (
      val.name.match(/^[A-Z]/) ||
      (k &&
        ['__apivis__chain_link',
          'constructor',
          'prototype',
          '__proto__'
        ].includes(k)
      )
    )) {
      t = val.name;
    }

    t = `${t}(${_argsStr(val.length)})`;
  }

  if (val && (
    (val.hasOwnProperty && val.hasOwnProperty('constructor'))
  )) {
    if (!t.endsWith('Prototype') && (
      (t !== 'Object' || val === Object.prototype)
    )) {
      t = `${t}.prototype`;
    }
  }

  if (val instanceof Error) {
    if (val.message) {
      t = `${t}("${val.message}")`;
    }
  }

  return t;
}

function descStr(val, k) {
  if (val === undefined || val === null) {
    return 'n/a';
  }

  let desc = Object.getOwnPropertyDescriptor(val, k);
  let d1 = '';
  let d2 = '';

  if (desc === undefined) {
    return 'n/a';
  }

  if (desc.hasOwnProperty('value')) { d1 += 'v'; }
  if (desc.writable) { d1 += 'w'; }
  if (desc.get) { d1 += 'g'; }
  if (desc.set) { d1 += 's'; }
  if (desc.enumerable) { d2 += 'e'; }
  if (desc.configurable) { d2 += 'c'; }

  return (d2) ?
    `${d1} ${d2}` :
    d1;
}

function members(val) {
  let symbols = Object.getOwnPropertySymbols(val).sort((a, b) => {
    let sa = String(a);
    let sb = String(b);

    return (sa < sb) ? -1 :
      (sa > sb) ? 1 :
        0;
  });
  let names = Object.getOwnPropertyNames(val).sort();

  return symbols.concat(names);
}

function membersStr(val, indent = '  ', level = 0, leaf = val) {
  return members(val).
    map(k => {
      // Do not attempt to resolve these
      let skip = [
        'arguments',
        'callee',
        'caller'
      ];
      // Only resolve these in the context of leaf
      let leafOnly = [
        '__proto__'
      ];
      let v;
      let sv = '';
      let smax = 101;

      // First resolve k in the context of leaf (like it would be normally)
      try {
        if (!skip.includes(k)) {
          v = leaf[k];
        }
      } catch (err) {
        v = err; // Make the error visible in the dump
      }

      // Then try resolving k in the context of val (reached through
      // following __proto__) to eventually get a shadowed value (some
      // props only make sense when resolved in the context of leaf
      // and an exception will be thrown upon trying to access them through val)
      try {
        if ( !(val === leaf || leafOnly.includes(k) || skip.includes(k)) ) {
          v = val[k];
        }
      } catch (err) {
        // Leave v as set by trying to resolve k in the context of leaf
      }

      // Show the values of primitive booleans, numbers and strings
      switch (typeof v) {
      case 'boolean':
      case 'number':
        sv = `(${v})`;

        break;
      case 'string':
        if (v.length > smax) {
          sv = `("${v.substr(0, smax)}...")`;
        } else {
          sv = `("${v}")`;
        }

        break;
      }

      return `${indent.repeat(level)}${String(k)}{${descStr(val, k)}}: ${typeStr(v, k)}${sv}`;
    }).
    join('\n');
}

function chain(val) {
  let links = [val];

  for (let link = Object.getPrototypeOf(val);
    link;
    link = Object.getPrototypeOf(link)
  ) {
    links.push(link);
  }

  return links;
}

function chainStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]`).
    join('\n');
}

function apiStr(val, indent = '  ') {
  return chain(val).
    reverse().
    map((v, i) => `${indent.repeat(i)}[${typeStr(v, '__apivis__chain_link')}]\n${membersStr(v, indent, i + 1, val)}`).
    join('\n');
}

// peek42 plugin
function peek42(fnOutput, fnComment) {
  return {
    type(val, comment, opts) {
      fnOutput(
        typeStr(val),
        fnComment(comment, val, 'type'),
        opts
      );
    },
    desc(val, k, comment, opts) {
      fnOutput(
        descStr(val, k),
        fnComment(comment, `${String(k)} in ${typeStr(val)}`, 'desc'),
        opts
      );
    },
    members(val, comment, opts) {
      fnOutput(
        membersStr(val,
          (opts.indent === undefined) ? undefined : opts.indent,
          (opts.indentLevel === undefined) ? undefined : opts.indentLevel
        ),
        fnComment(comment, typeStr(val), 'members'),
        opts
      );
    },
    chain(val, comment, opts) {
      fnOutput(
        chainStr(val,
          (opts.indent === undefined) ? undefined : opts.indent
        ),
        fnComment(comment, typeStr(val), 'chain'),
        opts
      );
    },
    api(val, comment, opts) {
      fnOutput(
        apiStr(val,
          (opts.indent === undefined) ? undefined : opts.indent
        ),
        fnComment(comment, typeStr(val), 'api'),
        opts
      );
    }
  };
}

const apivis = {
  get [Symbol.toStringTag]() {
    return LIB_NAME;
  },
  version: LIB_VERSION,
  typeStr,
  descStr,
  members,
  membersStr,
  chain,
  chainStr,
  apiStr,
  peek42
};

export {typeStr, descStr, members, membersStr, chain, chainStr, apiStr};
export default apivis;
<|endoftext|>


<commit_before>export default (template, values = {}) => {
    let path = template;

    Object.keys(values).forEach((key) => {
        if (Object.prototype.hasOwnProperty.call(values, key)) {
            path = path.replace(`{${key}}`, values[key]);
        }
    });

    return path;
};
<commit_msg>Removed unnecessary check in createPath (#13)<commit_after>export default (template, values = {}) => {
    let path = template;

    Object.keys(values).forEach((key) => {
        path = path.replace(`{${key}}`, values[key]);
    });

    return path;
};
<|endoftext|>


<commit_before>import Typography from 'typography';

const typography = new Typography({
  baseFontSize: '16px',
});

export default typography;
<commit_msg>Add base font styles<commit_after>import Typography from 'typography';

const headerGoogleFont = 'Source Sans Pro';
const bodyGoogleFont = 'Open Sans';

const typography = new Typography({
  baseFontSize: '16px',
  baseLineHeight: 1.666,
  scaleRatio: 1.666,
  headerFontFamily: [headerGoogleFont, 'sans-serif'],
  bodyFontFamily: [bodyGoogleFont, 'sans-serif'],
  googleFonts: [
    {
      name: bodyGoogleFont,
      styles: [
        '300',
        '400'
      ],
    },
    {
      name: headerGoogleFont,
      styles: [
        '500'
      ]
    }
  ],
});

export default typography;
<|endoftext|>


<commit_before>import { VALIDATE_UPDATE } from '../const'
import util, { empty, each, trigger, isPromise, toggleClasses } from '../util'

/**
 * BaseValidation class
 */

export default class BaseValidation {

  constructor (field, model, vm, el, scope, validator, filters, detectBlur, detectChange) {
    this.field = field
    this.touched = false
    this.dirty = false
    this.modified = false

    this._modified = false
    this._model = model
    this._filters = filters
    this._validator = validator
    this._vm = vm
    this._el = el
    this._forScope = scope
    this._init = this._getValue(el)
    this._validators = {}
    this._detectBlur = detectBlur
    this._detectChange = detectChange
    this._classes = {}
  }

  get vm () { return this._vm }

  get el () { return this._el }

  get detectChange () { return this._detectChange }
  set detectChange (val) { this._detectChange = val }

  get detectBlur () { return this._detectBlur }
  set detectBlur (val) { this._detectBlur = val }

  manageElement (el, initial) {
    const scope = this._getScope()
    const model = this._model

    this._initial = initial

    const classIds = el.getAttribute(VALIDATE_UPDATE)
    if (classIds) {
      el.removeAttribute(VALIDATE_UPDATE)
      this._classIds = classIds.split(',')
    }

    if (model) {
      el.value = this._evalModel(model, this._filters)
      this._unwatch = scope.$watch(model, (val, old) => {
        if (val !== old) {
          if (this.guardValidate(el, 'input')) {
            return
          }

          this.handleValidate(el, { noopable: this._initial })
          if (this._initial) {
            this._initial = null
          }
        }
      }, { deep: true })
    }
  }

  unmanageElement (el) {
    this._unwatch && this._unwatch()
  }

  setValidation (name, arg, msg, initial) {
    let validator = this._validators[name]
    if (!validator) {
      validator = this._validators[name] = {}
      validator.name = name
    }

    validator.arg = arg
    if (msg) {
      validator.msg = msg
    }

    if (initial) {
      validator.initial = initial
      validator._isNoopable = true
    }
  }

  setValidationClasses (classes) {
    each(classes, (value, key) => {
      this._classes[key] = value
    })
  }

  willUpdateFlags (touched = false) {
    touched && this.willUpdateTouched(this._el, 'blur')
    this.willUpdateDirty(this._el)
    this.willUpdateModified(this._el)
  }

  willUpdateTouched (el, type) {
    if (type && type === 'blur') {
      this.touched = true
      this._fireEvent(el, 'touched')
    }
  }

  willUpdateDirty (el) {
    if (!this.dirty && this._checkModified(el)) {
      this.dirty = true
      this._fireEvent(el, 'dirty')
    }
  }

  willUpdateModified (el) {
    this.modified = this._checkModified(el)
    if (this._modified !== this.modified) {
      this._fireEvent(el, 'modified', { modified: this.modified })
      this._modified = this.modified
    }
  }

  listener (e) {
    if (this.guardValidate(e.target, e.type)) {
      return
    }

    this.handleValidate(e.target, { type: e.type })
  }

  handleValidate (el, { type = null, noopable = false } = {}) {
    this.willUpdateTouched(el, type)
    this.willUpdateDirty(el)
    this.willUpdateModified(el)

    this._validator.validate({ field: this.field, el: el, noopable: noopable })
  }

  validate (cb, noopable = false, el = null) {
    const _ = util.Vue.util

    let results = {}
    let errors = []
    let valid = true

    this._runValidators((descriptor, name, done) => {
      let asset = this._resolveValidator(name)
      let validator = null
      let msg = null

      if (_.isPlainObject(asset)) {
        if (asset.check && typeof asset.check === 'function') {
          validator = asset.check
        }
        if (asset.message) {
          msg = asset.message
        }
      } else if (typeof asset === 'function') {
        validator = asset
      }

      if (descriptor.msg) {
        msg = descriptor.msg
      }

      if (noopable) {
        results[name] = false
        return done()
      }

      if (descriptor._isNoopable) {
        results[name] = false
        descriptor._isNoopable = null
        return done()
      }

      if (validator) {
        let value = this._getValue(this._el)
        this._invokeValidator(this._vm, validator, value, descriptor.arg, (ret, err) => {
          if (!ret) {
            valid = false
            if (err) { // async error message
              errors.push({ validator: name, message: err })
              results[name] = err
            } else if (msg) {
              let error = { validator: name }
              error.message = typeof msg === 'function'
                ? msg.call(this._vm, this.field, descriptor.arg)
                : msg
              errors.push(error)
              results[name] = error.message
            } else {
              results[name] = !ret
            }
          } else {
            results[name] = !ret
          }

          done()
        })
      } else {
        done()
      }
    }, () => { // finished
      this._fireEvent(this._el, valid ? 'valid' : 'invalid')

      let props = {
        valid: valid,
        invalid: !valid,
        touched: this.touched,
        untouched: !this.touched,
        dirty: this.dirty,
        pristine: !this.dirty,
        modified: this.modified
      }
      if (!empty(errors)) {
        props.errors = errors
      }
      _.extend(results, props)

      this.willUpdateClasses(results, el)

      cb(results)
    })
  }

  resetFlags () {
    this.touched = false
    this.dirty = false
    this.modified = false
    this._modified = false
  }

  reset () {
    each(this._validators, (descriptor, key) => {
      if (descriptor.initial && !descriptor._isNoopable) {
        descriptor._isNoopable = true
      }
    })
    this.resetFlags()
    this._init = this._getValue(this._el)
  }

  willUpdateClasses (results, el = null) {
    if (this._checkClassIds(el)) {
      const classIds = this._getClassIds(el)
      this.vm.$nextTick(() => {
        this.vm.$emit(VALIDATE_UPDATE, classIds, this, results)
      })
    } else {
      this.updateClasses(results)
    }
  }

  updateClasses (results, el = null) {
    this._updateClasses(el || this._el, results)
  }

  guardValidate (el, type) {
    if (type && type === 'blur' && !this.detectBlur) {
      return true
    }

    if (type && type === 'input' && !this.detectChange) {
      return true
    }

    if (type && type === 'change' && !this.detectChange) {
      return true
    }

    if (type && type === 'click' && !this.detectChange) {
      return true
    }

    return false
  }

  _getValue (el) {
    return el.value
  }

  _getScope () {
    return this._forScope || this._vm
  }

  _getClassIds (el) {
    return this._classIds
  }

  _checkModified (target) {
    return this._init !== this._getValue(target)
  }

  _checkClassIds (el) {
    return this._getClassIds(el)
  }

  _fireEvent (el, type, args) {
    trigger(el, type, args)
  }

  _evalModel (model, filters) {
    const scope = this._getScope()

    let val = null
    if (filters) {
      val = scope.$get(model)
      return filters ? this._applyFilters(val, null, filters) : val
    } else {
      val = scope.$get(model)
      return val === undefined || val === null ? '' : val
    }
  }

  _updateClasses (el, results) {
    this._toggleValid(el, results.valid)
    this._toggleTouched(el, results.touched)
    this._togglePristine(el, results.pristine)
    this._toggleModfied(el, results.modified)
  }

  _toggleValid (el, valid) {
    const { addClass, removeClass } = util.Vue.util
    const validClass = this._classes.valid || 'valid'
    const invalidClass = this._classes.invalid || 'invalid'

    if (valid) {
      toggleClasses(el, validClass, addClass)
      toggleClasses(el, invalidClass, removeClass)
    } else {
      toggleClasses(el, validClass, removeClass)
      toggleClasses(el, invalidClass, addClass)
    }
  }

  _toggleTouched (el, touched) {
    const { addClass, removeClass } = util.Vue.util
    const touchedClass = this._classes.touched || 'touched'
    const untouchedClass = this._classes.untouched || 'untouched'

    if (touched) {
      toggleClasses(el, touchedClass, addClass)
      toggleClasses(el, untouchedClass, removeClass)
    } else {
      toggleClasses(el, touchedClass, removeClass)
      toggleClasses(el, untouchedClass, addClass)
    }
  }

  _togglePristine (el, pristine) {
    const { addClass, removeClass } = util.Vue.util
    const pristineClass = this._classes.pristine || 'pristine'
    const dirtyClass = this._classes.dirty || 'dirty'

    if (pristine) {
      toggleClasses(el, pristineClass, addClass)
      toggleClasses(el, dirtyClass, removeClass)
    } else {
      toggleClasses(el, pristineClass, removeClass)
      toggleClasses(el, dirtyClass, addClass)
    }
  }

  _toggleModfied (el, modified) {
    const { addClass, removeClass } = util.Vue.util
    const modifiedClass = this._classes.modified || 'modified'

    if (modified) {
      toggleClasses(el, modifiedClass, addClass)
    } else {
      toggleClasses(el, modifiedClass, removeClass)
    }
  }

  _applyFilters (value, oldValue, filters, write) {
    const resolveAsset = util.Vue.util.resolveAsset
    const scope = this._getScope()

    let filter, fn, args, arg, offset, i, l, j, k
    for (i = 0, l = filters.length; i < l; i++) {
      filter = filters[i]
      fn = resolveAsset(this._vm.$options, 'filters', filter.name)
      if (!fn) { continue }

      fn = write ? fn.write : (fn.read || fn)
      if (typeof fn !== 'function') { continue }

      args = write ? [value, oldValue] : [value]
      offset = write ? 2 : 1
      if (filter.args) {
        for (j = 0, k = filter.args.length; j < k; j++) {
          arg = filter.args[j]
          args[j + offset] = arg.dynamic ? scope.$get(arg.value) : arg.value
        }
      }

      value = fn.apply(this._vm, args)
    }

    return value
  }

  _runValidators (fn, cb) {
    const validators = this._validators
    const length = Object.keys(validators).length

    let count = 0
    each(validators, (descriptor, name) => {
      fn(descriptor, name, () => {
        ++count
        count >= length && cb()
      })
    })
  }

  _invokeValidator (vm, validator, val, arg, cb) {
    let future = validator.call(this, val, arg)
    if (typeof future === 'function') { // function
      if (future.resolved) {
        // cached
        cb(future.resolved)
      } else if (future.requested) {
        // pool callbacks
        future.pendingCallbacks.push(cb)
      } else {
        future.requested = true
        let cbs = future.pendingCallbacks = [cb]
        future(() => { // resolve
          future.resolved = true
          for (let i = 0, l = cbs.length; i < l; i++) {
            cbs[i](true)
          }
        }, (msg) => { // reject
          cb(false, msg)
        })
      }
    } else if (isPromise(future)) { // promise
      future.then(() => { // resolve
        cb(true)
      }, (msg) => { // reject
        cb(false, msg)
      }).catch((err) => {
        cb(false, err.message)
      })
    } else { // sync
      cb(future)
    }
  }

  _resolveValidator (name) {
    const resolveAsset = util.Vue.util.resolveAsset
    return resolveAsset(this._vm.$options, 'validators', name)
  }
}
<commit_msg>:zap: improvement(async): update async validator for function I/F<commit_after>import { VALIDATE_UPDATE } from '../const'
import util, { empty, each, trigger, isPromise, toggleClasses } from '../util'

/**
 * BaseValidation class
 */

export default class BaseValidation {

  constructor (field, model, vm, el, scope, validator, filters, detectBlur, detectChange) {
    this.field = field
    this.touched = false
    this.dirty = false
    this.modified = false

    this._modified = false
    this._model = model
    this._filters = filters
    this._validator = validator
    this._vm = vm
    this._el = el
    this._forScope = scope
    this._init = this._getValue(el)
    this._validators = {}
    this._detectBlur = detectBlur
    this._detectChange = detectChange
    this._classes = {}
  }

  get vm () { return this._vm }

  get el () { return this._el }

  get detectChange () { return this._detectChange }
  set detectChange (val) { this._detectChange = val }

  get detectBlur () { return this._detectBlur }
  set detectBlur (val) { this._detectBlur = val }

  manageElement (el, initial) {
    const scope = this._getScope()
    const model = this._model

    this._initial = initial

    const classIds = el.getAttribute(VALIDATE_UPDATE)
    if (classIds) {
      el.removeAttribute(VALIDATE_UPDATE)
      this._classIds = classIds.split(',')
    }

    if (model) {
      el.value = this._evalModel(model, this._filters)
      this._unwatch = scope.$watch(model, (val, old) => {
        if (val !== old) {
          if (this.guardValidate(el, 'input')) {
            return
          }

          this.handleValidate(el, { noopable: this._initial })
          if (this._initial) {
            this._initial = null
          }
        }
      }, { deep: true })
    }
  }

  unmanageElement (el) {
    this._unwatch && this._unwatch()
  }

  setValidation (name, arg, msg, initial) {
    let validator = this._validators[name]
    if (!validator) {
      validator = this._validators[name] = {}
      validator.name = name
    }

    validator.arg = arg
    if (msg) {
      validator.msg = msg
    }

    if (initial) {
      validator.initial = initial
      validator._isNoopable = true
    }
  }

  setValidationClasses (classes) {
    each(classes, (value, key) => {
      this._classes[key] = value
    })
  }

  willUpdateFlags (touched = false) {
    touched && this.willUpdateTouched(this._el, 'blur')
    this.willUpdateDirty(this._el)
    this.willUpdateModified(this._el)
  }

  willUpdateTouched (el, type) {
    if (type && type === 'blur') {
      this.touched = true
      this._fireEvent(el, 'touched')
    }
  }

  willUpdateDirty (el) {
    if (!this.dirty && this._checkModified(el)) {
      this.dirty = true
      this._fireEvent(el, 'dirty')
    }
  }

  willUpdateModified (el) {
    this.modified = this._checkModified(el)
    if (this._modified !== this.modified) {
      this._fireEvent(el, 'modified', { modified: this.modified })
      this._modified = this.modified
    }
  }

  listener (e) {
    if (this.guardValidate(e.target, e.type)) {
      return
    }

    this.handleValidate(e.target, { type: e.type })
  }

  handleValidate (el, { type = null, noopable = false } = {}) {
    this.willUpdateTouched(el, type)
    this.willUpdateDirty(el)
    this.willUpdateModified(el)

    this._validator.validate({ field: this.field, el: el, noopable: noopable })
  }

  validate (cb, noopable = false, el = null) {
    const _ = util.Vue.util

    let results = {}
    let errors = []
    let valid = true

    this._runValidators((descriptor, name, done) => {
      let asset = this._resolveValidator(name)
      let validator = null
      let msg = null

      if (_.isPlainObject(asset)) {
        if (asset.check && typeof asset.check === 'function') {
          validator = asset.check
        }
        if (asset.message) {
          msg = asset.message
        }
      } else if (typeof asset === 'function') {
        validator = asset
      }

      if (descriptor.msg) {
        msg = descriptor.msg
      }

      if (noopable) {
        results[name] = false
        return done()
      }

      if (descriptor._isNoopable) {
        results[name] = false
        descriptor._isNoopable = null
        return done()
      }

      if (validator) {
        let value = this._getValue(this._el)
        this._invokeValidator(this._vm, validator, value, descriptor.arg, (ret, err) => {
          if (!ret) {
            valid = false
            if (err) { // async error message
              errors.push({ validator: name, message: err })
              results[name] = err
            } else if (msg) {
              let error = { validator: name }
              error.message = typeof msg === 'function'
                ? msg.call(this._vm, this.field, descriptor.arg)
                : msg
              errors.push(error)
              results[name] = error.message
            } else {
              results[name] = !ret
            }
          } else {
            results[name] = !ret
          }

          done()
        })
      } else {
        done()
      }
    }, () => { // finished
      this._fireEvent(this._el, valid ? 'valid' : 'invalid')

      let props = {
        valid: valid,
        invalid: !valid,
        touched: this.touched,
        untouched: !this.touched,
        dirty: this.dirty,
        pristine: !this.dirty,
        modified: this.modified
      }
      if (!empty(errors)) {
        props.errors = errors
      }
      _.extend(results, props)

      this.willUpdateClasses(results, el)

      cb(results)
    })
  }

  resetFlags () {
    this.touched = false
    this.dirty = false
    this.modified = false
    this._modified = false
  }

  reset () {
    each(this._validators, (descriptor, key) => {
      if (descriptor.initial && !descriptor._isNoopable) {
        descriptor._isNoopable = true
      }
    })
    this.resetFlags()
    this._init = this._getValue(this._el)
  }

  willUpdateClasses (results, el = null) {
    if (this._checkClassIds(el)) {
      const classIds = this._getClassIds(el)
      this.vm.$nextTick(() => {
        this.vm.$emit(VALIDATE_UPDATE, classIds, this, results)
      })
    } else {
      this.updateClasses(results)
    }
  }

  updateClasses (results, el = null) {
    this._updateClasses(el || this._el, results)
  }

  guardValidate (el, type) {
    if (type && type === 'blur' && !this.detectBlur) {
      return true
    }

    if (type && type === 'input' && !this.detectChange) {
      return true
    }

    if (type && type === 'change' && !this.detectChange) {
      return true
    }

    if (type && type === 'click' && !this.detectChange) {
      return true
    }

    return false
  }

  _getValue (el) {
    return el.value
  }

  _getScope () {
    return this._forScope || this._vm
  }

  _getClassIds (el) {
    return this._classIds
  }

  _checkModified (target) {
    return this._init !== this._getValue(target)
  }

  _checkClassIds (el) {
    return this._getClassIds(el)
  }

  _fireEvent (el, type, args) {
    trigger(el, type, args)
  }

  _evalModel (model, filters) {
    const scope = this._getScope()

    let val = null
    if (filters) {
      val = scope.$get(model)
      return filters ? this._applyFilters(val, null, filters) : val
    } else {
      val = scope.$get(model)
      return val === undefined || val === null ? '' : val
    }
  }

  _updateClasses (el, results) {
    this._toggleValid(el, results.valid)
    this._toggleTouched(el, results.touched)
    this._togglePristine(el, results.pristine)
    this._toggleModfied(el, results.modified)
  }

  _toggleValid (el, valid) {
    const { addClass, removeClass } = util.Vue.util
    const validClass = this._classes.valid || 'valid'
    const invalidClass = this._classes.invalid || 'invalid'

    if (valid) {
      toggleClasses(el, validClass, addClass)
      toggleClasses(el, invalidClass, removeClass)
    } else {
      toggleClasses(el, validClass, removeClass)
      toggleClasses(el, invalidClass, addClass)
    }
  }

  _toggleTouched (el, touched) {
    const { addClass, removeClass } = util.Vue.util
    const touchedClass = this._classes.touched || 'touched'
    const untouchedClass = this._classes.untouched || 'untouched'

    if (touched) {
      toggleClasses(el, touchedClass, addClass)
      toggleClasses(el, untouchedClass, removeClass)
    } else {
      toggleClasses(el, touchedClass, removeClass)
      toggleClasses(el, untouchedClass, addClass)
    }
  }

  _togglePristine (el, pristine) {
    const { addClass, removeClass } = util.Vue.util
    const pristineClass = this._classes.pristine || 'pristine'
    const dirtyClass = this._classes.dirty || 'dirty'

    if (pristine) {
      toggleClasses(el, pristineClass, addClass)
      toggleClasses(el, dirtyClass, removeClass)
    } else {
      toggleClasses(el, pristineClass, removeClass)
      toggleClasses(el, dirtyClass, addClass)
    }
  }

  _toggleModfied (el, modified) {
    const { addClass, removeClass } = util.Vue.util
    const modifiedClass = this._classes.modified || 'modified'

    if (modified) {
      toggleClasses(el, modifiedClass, addClass)
    } else {
      toggleClasses(el, modifiedClass, removeClass)
    }
  }

  _applyFilters (value, oldValue, filters, write) {
    const resolveAsset = util.Vue.util.resolveAsset
    const scope = this._getScope()

    let filter, fn, args, arg, offset, i, l, j, k
    for (i = 0, l = filters.length; i < l; i++) {
      filter = filters[i]
      fn = resolveAsset(this._vm.$options, 'filters', filter.name)
      if (!fn) { continue }

      fn = write ? fn.write : (fn.read || fn)
      if (typeof fn !== 'function') { continue }

      args = write ? [value, oldValue] : [value]
      offset = write ? 2 : 1
      if (filter.args) {
        for (j = 0, k = filter.args.length; j < k; j++) {
          arg = filter.args[j]
          args[j + offset] = arg.dynamic ? scope.$get(arg.value) : arg.value
        }
      }

      value = fn.apply(this._vm, args)
    }

    return value
  }

  _runValidators (fn, cb) {
    const validators = this._validators
    const length = Object.keys(validators).length

    let count = 0
    each(validators, (descriptor, name) => {
      fn(descriptor, name, () => {
        ++count
        count >= length && cb()
      })
    })
  }

  _invokeValidator (vm, validator, val, arg, cb) {
    let future = validator.call(this, val, arg)
    if (typeof future === 'function') { // function
      future(() => { // resolve
        cb(true)
      }, (msg) => { // reject
        cb(false, msg)
      })
    } else if (isPromise(future)) { // promise
      future.then(() => { // resolve
        cb(true)
      }, (msg) => { // reject
        cb(false, msg)
      }).catch((err) => {
        cb(false, err.message)
      })
    } else { // sync
      cb(future)
    }
  }

  _resolveValidator (name) {
    const resolveAsset = util.Vue.util.resolveAsset
    return resolveAsset(this._vm.$options, 'validators', name)
  }
}
<|endoftext|>


<commit_before>
'use strict';

var utils = require('../utils');
var onFileProgress = utils.onFileProgress;
var handleFileUpload = require('../fileupload').handleFileUpload;
var initSocket = require('../socket').initSocket;
var showError = require('./showerror').showError;
var effects = require('./effects');

var playSample = function(token, imageTag, iconName, url, callback) {

  var timer = setInterval(effects.toggleImage, 750, imageTag, iconName);

  var xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);
  xhr.responseType = 'blob';
  xhr.onload = function(e) {
    var blob = xhr.response;
    var currentModel = localStorage.getItem('currentModel');
    var reader = new FileReader();
    var blobToText = new Blob([blob]).slice(0, 4);
    console.log('TOKEN', token);
    console.log('URL', url);
    console.log('BLOB', blob);
    reader.readAsText(blobToText);
    reader.onload = function() {
      var contentType = reader.result === 'fLaC' ? 'audio/flac' : 'audio/wav';
      console.log('Uploading file', reader.result);
      handleFileUpload(token, currentModel, blob, contentType, function(socket) {
        var parseOptions = {
          file: blob
        };
        onFileProgress(parseOptions,
          // On data chunk
          function(chunk) {
            console.log('Handling chunk', chunk);
            socket.send(chunk);
          },
          // On file read error
          function(evt) {
            console.log('Error reading file: ', evt.message);
            showError(evt.message);
          },
          // On load end
          function() {
            socket.send(JSON.stringify({'action': 'stop'}));
          });
      },
      // On connection end
        function(evt) {
          effects.stopToggleImage(timer, imageTag, iconName);
        }
      );
    };
  };
  xhr.send();
};

exports.initPlaySample = function(ctx) {

  (function() {
    var el = $('.play-sample-1');
    var iconName = 'play';
    var imageTag = el.find('img');
    var fileName = 'audio/sample1.wav';
    el.click( function(evt) {
      console.log('CLICK!');
      playSample(ctx.token, imageTag, iconName, fileName, function(result) {
        console.log('Play sample result', result);
      });
    });
  })(ctx);

  (function() {
    var el = $('.play-sample-2');
    var iconName = 'play';
    var imageTag = el.find('img');
    var fileName = 'audio/sample2.wav';
    el.click( function(evt) {
      console.log('CLICK!');
      playSample(ctx.token, imageTag, iconName, fileName, function(result) {
        console.log('Play sample result', result);
      });
    });
  })(ctx);

};

<commit_msg>Add hard-coded model value for play samples<commit_after>
'use strict';

var utils = require('../utils');
var onFileProgress = utils.onFileProgress;
var handleFileUpload = require('../fileupload').handleFileUpload;
var initSocket = require('../socket').initSocket;
var showError = require('./showerror').showError;
var effects = require('./effects');

var playSample = function(token, imageTag, iconName, url, callback) {

  var timer = setInterval(effects.toggleImage, 750, imageTag, iconName);

  var xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);
  xhr.responseType = 'blob';
  xhr.onload = function(e) {
    var blob = xhr.response;
    var currentModel = 'en-US_BroadbandModel';
    var reader = new FileReader();
    var blobToText = new Blob([blob]).slice(0, 4);
    console.log('TOKEN', token);
    console.log('URL', url);
    console.log('BLOB', blob);
    reader.readAsText(blobToText);
    reader.onload = function() {
      var contentType = reader.result === 'fLaC' ? 'audio/flac' : 'audio/wav';
      console.log('Uploading file', reader.result);
      handleFileUpload(token, currentModel, blob, contentType, function(socket) {
        var parseOptions = {
          file: blob
        };
        onFileProgress(parseOptions,
          // On data chunk
          function(chunk) {
            console.log('Handling chunk', chunk);
            socket.send(chunk);
          },
          // On file read error
          function(evt) {
            console.log('Error reading file: ', evt.message);
            showError(evt.message);
          },
          // On load end
          function() {
            socket.send(JSON.stringify({'action': 'stop'}));
          });
      },
      // On connection end
        function(evt) {
          effects.stopToggleImage(timer, imageTag, iconName);
        }
      );
    };
  };
  xhr.send();
};

exports.initPlaySample = function(ctx) {

  (function() {
    var el = $('.play-sample-1');
    var iconName = 'play';
    var imageTag = el.find('img');
    var fileName = 'audio/sample1.wav';
    el.click( function(evt) {
      console.log('CLICK!');
      playSample(ctx.token, imageTag, iconName, fileName, function(result) {
        console.log('Play sample result', result);
      });
    });
  })(ctx);

  (function() {
    var el = $('.play-sample-2');
    var iconName = 'play';
    var imageTag = el.find('img');
    var fileName = 'audio/sample2.wav';
    el.click( function(evt) {
      console.log('CLICK!');
      playSample(ctx.token, imageTag, iconName, fileName, function(result) {
        console.log('Play sample result', result);
      });
    });
  })(ctx);

};

<|endoftext|>