<commit_before>
var fs = require('fs');
var util=require('util');
var path=require('path');
var watch=require('watch');
var JSON_stringify = require('json-stable-stringify');

var ls=function(a) { console.log(util.inspect(a,{depth:null})); }

// wrap so we can contain multiple environments without borking
exports.create=function(opts,plated){

	var timestr=function(){ return new Date().toISOString().replace(/^.+T/, "").replace(/\..+/, ""); }

	var plated_files={};

	plated_files.mkdir = function(dir){
		if (fs.existsSync(dir)){
			return
		}

		try{
			fs.mkdirSync(dir)
		}catch(err){
			if(err.code == 'ENOENT'){
				plated_files.mkdir(path.dirname(dir)) //create parent dir
				plated_files.mkdir(dir) //create dir
			}
		}
	}

// fill in _source and related chunks
	plated_files.set_source=function(chunks,source)
	{
		chunks._sourcename=plated_files.filename_fixup(source);

		chunks._filename=plated_files.filename_to_output(chunks._sourcename);

		chunks._dirname=plated_files.filename_to_dirname(chunks._sourcename);

		chunks._root=opts.root; // probably just "/"
		chunks._filename=opts.root+chunks._filename;
		chunks._dirname=opts.root+chunks._dirname;

		return chunks;
	}

// create parent dir if necessary and write data into this file
	plated_files.write = function(filename,data) {
		plated_files.mkdir( path.dirname(filename) );
		fs.writeFileSync( filename , data );
	};

// get the dirname of this filename
	plated_files.filename_fixup = function(filename) {
		if( filename =="." ) { filename =""; }
		if( filename =="/." ) { filename =""; }
		if( filename =="/" ) { filename =""; }
		return filename;
	}

// get the dirname of this filename
	plated_files.filename_to_dirname = function(filename) {
		return plated_files.filename_fixup(path.dirname(filename));
	}

// convert a source path into an output path
	plated_files.source_to_output = function(path) {
		var ps=path.replace(opts.source,opts.output);
		if( ps.startsWith(opts.output) ) { return ps; }
		return null;
	};

// is this filename part of the basechunks for a dir
	plated_files.filename_is_basechunk=function(fname)
	{
		var vv=path.basename(fname).split(".");
		if( vv[0]==opts.hashfile )
		{
			return true
		}
		return false;
	}

// is this filename something we need to run through plated
	plated_files.filename_is_plated=function(fname)
	{
		var vv=path.basename(fname).split(".");
		if( vv.length>2 && vv[ vv.length-2 ]==opts.hashfile )
		{
			return true
		}
		return false;
	}

// output filename
	plated_files.filename_to_output=function(fname)
	{
		var d=path.dirname(fname);
		var vv=path.basename(fname).split(".");
		for(var i=vv.length-1;i>0;i--)
		{
			if( vv[i] == opts.hashfile )
			{
				vv.splice(i,1);
			}
		}
		return plated_files.filename_fixup( path.join(d,vv.join(".")) );
	}

// empty the (output) folder or make it if it does not exist
	plated_files.empty_folder = function(path) {
		var files = [];
		if( fs.existsSync(path) ) {
			files = fs.readdirSync(path);
			files.forEach(function(file,index){
				var curPath = path + "/" + file;
				if(fs.lstatSync(curPath).isDirectory()) { // recurse
					plated_files.empty_folder(curPath);
				} else { // delete file
					if(file!=".git") // dont delete .git files // TODO:make generic rule? We need t keep .git for submodules
					{
						fs.unlinkSync(curPath);
					}
				}
			});
		}
		else
		{
			try { fs.mkdirSync(path); } catch(e){} // create it
		}
	};

// call f with every file we find
	plated_files.find_files = function(root,name,f) {
		var files=fs.readdirSync( path.join(root,name) );
		for(var i in files){ var v=files[i];
			var st=fs.lstatSync( path.join(root,name,v) );
			if( st.isDirectory() || st.isSymbolicLink() )
			{
				plated_files.find_files(root,path.join(name,v),f);
			}
			else
			{
				f( path.join(name,v) );
			}
		}
	};

// call f with every dir we find
	plated_files.find_dirs = function(root,name,f) {
		f(name);
		var files=fs.readdirSync( path.join(root,name) );
		for(var i in files){ var v=files[i];
			var st=fs.lstatSync( path.join(root,name,v) );
			if( st.isDirectory() || st.isSymbolicLink() )
			{
				plated_files.find_dirs(root,path.join(name,v),f);
			}
		}
	};

	var cache={}

	plated_files.empty_cache=function()
	{
		cache={};
	}

	plated_files.file_to_chunks=function(root,fname,chunks)
	{
		if(!cache[fname])
		{
			var s;
			try { s=fs.readFileSync(path.join(root,fname),'utf8'); } catch(e){}
			if(s)
			{
				cache[fname]=s;
			}
		}
		return plated.chunks.fill_chunks( cache[fname] , chunks);
	}

// check this directory and all directories above for generic chunks
// build all of these into the current chunk namespace for this file
	plated_files.prepare_namespace=function(fname)
	{
		var ns=[];

		var list=[];
		var rf=function(fn){
			var d=path.dirname(fn);
			if(d==".") { d=""; }

			var chunks=plated.dirs[d];
			if( chunks ) { ns.push(chunks); }

			if((d!="")&&(d!=".")&&(d!="/")) { rf(d); } // next dir
		};
		rf(fname)

		ns.reverse();

		plated.chunks.set_namespace(ns);

	}

// check this directory and all directories above for generic chunks
// build all of these into the current chunk namespace for this file
	plated_files.base_files_to_chunks=function(fname)
	{
		var list=[];
		var rf=function(fn){
			var d=path.dirname(fn);
			var p=path.join(opts.source,d);
			var files=fs.readdirSync(p);
			files.sort();
			files.reverse();
			for(var i in files){ var v=files[i];
				if( plated_files.filename_is_basechunk(v) )
				{
					var p2=path.join(d,v);
					list.push(p2);
				}
			}
		};
		rf(fname)

		var chunks={};
		for(var i=list.length-1 ; i>=0 ; i--) { var v=list[i];
			plated_files.file_to_chunks(opts.source,v,chunks);
		}
		return chunks;
	}

// build the given source filename, using chunks or maybe just a raw copy
	plated_files.build_file=function(fname)
	{
		if(plated_files.filename_is_plated(fname))
		{
			var output_filename = path.join( opts.output , plated.files.filename_to_output(fname) );

			plated_files.prepare_namespace(fname); // prepare merged namespace

			var chunks={};

			plated_files.file_to_chunks(opts.source, fname , chunks); // read chunks from this file

			plated_files.set_source(chunks,fname)

			plated.chunks.format_chunks( chunks);

			// run chunks through plugins, eg special blog handling
			for(var idx in plated.process_file) { var f=plated.process_file[idx];
				chunks = f( chunks ); // adjust and or output special chunks or files
			}

			var merged_chunks=plated.chunks.merge_namespace(chunks);

			merged_chunks._output_filename=plated.files.filename_to_output(fname)
			merged_chunks._output_chunkname=fname.split('.').pop()
			plated.output.remember_and_write( merged_chunks )

//			plated_files.write( output_filename , plated.chunks.replace( plated.chunks.delimiter_wrap_str(fname.split('.').pop()),merged_chunks) );
//			if(opts.dumpjson){
//				plated_files.write( output_filename+".json" , JSON_stringify(merged_chunks,{space:1}) );
//			}

		}
		else
		{
			plated_files.write( path.join(opts.output,fname), fs.readFileSync( path.join(opts.source,fname) ));
		}
	}

// build all files found in the source dir into the output dir
	plated_files.build=function()
	{

		plated_files.empty_folder(opts.output);

		plated.dirs={};

		plated_files.find_dirs(opts.source,"",function(s){
			console.log(timestr()+" DIR  "+"/"+s)

			var chunks=plated_files.base_files_to_chunks(s+"/name.txt");

			plated_files.set_source(chunks,s+"/.")

			plated.chunks.format_chunks( chunks );

			// run chunks through plugins, eg special blog handling
			for(var idx in plated.process_file) { var f=plated.process_file[idx];
				chunks = f( chunks ); // adjust and or output special chunks or files
			}

			plated.dirs[s]=chunks;
		});

		// run chunks through plugins, eg special blog handling
		for(var idx in plated.process_dirs) { var f=plated.process_dirs[idx];
			plated.dirs = f( plated.dirs ); // adjust and or output special chunks or files
		}

		for(var d in plated.dirs){ var chunks=plated.dirs[d];

			plated_files.prepare_namespace( path.join(d,".json") ); // prepare merged namespace
			var merged_chunks=plated.chunks.merge_namespace({});

			merged_chunks._output_filename=d+"/"
			merged_chunks._output_chunkname=undefined
			plated.output.remember_and_write( merged_chunks )

//			if(opts.dumpjson){
//				plated_files.write( path.join(opts.output,d,".json") , JSON_stringify( plated.chunks.merge_namespace({}) ,{space:1}) );
//			}
		}

		plated_files.find_files(opts.source,"",function(s){

				if(!plated_files.filename_is_basechunk(s))
				{
					console.log(timestr()+" FILE "+"/"+s)
					plated_files.build_file(s);
				}
		});

		plated.output.write_all()
	}

// build all files found in the source dir into the output dir
	plated_files.watch=function()
	{
		plated_files.build(); // build once

		var as=opts.source.split(path.sep);
		watch.watchTree(opts.source,{},function(f,curr,prev){
			if(typeof f == "object" && prev === null && curr === null)
			{
				// finished
			}
			else
			if(curr.nlink===0) // f was removed
			{
				plated_files.build(); // rebuild everything
			}
			else
			if(prev === null) // f is a new file
			{
				plated_files.build(); // rebuild everything
			}
			else
			{
				var af=f.split(path.sep);
				for(var i=0;i<as.length;i++)
				{
					if( as[i]==af[0] )
					{
						af.splice(0,1);
					}
				}
				var s=af.join(path.sep);

				plated_files.empty_cache();
				if(plated_files.filename_is_basechunk(s)) // full build
				{
					plated_files.build();
				}
				else
				{
					console.log(timestr()+" FILE "+"/"+s)
					plated_files.build_file(s);
				}

			}
		});
	}

	return plated_files;
};
<commit_msg>deal with files that blink into existence and are gone before we can open them<commit_after>
var fs = require('fs');
var util=require('util');
var path=require('path');
var watch=require('watch');
var JSON_stringify = require('json-stable-stringify');

var ls=function(a) { console.log(util.inspect(a,{depth:null})); }

// wrap so we can contain multiple environments without borking
exports.create=function(opts,plated){

	var timestr=function(){ return new Date().toISOString().replace(/^.+T/, "").replace(/\..+/, ""); }

	var plated_files={};

	plated_files.mkdir = function(dir){
		if (fs.existsSync(dir)){
			return
		}

		try{
			fs.mkdirSync(dir)
		}catch(err){
			if(err.code == 'ENOENT'){
				plated_files.mkdir(path.dirname(dir)) //create parent dir
				plated_files.mkdir(dir) //create dir
			}
		}
	}

// fill in _source and related chunks
	plated_files.set_source=function(chunks,source)
	{
		chunks._sourcename=plated_files.filename_fixup(source);

		chunks._filename=plated_files.filename_to_output(chunks._sourcename);

		chunks._dirname=plated_files.filename_to_dirname(chunks._sourcename);

		chunks._root=opts.root; // probably just "/"
		chunks._filename=opts.root+chunks._filename;
		chunks._dirname=opts.root+chunks._dirname;

		return chunks;
	}

// create parent dir if necessary and write data into this file
	plated_files.write = function(filename,data) {
		plated_files.mkdir( path.dirname(filename) );
		fs.writeFileSync( filename , data );
	};

// get the dirname of this filename
	plated_files.filename_fixup = function(filename) {
		if( filename =="." ) { filename =""; }
		if( filename =="/." ) { filename =""; }
		if( filename =="/" ) { filename =""; }
		return filename;
	}

// get the dirname of this filename
	plated_files.filename_to_dirname = function(filename) {
		return plated_files.filename_fixup(path.dirname(filename));
	}

// convert a source path into an output path
	plated_files.source_to_output = function(path) {
		var ps=path.replace(opts.source,opts.output);
		if( ps.startsWith(opts.output) ) { return ps; }
		return null;
	};

// is this filename part of the basechunks for a dir
	plated_files.filename_is_basechunk=function(fname)
	{
		var vv=path.basename(fname).split(".");
		if( vv[0]==opts.hashfile )
		{
			return true
		}
		return false;
	}

// is this filename something we need to run through plated
	plated_files.filename_is_plated=function(fname)
	{
		var vv=path.basename(fname).split(".");
		if( vv.length>2 && vv[ vv.length-2 ]==opts.hashfile )
		{
			return true
		}
		return false;
	}

// output filename
	plated_files.filename_to_output=function(fname)
	{
		var d=path.dirname(fname);
		var vv=path.basename(fname).split(".");
		for(var i=vv.length-1;i>0;i--)
		{
			if( vv[i] == opts.hashfile )
			{
				vv.splice(i,1);
			}
		}
		return plated_files.filename_fixup( path.join(d,vv.join(".")) );
	}

// empty the (output) folder or make it if it does not exist
	plated_files.empty_folder = function(path) {
		var files = [];
		if( fs.existsSync(path) ) {
			files = fs.readdirSync(path);
			files.forEach(function(file,index){
				var curPath = path + "/" + file;
				if(fs.lstatSync(curPath).isDirectory()) { // recurse
					plated_files.empty_folder(curPath);
				} else { // delete file
					if(file!=".git") // dont delete .git files // TODO:make generic rule? We need t keep .git for submodules
					{
						fs.unlinkSync(curPath);
					}
				}
			});
		}
		else
		{
			try { fs.mkdirSync(path); } catch(e){} // create it
		}
	};

// call f with every file we find
	plated_files.find_files = function(root,name,f) {
		var files=fs.readdirSync( path.join(root,name) );
		for(var i in files){ var v=files[i];
			var st=fs.lstatSync( path.join(root,name,v) );
			if( st.isDirectory() || st.isSymbolicLink() )
			{
				plated_files.find_files(root,path.join(name,v),f);
			}
			else
			{
				f( path.join(name,v) );
			}
		}
	};

// call f with every dir we find
	plated_files.find_dirs = function(root,name,f) {
		f(name);
		var files=fs.readdirSync( path.join(root,name) );
		for(var i in files){ var v=files[i];
			var st=fs.lstatSync( path.join(root,name,v) );
			if( st.isDirectory() || st.isSymbolicLink() )
			{
				plated_files.find_dirs(root,path.join(name,v),f);
			}
		}
	};

	var cache={}

	plated_files.empty_cache=function()
	{
		cache={};
	}

	plated_files.file_to_chunks=function(root,fname,chunks)
	{
		if(!cache[fname])
		{
			var s;
			try { s=fs.readFileSync(path.join(root,fname),'utf8'); } catch(e){}
			if(s)
			{
				cache[fname]=s;
			}
		}
		return plated.chunks.fill_chunks( cache[fname] , chunks);
	}

// check this directory and all directories above for generic chunks
// build all of these into the current chunk namespace for this file
	plated_files.prepare_namespace=function(fname)
	{
		var ns=[];

		var list=[];
		var rf=function(fn){
			var d=path.dirname(fn);
			if(d==".") { d=""; }

			var chunks=plated.dirs[d];
			if( chunks ) { ns.push(chunks); }

			if((d!="")&&(d!=".")&&(d!="/")) { rf(d); } // next dir
		};
		rf(fname)

		ns.reverse();

		plated.chunks.set_namespace(ns);

	}

// check this directory and all directories above for generic chunks
// build all of these into the current chunk namespace for this file
	plated_files.base_files_to_chunks=function(fname)
	{
		var list=[];
		var rf=function(fn){
			var d=path.dirname(fn);
			var p=path.join(opts.source,d);
			var files=fs.readdirSync(p);
			files.sort();
			files.reverse();
			for(var i in files){ var v=files[i];
				if( plated_files.filename_is_basechunk(v) )
				{
					var p2=path.join(d,v);
					list.push(p2);
				}
			}
		};
		rf(fname)

		var chunks={};
		for(var i=list.length-1 ; i>=0 ; i--) { var v=list[i];
			plated_files.file_to_chunks(opts.source,v,chunks);
		}
		return chunks;
	}

// build the given source filename, using chunks or maybe just a raw copy
	plated_files.build_file=function(fname)
	{
		if(plated_files.filename_is_plated(fname))
		{
			var output_filename = path.join( opts.output , plated.files.filename_to_output(fname) );

			plated_files.prepare_namespace(fname); // prepare merged namespace

			var chunks={};

			plated_files.file_to_chunks(opts.source, fname , chunks); // read chunks from this file

			plated_files.set_source(chunks,fname)

			plated.chunks.format_chunks( chunks);

			// run chunks through plugins, eg special blog handling
			for(var idx in plated.process_file) { var f=plated.process_file[idx];
				chunks = f( chunks ); // adjust and or output special chunks or files
			}

			var merged_chunks=plated.chunks.merge_namespace(chunks);

			merged_chunks._output_filename=plated.files.filename_to_output(fname)
			merged_chunks._output_chunkname=fname.split('.').pop()
			plated.output.remember_and_write( merged_chunks )

//			plated_files.write( output_filename , plated.chunks.replace( plated.chunks.delimiter_wrap_str(fname.split('.').pop()),merged_chunks) );
//			if(opts.dumpjson){
//				plated_files.write( output_filename+".json" , JSON_stringify(merged_chunks,{space:1}) );
//			}

		}
		else
		{
			var s=null; // ignore bad files
			try { s=fs.readFileSync( path.join(opts.source,fname) ); } catch(e){}
			if(s!==null)
			{
				plated_files.write( path.join(opts.output,fname), s );
			}
		}
	}

// build all files found in the source dir into the output dir
	plated_files.build=function()
	{

		plated_files.empty_folder(opts.output);

		plated.dirs={};

		plated_files.find_dirs(opts.source,"",function(s){
			console.log(timestr()+" DIR  "+"/"+s)

			var chunks=plated_files.base_files_to_chunks(s+"/name.txt");

			plated_files.set_source(chunks,s+"/.")

			plated.chunks.format_chunks( chunks );

			// run chunks through plugins, eg special blog handling
			for(var idx in plated.process_file) { var f=plated.process_file[idx];
				chunks = f( chunks ); // adjust and or output special chunks or files
			}

			plated.dirs[s]=chunks;
		});

		// run chunks through plugins, eg special blog handling
		for(var idx in plated.process_dirs) { var f=plated.process_dirs[idx];
			plated.dirs = f( plated.dirs ); // adjust and or output special chunks or files
		}

		for(var d in plated.dirs){ var chunks=plated.dirs[d];

			plated_files.prepare_namespace( path.join(d,".json") ); // prepare merged namespace
			var merged_chunks=plated.chunks.merge_namespace({});

			merged_chunks._output_filename=d+"/"
			merged_chunks._output_chunkname=undefined
			plated.output.remember_and_write( merged_chunks )

//			if(opts.dumpjson){
//				plated_files.write( path.join(opts.output,d,".json") , JSON_stringify( plated.chunks.merge_namespace({}) ,{space:1}) );
//			}
		}

		plated_files.find_files(opts.source,"",function(s){

				if(!plated_files.filename_is_basechunk(s))
				{
					console.log(timestr()+" FILE "+"/"+s)
					plated_files.build_file(s);
				}
		});

		plated.output.write_all()
	}

// build all files found in the source dir into the output dir
	plated_files.watch=function()
	{
		plated_files.build(); // build once

		var as=opts.source.split(path.sep);
		watch.watchTree(opts.source,{},function(f,curr,prev){
			if(typeof f == "object" && prev === null && curr === null)
			{
				// finished
			}
			else
			if(curr.nlink===0) // f was removed
			{
				plated_files.build(); // rebuild everything
			}
			else
			if(prev === null) // f is a new file
			{
				plated_files.build(); // rebuild everything
			}
			else
			{
				var af=f.split(path.sep);
				for(var i=0;i<as.length;i++)
				{
					if( as[i]==af[0] )
					{
						af.splice(0,1);
					}
				}
				var s=af.join(path.sep);

				plated_files.empty_cache();
				if(plated_files.filename_is_basechunk(s)) // full build
				{
					plated_files.build();
				}
				else
				{
					console.log(timestr()+" FILE "+"/"+s)
					plated_files.build_file(s);
				}

			}
		});
	}

	return plated_files;
};
<|endoftext|>


<commit_before>'use strict';

/**
 * Address
 *
 **/

var Helpers = require('./helpers');
var Charlatan = require('./charlatan');

/** alias of zip, postcode
 * Address#zipCode(format = null) -> String
 * - format (string): input format for example '#####-####'
 *
 * Generate zip code by from format. Each sharp symbol will be replaced by number.
 * If format is null, then random choise "#####" or '#####-####'
 *
 **/
exports.postcode = exports.zip = exports.zipCode = function (format) {
  return Charlatan.letterify(Charlatan.numerify(Charlatan.fetch('address.postcode')));
};

/**
 * Address#city() -> String
 *
 * Generate city name. For example 'Port Marianashire'
 **/
exports.city = function() {
  return Charlatan.parse('address.city');
};

/**
 * Address#streetName() -> String
 *
 * Generate street name. For example 'Schuster borough'
 **/
exports.streetName = function() {
  return Charlatan.parse('address.street_name');
};

/**
 * Address#secondaryAddress() -> String
 *
 * Generate secodary address part Apt/Suite.
 **/
var secondaryAddress = exports.secondaryAddress = function() {
  return Charlatan.numerify(Charlatan.fetch('address.secondary_address'));
};

/**
 * Address#streetAddress(include_secondary = false) -> String
 * - include_secondary (boolean) : is need add apartment/suite part
 *
 * Generate street address. For example 'Schuster borough'
 **/
exports.streetAddress = function(include_secondary) {
  return Charlatan.numerify(Charlatan.parse('address.street_address') +
                (include_secondary ? ' ' + secondaryAddress() : ''));
};

/**
 * Address#state(abbr = false) -> String
 * - abbr (boolean): flag abbr or full name
 *
 * Return random state(or state abbr).
 **/
var state = exports.state = function( abbr ) {
  if (!!abbr) {
    return Charlatan.fetch('address.state_abbr');
  }
  else {
    return Charlatan.fetch('address.state');
  }
};

/**
 * Address#stateAbbr() -> String
 *
 * Return random state abbr.
 **/
exports.stateAbbr = function() {
  return state(true);
};

/**
 * Address#county() -> String
 *
 * Return random county.
 * Note: if county dosen't set in current locale, then return empy string
 **/
exports.county = function(){
  try {
    return Charlatan.fetch('address.county');
  }
  catch (e) {
    return '';
  }
};

/**
 * Address#country() -> String
 *
 * Return random country
 **/
exports.country = function(){
  return Charlatan.fetch('address.country');
};
<commit_msg>Add latitude and longitude<commit_after>'use strict';

/**
 * Address
 *
 **/

var Helpers = require('./helpers');
var Charlatan = require('./charlatan');

/** alias of zip, postcode
 * Address#zipCode(format = null) -> String
 * - format (string): input format for example '#####-####'
 *
 * Generate zip code by from format. Each sharp symbol will be replaced by number.
 * If format is null, then random choise "#####" or '#####-####'
 *
 **/
exports.postcode = exports.zip = exports.zipCode = function (format) {
  return Charlatan.letterify(Charlatan.numerify(Charlatan.fetch('address.postcode')));
};

/**
 * Address#city() -> String
 *
 * Generate city name. For example 'Port Marianashire'
 **/
exports.city = function() {
  return Charlatan.parse('address.city');
};

/**
 * Address#streetName() -> String
 *
 * Generate street name. For example 'Schuster borough'
 **/
exports.streetName = function() {
  return Charlatan.parse('address.street_name');
};

/**
 * Address#secondaryAddress() -> String
 *
 * Generate secodary address part Apt/Suite.
 **/
var secondaryAddress = exports.secondaryAddress = function() {
  return Charlatan.numerify(Charlatan.fetch('address.secondary_address'));
};

/**
 * Address#streetAddress(include_secondary = false) -> String
 * - include_secondary (boolean) : is need add apartment/suite part
 *
 * Generate street address. For example 'Schuster borough'
 **/
exports.streetAddress = function(include_secondary) {
  return Charlatan.numerify(Charlatan.parse('address.street_address') +
                (include_secondary ? ' ' + secondaryAddress() : ''));
};

/**
 * Address#state(abbr = false) -> String
 * - abbr (boolean): flag abbr or full name
 *
 * Return random state(or state abbr).
 **/
var state = exports.state = function( abbr ) {
  if (!!abbr) {
    return Charlatan.fetch('address.state_abbr');
  }
  else {
    return Charlatan.fetch('address.state');
  }
};

/**
 * Address#stateAbbr() -> String
 *
 * Return random state abbr.
 **/
exports.stateAbbr = function() {
  return state(true);
};

/**
 * Address#county() -> String
 *
 * Return random county.
 * Note: if county dosen't set in current locale, then return empy string
 **/
exports.county = function(){
  try {
    return Charlatan.fetch('address.county');
  }
  catch (e) {
    return '';
  }
};

/**
 * Address#country() -> String
 *
 * Return random country
 **/
exports.country = function(){
  return Charlatan.fetch('address.country');
};

/**
 * Address#latitude() -> string
 *
 * Generate latitude
 **/
exports.latitude = function() {
  return ((Math.random() * 180) - 90).toString();
};

/**
 * Address#longitude() ->string
 *
 * Generate longitude
 **/
exports.longitude = function() {
  return ((Math.random() * 360) - 180).toString();
};
<|endoftext|>


<commit_before>var _CALLBACK_ = function() {
	$(document).ready(
		function() {
			function parse(v) {
				var t = v.replace(/(“|”)/ig, '"').replace(/(”|”)/ig, '"');
				return JSON.parse(t);
			}
			var v = $('.qaletplugin'), r={}, f=[];
			for (var i = 0; i < v.length; i++) {
				var data = $(v[i]).html();
				if (!data) data = $(v[i]).attr('data');
				console.log(data);

				var o = parse(data);
				if (o.module) {
					r[o.module] = true;
					o.id = o.module + '_plugin_' + i;
					f[f.length] = o;
					 $(v[i]).html('

').fadeIn( "slow");
				}
			}
			console.log(f);
			for (var i=0; i<f.length; i++) {
				if (typeof _QALET_[f[i].module] == 'function') {
					_QALET_[f[i].module](f[i]);
					//$(v[i]).fadeIn( "slow");
				} else {
					console.log('=='+f[i].module+'==');
				}
			}

			$('<link>').appendTo('head').attr({ type: 'text/css', rel: 'stylesheet', href: '//qalet.com/css/bootstrap.min.css' });
			$('<link>').appendTo('head').attr({ type: 'text/css', rel: 'stylesheet', href: '//docviewer.qalet.com/package/docviewer_wp.min.css' });
		//	$.getScript('http://docviewer.qalet.com/package/qalet_plugin_plus.jsx?plus='+Object.keys(r).join(',') + '&callback=_QACALLBACK_');
		}
	);
};
<commit_msg>Update qalet_plugin.js<commit_after>var _CALLBACK_ = function() {
	$(document).ready(
		function() {
			function parse(v) {
				var t = v.replace(/(“|”)/ig, '"').replace(/(”|”)/ig, '--');
				return JSON.parse(t);
			}
			var v = $('.qaletplugin'), r={}, f=[];
			for (var i = 0; i < v.length; i++) {
				var data = $(v[i]).html();
				if (!data) data = $(v[i]).attr('data');
				console.log(data);

				var o = parse(data);
				if (o.module) {
					r[o.module] = true;
					o.id = o.module + '_plugin_' + i;
					f[f.length] = o;
					 $(v[i]).html('

').fadeIn( "slow");
				}
			}
			console.log(f);
			for (var i=0; i<f.length; i++) {
				if (typeof _QALET_[f[i].module] == 'function') {
					_QALET_[f[i].module](f[i]);
					//$(v[i]).fadeIn( "slow");
				} else {
					console.log('=='+f[i].module+'==');
				}
			}

			$('<link>').appendTo('head').attr({ type: 'text/css', rel: 'stylesheet', href: '//qalet.com/css/bootstrap.min.css' });
			$('<link>').appendTo('head').attr({ type: 'text/css', rel: 'stylesheet', href: '//docviewer.qalet.com/package/docviewer_wp.min.css' });
		//	$.getScript('http://docviewer.qalet.com/package/qalet_plugin_plus.jsx?plus='+Object.keys(r).join(',') + '&callback=_QACALLBACK_');
		}
	);
};
<|endoftext|>


<commit_before>RAMBLE.Login = (function ($) {
    "use strict";
    var module = {},
    // default dialog options
        dialog_opts = {
            autoOpen: false,
            modal: true,
            draggable: false,
            width: 400,
            close: function () {
                $(this).dialog("destroy");
            }
        },
        login,
        register,
        logout;

    function log_success(data) {
        // successful login
        if (data === true) {
            $('#dialog').dialog("close");
        } else {
            console.log(data);
        }
    }

    login = {
        dialog: function () {
            var d = $('

'),
                f = $('<form id="login_form"></form>'),
                login_form = "",
                login_buttons = {
                    "Login": login.process
                },
                opts = $.extend({
                    buttons: login_buttons,
                    title: 'Login'
                }, dialog_opts);
            login_form += '
';
            login_form += 'Username:';
            login_form += '<input type="text" name="username">';
            login_form += '

';
            login_form += 'Password:';
            login_form += '<input type="password" name="password">';
            login_form += '
';
            f.append(login_form);
            d.append(f);
            d.dialog(opts);
            d.dialog("open");
        },
        process: function () {
            var form = $(this).children('form');
            form.ajaxSubmit({
                dataType: "json",
                type: "POST",
                url: "login.php?mode=login",
                success: log_success
            });
        }
    };

    logout = {
        process: function () {
            $.ajax({
                type: "POST",
                url: "login.php?mode=logout",
                dataType: "json",
                success: function (data) {
                    if (data === true) {
                        location.reload();
                    }
                }
            });
        }
    };

    register = {
        dialog: function () {
            var d = $('

'),
                f = $('<form id="login_form"></form>'),
                register_form = "",
                reg_buttons = {
                    "Create Account": register.process
                },
                opts = $.extend({
                    buttons: reg_buttons,
                    title: 'Register'
                }, dialog_opts);
            register_form += '
';
            register_form += 'Username:';
            register_form += '<input type="text" name="username">';
            register_form += '

';
            register_form += 'Password:';
            register_form += '<input type="password" name="password">';
            register_form += '
';
            f.append(register_form);
            d.append(f);
            d.dialog(opts);
            d.dialog("open");
        },
        process: function () {
            var form = $(this).children('form');
            form.ajaxSubmit({
                dataType: "json",
                type: "POST",
                url: "login.php?mode=register",
                success: log_success
            });
        }
    };

    module.init = function () {
        // Allow enter to submit form in jQuery UI Dialog
        // From http://stackoverflow.com/a/13522434/28429
        $(document).delegate('.ui-dialog', 'keyup', function (e) {
            var tagName = e.target.tagName.toLowerCase();

            tagName = (tagName === 'input' && e.target.type === 'button') ? 'button' : tagName;

            if (e.which === $.ui.keyCode.ENTER && tagName !== 'textarea' && tagName !== 'select' && tagName !== 'button') {
                $(this).find('.ui-dialog-buttonset button').eq(0).trigger('click');

                return false;
            }
        });

        $("#registerlink").on('click', register.dialog);
        $("#loginlink").on('click', login.dialog);
        $("#logoutlink").on('click', logout.process);
    };

    return module;
}(jQuery));<commit_msg>Reload on login<commit_after>RAMBLE.Login = (function ($) {
    "use strict";
    var module = {},
    // default dialog options
        dialog_opts = {
            autoOpen: false,
            modal: true,
            draggable: false,
            width: 400,
            close: function () {
                $(this).dialog("destroy");
            }
        },
        login,
        register,
        logout;

    function log_success(data) {
        // successful login
        if (data === true) {
            $('#dialog').dialog("close");
            location.reload();
        } else {
            console.log(data);
        }
    }

    login = {
        dialog: function () {
            var d = $('

'),
                f = $('<form id="login_form"></form>'),
                login_form = "",
                login_buttons = {
                    "Login": login.process
                },
                opts = $.extend({
                    buttons: login_buttons,
                    title: 'Login'
                }, dialog_opts);
            login_form += '
';
            login_form += 'Username:';
            login_form += '<input type="text" name="username">';
            login_form += '

';
            login_form += 'Password:';
            login_form += '<input type="password" name="password">';
            login_form += '
';
            f.append(login_form);
            d.append(f);
            d.dialog(opts);
            d.dialog("open");
        },
        process: function () {
            var form = $(this).children('form');
            form.ajaxSubmit({
                dataType: "json",
                type: "POST",
                url: "login.php?mode=login",
                success: log_success
            });
        }
    };

    logout = {
        process: function () {
            $.ajax({
                type: "POST",
                url: "login.php?mode=logout",
                dataType: "json",
                success: function (data) {
                    if (data === true) {
                        location.reload();
                    }
                }
            });
        }
    };

    register = {
        dialog: function () {
            var d = $('

'),
                f = $('<form id="login_form"></form>'),
                register_form = "",
                reg_buttons = {
                    "Create Account": register.process
                },
                opts = $.extend({
                    buttons: reg_buttons,
                    title: 'Register'
                }, dialog_opts);
            register_form += '
';
            register_form += 'Username:';
            register_form += '<input type="text" name="username">';
            register_form += '

';
            register_form += 'Password:';
            register_form += '<input type="password" name="password">';
            register_form += '
';
            f.append(register_form);
            d.append(f);
            d.dialog(opts);
            d.dialog("open");
        },
        process: function () {
            var form = $(this).children('form');
            form.ajaxSubmit({
                dataType: "json",
                type: "POST",
                url: "login.php?mode=register",
                success: log_success
            });
        }
    };

    module.init = function () {
        // Allow enter to submit form in jQuery UI Dialog
        // From http://stackoverflow.com/a/13522434/28429
        $(document).delegate('.ui-dialog', 'keyup', function (e) {
            var tagName = e.target.tagName.toLowerCase();

            tagName = (tagName === 'input' && e.target.type === 'button') ? 'button' : tagName;

            if (e.which === $.ui.keyCode.ENTER && tagName !== 'textarea' && tagName !== 'select' && tagName !== 'button') {
                $(this).find('.ui-dialog-buttonset button').eq(0).trigger('click');

                return false;
            }
        });

        $("#registerlink").on('click', register.dialog);
        $("#loginlink").on('click', login.dialog);
        $("#logoutlink").on('click', logout.process);
    };

    return module;
}(jQuery));<|endoftext|>


<commit_before>
/**
 * Set / Get css.
 *
 * @param {String|Object} prop
 * @param {String} val
 * @return {self}
 * @api public
 */

exports.css = function(prop, val){
  switch (arguments.length) {
    case 2: return set(this, prop, val);
    case 0: return get(this);
    case 1: return 'object' == typeof prop
      ? set(this, prop)
      : get(this, prop);
  }
};

/**
 * Set styles of all elements.
 *
 * @param {Cheerio} self
 * @param {String|Object} prop
 * @param {String} val
 * @return {self}
 * @api private
 */

function set(self, prop, val){
  if ('string' == typeof prop) {
    var styles = get(self);
    styles[prop] = val;
    return self.attr('style', stringify(styles));
  } else if ('object' == typeof prop) {
    Object.keys(prop).forEach(function(k){
      set(self, k, prop[k]);
    });
    return self;
  }
}

/**
 * Get parsed styles of the first element.
 *
 * @param {Cheerio} self
 * @param {String} prop
 * @return {Object}
 * @api private
 */

function get(self, prop){
  var styles = parse(self.attr('style'));
  if (undefined == styles) throw new Error('undefined');
  return 2 == arguments.length
    ? styles[prop]
    : styles;
}

/**
 * Stringify `obj` to styles.
 *
 * @param {Object} obj
 * @return {Object}
 * @api private
 */

function stringify(obj){
  return Object.keys(obj || {})
    .reduce(function(str, prop){
      return str += ''
        + (str ? ' ' : '')
        + prop
        + ': '
        + obj[prop]
        + ';';
    }, '');
}

/**
 * Parse `styles`.
 *
 * @param {String} styles
 * @return {Object}
 * @api private
 */

function parse(styles){
  styles = (styles || '').trim();

  if ('' == styles) return {};

  return styles.trim()
    .split(/\s*;\s*/)
    .reduce(function(obj, str){
      var parts = str.split(/\s*:\s*/);
      if ('' == parts[0]) return obj;
      obj[parts[0]] = parts[1];
      return obj;
    }, {});
}
<commit_msg>remove uneeded .trim()<commit_after>
/**
 * Set / Get css.
 *
 * @param {String|Object} prop
 * @param {String} val
 * @return {self}
 * @api public
 */

exports.css = function(prop, val){
  switch (arguments.length) {
    case 2: return set(this, prop, val);
    case 0: return get(this);
    case 1: return 'object' == typeof prop
      ? set(this, prop)
      : get(this, prop);
  }
};

/**
 * Set styles of all elements.
 *
 * @param {Cheerio} self
 * @param {String|Object} prop
 * @param {String} val
 * @return {self}
 * @api private
 */

function set(self, prop, val){
  if ('string' == typeof prop) {
    var styles = get(self);
    styles[prop] = val;
    return self.attr('style', stringify(styles));
  } else if ('object' == typeof prop) {
    Object.keys(prop).forEach(function(k){
      set(self, k, prop[k]);
    });
    return self;
  }
}

/**
 * Get parsed styles of the first element.
 *
 * @param {Cheerio} self
 * @param {String} prop
 * @return {Object}
 * @api private
 */

function get(self, prop){
  var styles = parse(self.attr('style'));
  if (undefined == styles) throw new Error('undefined');
  return 2 == arguments.length
    ? styles[prop]
    : styles;
}

/**
 * Stringify `obj` to styles.
 *
 * @param {Object} obj
 * @return {Object}
 * @api private
 */

function stringify(obj){
  return Object.keys(obj || {})
    .reduce(function(str, prop){
      return str += ''
        + (str ? ' ' : '')
        + prop
        + ': '
        + obj[prop]
        + ';';
    }, '');
}

/**
 * Parse `styles`.
 *
 * @param {String} styles
 * @return {Object}
 * @api private
 */

function parse(styles){
  styles = (styles || '').trim();

  if ('' == styles) return {};

  return styles
    .split(/\s*;\s*/)
    .reduce(function(obj, str){
      var parts = str.split(/\s*:\s*/);
      if ('' == parts[0]) return obj;
      obj[parts[0]] = parts[1];
      return obj;
    }, {});
}
<|endoftext|>


<commit_before>    setInterval(function(){
          if(!localStorage.name){
             return;
           }
        // if(localStorage.)

        alert("i will eat you");
        if(Math.random() < 1) {
            var monsterlist = JSON.parse(localStorage.monsters);
            var firstMonster = monsterlist[randomInt(monsterlist.length)].name;
            var secondMonster = monsterlist[randomInt(monsterlist.length)].name;
            while(secondMonster == firstMonster) {
                var secondMonster = monsterlist[randomInt(monsterlist.length)].name;
            }
            localStorage.firstMonster = firstMonster;
            localStorage.secondMonster = secondMonster;

            $('#alertBox').fadeIn('slow');

        }
    }, 5000); // 60000 = run every 10 minutes

function randomInt(max) {
    return Math.floor(Math.random() * max);
}<commit_msg>pop ups don't happen if user isn't signed in. 'Hack Alert'<commit_after>    setInterval(function(){
          if(!localStorage.name){
             return;
           }
        // if(localStorage.)

        // alert("i will eat you");
        if(Math.random() < 1) {
            var monsterlist = JSON.parse(localStorage.monsters);
            var firstMonster = monsterlist[randomInt(monsterlist.length)].name;
            var secondMonster = monsterlist[randomInt(monsterlist.length)].name;
            while(secondMonster == firstMonster) {
                var secondMonster = monsterlist[randomInt(monsterlist.length)].name;
            }
            localStorage.firstMonster = firstMonster;
            localStorage.secondMonster = secondMonster;

            $('#alertBox').fadeIn('slow');

        }
    }, 5000); // 60000 = run every 10 minutes

function randomInt(max) {
    return Math.floor(Math.random() * max);
}<|endoftext|>


<commit_before>// appinit.js
// Managing apis and handling errors
// © Harald Rudell 2012

var appshutdown = require('./appshutdown')
var apperror = require('./apperror')
var anomaly = require('./anomaly')
var apimanager = require('./apimanager')

exports.initApp = initApp

var slogan = 'App Runner'
var msPerDay = 24*60*60*1e3

/*
defaults: options, typically loaded by haraldops
.init.appFolder: string: the folder of initial script
.init.logger: optional function(string): logging, default console.log
.init.ops.sendMail: optional function(subject, body): Sends mail, default none
.api: optional, indicates that Api Manager should be used
.api.apiMap: api configurations
app: Web server, has .on and .get methods
*/
function initApp(defaults, app) {
	if (!defaults) defaults = {}

	// configure error handling
	Error.stackTraceLimit = Infinity
	appshutdown.init(defaults)
	apperror.addErrorListener(app)
	apperror.addErrorListener(require('./rqs').emitter)
	if (!defaults.noInfoLog) console.log(slogan + ' is listening for errors')

	// get email function
	var sendMail
	if (defaults.init && defaults.init.ops) sendMail = defaults.init.ops.sendMail
	if (sendMail) require('./emailer').setSendMail(sendMail)

	// add anomaly reporting
	if (!(defaults.anomaly === false)) {

		// ability to not have email
		var doMail = defaults.anomaly
		if (doMail && defaults.anomaly.noEmail != null) {
			if (typeof defaults.anomaly.noEmail == 'string') {
				var date = new Date(defaults.anomaly.noEmail).getTime()
				if (isNaN(date)) doMail = true
				else {
					var daySerial = Math.floor(date / msPerDay)
					var nowDaySerial = Math.floor(Date.now() / msPerDay)
					doMail = nowDaySerial > daySerial
				}
			} else doMail = !!defaults.anomaly.noEmail
		}
		if (doMail) anomaly.enableAnomalyMail(false)

		// ability to report errors
		var logger
		if (defaults.init) {
			logger = defaults.init.logger
			if (!defaults.anomaly) defaults.anomaly = {}
			if (!defaults.anomaly.app) defaults.anomaly.app = defaults.init.appName
		}
		if (!sendMail && !defaults.noInfoLog) console.log(slogan + ': Warning: sendmail not available')
		anomaly.initAnomaly(
			defaults.anomaly,
			sendMail,
			logger)
	}

	// add api loading capability
	if (!(defaults.api === false)) apimanager.initApi(defaults, app)
}<commit_msg>fix doMail flag<commit_after>// appinit.js
// Managing apis and handling errors
// © Harald Rudell 2012

var appshutdown = require('./appshutdown')
var apperror = require('./apperror')
var anomaly = require('./anomaly')
var apimanager = require('./apimanager')

exports.initApp = initApp

var slogan = 'App Runner'
var msPerDay = 24*60*60*1e3

/*
defaults: options, typically loaded by haraldops
.init.appFolder: string: the folder of initial script
.init.logger: optional function(string): logging, default console.log
.init.ops.sendMail: optional function(subject, body): Sends mail, default none
.api: optional, indicates that Api Manager should be used
.api.apiMap: api configurations
app: Web server, has .on and .get methods
*/
function initApp(defaults, app) {
	if (!defaults) defaults = {}

	// configure error handling
	Error.stackTraceLimit = Infinity
	appshutdown.init(defaults)
	apperror.addErrorListener(app)
	apperror.addErrorListener(require('./rqs').emitter)
	if (!defaults.noInfoLog) console.log(slogan + ' is listening for errors')

	// get email function
	var sendMail
	if (defaults.init && defaults.init.ops) sendMail = defaults.init.ops.sendMail
	if (sendMail) require('./emailer').setSendMail(sendMail)

	// add anomaly reporting
	if (!(defaults.anomaly === false)) {

		// ability to not have email
		var doMail = defaults.anomaly
		if (doMail && defaults.anomaly.noEmail != null) {
			if (typeof defaults.anomaly.noEmail == 'string') {
				var date = new Date(defaults.anomaly.noEmail).getTime()
				if (isNaN(date)) doMail = true
				else {
					var daySerial = Math.floor(date / msPerDay)
					var nowDaySerial = Math.floor(Date.now() / msPerDay)
					doMail = nowDaySerial > daySerial
				}
			} else doMail = !!defaults.anomaly.noEmail
		}
		if (!doMail) anomaly.enableAnomalyMail(false)

		// ability to report errors
		var logger
		if (defaults.init) {
			logger = defaults.init.logger
			if (!defaults.anomaly) defaults.anomaly = {}
			if (!defaults.anomaly.app) defaults.anomaly.app = defaults.init.appName
		}
		if (!sendMail && !defaults.noInfoLog) console.log(slogan + ': Warning: sendmail not available')
		anomaly.initAnomaly(
			defaults.anomaly,
			sendMail,
			logger)
	}

	// add api loading capability
	if (!(defaults.api === false)) apimanager.initApi(defaults, app)
}<|endoftext|>


<commit_before>var selected = [];

var formats = {dialogue: {
  title: 'Dialogue',
  inline: 'span',
  classes: 'dialogue'
}, pensee: {
  title: 'Pensée',
  inline: 'span',
  classes: 'pensee'
}, rp1: {
  title: 'RP1',
  inline: 'span',
  classes: 'rp1'
}, rp2: {
  title: 'RP2',
  inline: 'span',
  classes: 'rp2'
}, rp3: {
  title: 'Hrp',
  inline: 'span',
  classes: 'hrp'
}, t1: {
  title: 'Titre 1',
  block: 'h1'
}, t2: {
  title: 'Titre 2',
  block: 'h2'
}, t3: {
  title: 'Titre 3',
  block: 'h3'
}, blockquote: {
  title: 'Citation',
  block: 'blockquote'
}};

var style_formats = [
  formats.dialogue,
  formats.pensee,
  formats.rp1,
  formats.rp2,
  formats.rp3,
  formats.t1,
  formats.t2,
  formats.t3,
  formats.blockquote
];

var fontFormat = "Standard=Helvetica Neue, Helvetica, Arial, sans-serif;" +
    "Police Lcd=LiquidCrystal;"+
    "Police Runique=Runes;"+
    "Police Elfique=Tengwar";

var configBase = {
  plugins: [
    "link image lists hr",
    "table fullscreen",
    "emoticons code"
  ],
  toolbar_mode: "sliding",
  menubar: false,
  contextmenu: false,
  autoresize: true,
  mobile: {
    min_height: 300,
    toolbar_mode: "sliding",
    toolbar: "fullscreen | styleselect removeformat | bold italic | link image | hr | private hide popup perso perso2 carte"
  },
  content_css : BASE_PATH + "/css/main.css",
  browser_spellcheck: true,
  convert_urls: false,
  toolbar: "undo redo | styleselect fontselect removeformat | bold italic forecolor | link image | fullscreen | emoticons private hide popup perso perso2 carte | hr | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table code",
  formats: formats,
  style_formats: style_formats,
  autosave_ask_before_unload: false,
  font_formats: fontFormat,
  setup: setupCustomIco
};

var configPost = jQuery.extend(true, {}, configBase);
configPost.min_height = 400;
configPost.selector = ".wysiwyg";

tinymce.init(configPost);

function setupCustomIco(editor) {
    editor.ui.registry.addButton('private', {
      text: 'Prv',
      onAction: function() {
        editor.windowManager.openUrl({
          title: 'Message privé',
          url: BASE_PATH + '/editor/tagPrivate/' + CAMPAGNE_ID,
          height: 280,
          buttons: [{
            type: "custom",
            text: 'OK',
            classes: 'widget btn primary first abs-layout-item',
            disabled: false
          }, {
            type: "cancel",
            text: 'Cancel',
            onAction: 'close'
          }],
          onAction: function(e){

            var find_src = BASE_PATH + '/editor/tagPrivate/' + CAMPAGNE_ID;
            var items = [];
            var val = $("iframe[src='" + find_src + "']").contents().find("select option:selected").each(function() {
              items.push($(this).val());
            });
            editor.execCommand( 'mceInsertContent', 0, "[private=" + items.join(',') + "]" + editor.selection.getContent() + "[/private]" );
            editor.windowManager.close();
          }
        });
      }
    });
    editor.ui.registry.addButton('hide', {
      text: 'Hid',
      onAction: function() {
        var content = tinyMCE.activeEditor.selection.getContent();
        editor.insertContent('[hide]' + content + '[/hide]');
      }
    });
    editor.ui.registry.addButton('popup', {
      text: 'Pop',
      onAction: function() {
        editor.windowManager.open({
          title: 'Informations Popup',
          body: {
            type: 'panel',
            items: [{
              type: 'input',
              name: 'title',
              label: 'Titre :'
            },
            {
              type: 'input',
              name: 'link',
              label: 'Lien affiché :'
            }]
          },
          buttons: [{
            type: "submit",
            text: 'OK',
            classes: 'widget btn primary first abs-layout-item',
            disabled: false
          }, {
            type: "cancel",
            text: 'Cancel',
            onAction: 'close'
          }],
          onSubmit: function(e) {
            var data = e.getData();
            var content = tinyMCE.activeEditor.selection.getContent();
            editor.insertContent('[popup=' + data.title + ',' + data.link + ']' + content + '[/popup]');
            editor.windowManager.close();
          }
        });
      }
    });

    editor.ui.registry.addButton('perso', {
      text: 'PNJ',
      onAction: function() {
        editor.windowManager.openUrl({
          title: 'Lien vers fiche PNJ',
          url: BASE_PATH + '/editor/tagPerso/' + CAMPAGNE_ID,
          height: 280,
          buttons: [{
            type: "custom",
            text: 'OK',
            classes: 'widget btn primary first abs-layout-item',
            disabled: false,
          }, {
            type: "cancel",
            text: 'Cancel',
            onAction: 'close'
          }],
          onAction: function(e){

            var find_src = BASE_PATH + '/editor/tagPerso/' + CAMPAGNE_ID;
            var val = $("iframe[src='" + find_src + "']").contents().find("select option:selected").val();
            var content = editor.selection.getContent() ? editor.selection.getContent(): val;
            editor.execCommand( 'mceInsertContent', 0, "[pnj=" + val + "]" + content + "[/pnj]" );
            editor.windowManager.close();
          }
        });
      }
    });

    editor.ui.registry.addButton('carte', {
      text: 'CARTE',
      onAction: function() {
        editor.windowManager.openUrl({
          title: 'Lien vers une carte',
          url: BASE_PATH + '/editor/tagCarte/' + CAMPAGNE_ID,
          height: 280,
          buttons: [{
            type: "custom",
            text: 'OK',
            classes: 'widget btn primary first abs-layout-item',
            disabled: false
          }, {
            type: "cancel",
            text: 'Cancel',
            onAction: 'close'
          }],
          onAction: function(e){

            var find_src = BASE_PATH + '/editor/tagCarte/' + CAMPAGNE_ID;
            var selection = $("iframe[src='" + find_src + "']").contents().find("select option:selected");
            var val = selection.val();
            var content = editor.selection.getContent() ? editor.selection.getContent(): selection.text();
            editor.execCommand( 'mceInsertContent', 0, "[carte=" + val + "]" + content + "[/carte]" );
            editor.windowManager.close();
          }
        });
      }
    });

    editor.addShortcut('ctrl+1', 'Dialogue Format', function() {
     editor.formatter.toggle('dialogue');
    });
    editor.addShortcut('ctrl+2', 'Dialogue Format', function() {
     editor.formatter.toggle('pensee');
    });
    editor.addShortcut('ctrl+3', 'Dialogue Format', function() {
     editor.formatter.toggle('rp1');
    });
    editor.addShortcut('ctrl+4', 'Dialogue Format', function() {
     editor.formatter.toggle('rp2');
    });
  }
<commit_msg>FEAT(Editeur) - Rajout different formats<commit_after>var selected = [];

var formats = {dialogue: {
  title: 'Dialogue',
  inline: 'span',
  classes: 'dialogue'
}, pensee: {
  title: 'Pensée',
  inline: 'span',
  classes: 'pensee'
}, rp1: {
  title: 'RP1',
  inline: 'span',
  classes: 'rp1'
}, rp2: {
  title: 'RP2',
  inline: 'span',
  classes: 'rp2'
}, rp3: {
  title: 'Hrp',
  inline: 'span',
  classes: 'hrp'
}, t1: {
  title: 'Titre 1',
  block: 'h1'
}, t2: {
  title: 'Titre 2',
  block: 'h2'
}, t3: {
  title: 'Titre 3',
  block: 'h3'
}, blockquote: {
  title: 'Citation',
  block: 'blockquote'
}};

var style_formats = [
  formats.dialogue,
  formats.pensee,
  formats.rp1,
  formats.rp2,
  formats.rp3,
  formats.t1,
  formats.t2,
  formats.t3,
  formats.blockquote
];

var fontFormat = "Standard=Helvetica Neue, Helvetica, Arial, sans-serif;" +
    "Police Lcd=LiquidCrystal;"+
    "Police Runique=Runes;"+
    "Police Elfique=Tengwar";

var configBase = {
  plugins: [
    "link image lists hr",
    "table fullscreen",
    "emoticons code"
  ],
  toolbar_mode: "sliding",
  menubar: false,
  contextmenu: false,
  autoresize: true,
  mobile: {
    min_height: 300,
    toolbar_mode: "sliding",
    toolbar: "fullscreen | styleselect removeformat | bold italic | link image | hr | private hide popup perso perso2 carte"
  },
  content_css : BASE_PATH + "/css/main.css",
  browser_spellcheck: true,
  convert_urls: false,
  toolbar: "undo redo | styleselect fontselect removeformat | bold italic forecolor | link image | fullscreen | emoticons private hide popup perso perso2 carte | hr | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | underline strikethrough | superscript subscript | table code",
  formats: formats,
  style_formats: style_formats,
  autosave_ask_before_unload: false,
  font_formats: fontFormat,
  setup: setupCustomIco
};

var configPost = jQuery.extend(true, {}, configBase);
configPost.min_height = 240;
configPost.selector = ".wysiwyg";

tinymce.init(configPost);

function setupCustomIco(editor) {
    editor.ui.registry.addButton('private', {
      text: 'Prv',
      onAction: function() {
        editor.windowManager.openUrl({
          title: 'Message privé',
          url: BASE_PATH + '/editor/tagPrivate/' + CAMPAGNE_ID,
          height: 280,
          buttons: [{
            type: "custom",
            text: 'OK',
            classes: 'widget btn primary first abs-layout-item',
            disabled: false
          }, {
            type: "cancel",
            text: 'Cancel',
            onAction: 'close'
          }],
          onAction: function(e){

            var find_src = BASE_PATH + '/editor/tagPrivate/' + CAMPAGNE_ID;
            var items = [];
            var val = $("iframe[src='" + find_src + "']").contents().find("select option:selected").each(function() {
              items.push($(this).val());
            });
            editor.execCommand( 'mceInsertContent', 0, "[private=" + items.join(',') + "]" + editor.selection.getContent() + "[/private]" );
            editor.windowManager.close();
          }
        });
      }
    });
    editor.ui.registry.addButton('hide', {
      text: 'Hid',
      onAction: function() {
        var content = tinyMCE.activeEditor.selection.getContent();
        editor.insertContent('[hide]' + content + '[/hide]');
      }
    });
    editor.ui.registry.addButton('popup', {
      text: 'Pop',
      onAction: function() {
        editor.windowManager.open({
          title: 'Informations Popup',
          body: {
            type: 'panel',
            items: [{
              type: 'input',
              name: 'title',
              label: 'Titre :'
            },
            {
              type: 'input',
              name: 'link',
              label: 'Lien affiché :'
            }]
          },
          buttons: [{
            type: "submit",
            text: 'OK',
            classes: 'widget btn primary first abs-layout-item',
            disabled: false
          }, {
            type: "cancel",
            text: 'Cancel',
            onAction: 'close'
          }],
          onSubmit: function(e) {
            var data = e.getData();
            var content = tinyMCE.activeEditor.selection.getContent();
            editor.insertContent('[popup=' + data.title + ',' + data.link + ']' + content + '[/popup]');
            editor.windowManager.close();
          }
        });
      }
    });

    editor.ui.registry.addButton('perso', {
      text: 'PNJ',
      onAction: function() {
        editor.windowManager.openUrl({
          title: 'Lien vers fiche PNJ',
          url: BASE_PATH + '/editor/tagPerso/' + CAMPAGNE_ID,
          height: 280,
          buttons: [{
            type: "custom",
            text: 'OK',
            classes: 'widget btn primary first abs-layout-item',
            disabled: false,
          }, {
            type: "cancel",
            text: 'Cancel',
            onAction: 'close'
          }],
          onAction: function(e){

            var find_src = BASE_PATH + '/editor/tagPerso/' + CAMPAGNE_ID;
            var val = $("iframe[src='" + find_src + "']").contents().find("select option:selected").val();
            var content = editor.selection.getContent() ? editor.selection.getContent(): val;
            editor.execCommand( 'mceInsertContent', 0, "[pnj=" + val + "]" + content + "[/pnj]" );
            editor.windowManager.close();
          }
        });
      }
    });

    editor.ui.registry.addButton('carte', {
      text: 'CARTE',
      onAction: function() {
        editor.windowManager.openUrl({
          title: 'Lien vers une carte',
          url: BASE_PATH + '/editor/tagCarte/' + CAMPAGNE_ID,
          height: 280,
          buttons: [{
            type: "custom",
            text: 'OK',
            classes: 'widget btn primary first abs-layout-item',
            disabled: false
          }, {
            type: "cancel",
            text: 'Cancel',
            onAction: 'close'
          }],
          onAction: function(e){

            var find_src = BASE_PATH + '/editor/tagCarte/' + CAMPAGNE_ID;
            var selection = $("iframe[src='" + find_src + "']").contents().find("select option:selected");
            var val = selection.val();
            var content = editor.selection.getContent() ? editor.selection.getContent(): selection.text();
            editor.execCommand( 'mceInsertContent', 0, "[carte=" + val + "]" + content + "[/carte]" );
            editor.windowManager.close();
          }
        });
      }
    });

    editor.addShortcut('ctrl+1', 'Dialogue Format', function() {
     editor.formatter.toggle('dialogue');
    });
    editor.addShortcut('ctrl+2', 'Dialogue Format', function() {
     editor.formatter.toggle('pensee');
    });
    editor.addShortcut('ctrl+3', 'Dialogue Format', function() {
     editor.formatter.toggle('rp1');
    });
    editor.addShortcut('ctrl+4', 'Dialogue Format', function() {
     editor.formatter.toggle('rp2');
    });
  }
<|endoftext|>


<commit_before>// ---- Constants ----
// buffer time between map change and reload
var LOAD_DELAY=500;   // in milliseconds
// margin around viewport where zones are loaded and calculated
var LOAD_MARGIN=0.5;   // in kilometers

// ---- Variables ----
var map;
var zones = {};
var markersArray = [];
var loadTimer = null;
var selectedUser;

// ---- Prototypes ----
if (typeof(Number.prototype.toRad) === "undefined") {
  Number.prototype.toRad = function() {
    return this * Math.PI / 180;
  }
}

if (typeof(String.prototype.hashCode) === "undefined") {
  // from http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery
  String.prototype.hashCode = function(){
      var hash = 0x55555555, i, char;
      if (this.length == 0) return hash;
      for (i = 0, l = this.length; i < l; i++) {
          char  = this.charCodeAt(i);
          hash  = ((hash<<5)-hash)+char;
          hash |= 0; // Convert to 32bit integer
      }
      return hash;
  }
}

// ---- Code ----
function initialize() {
  // Reduce saturation of the map
  var styles = [
  {
    stylers: [
      { saturation: -80 }
    ]
  }];

  var lat = 59.32893;
  var lng = 18.06491;
  var location = $.url().param('location');
  selectedUser = $.url().param('user');

  var mapOptions = {
    center: new google.maps.LatLng(lat, lng),
    zoom: 14,
    styles: styles
  };
  map = new google.maps.Map(document.getElementById("map-canvas"),
    mapOptions);

  google.maps.event.addListener(map, "bounds_changed", function() {
    if (loadTimer != null) {
      clearTimeout(loadTimer);
    }
    loadTimer = setTimeout(loadZones, LOAD_DELAY);
  });

  if (location != null) {
    gotoLocation(location);
  }
}

function calculateMargins(bbox) {
  var horizontalDistance = calculateDistance(
    bbox.getNorthEast().lat(),
    bbox.getNorthEast().lng(),
    bbox.getNorthEast().lat(),
    bbox.getSouthWest().lng()
    );
  var verticalDistance = calculateDistance(
    bbox.getNorthEast().lat(),
    bbox.getNorthEast().lng(),
    bbox.getSouthWest().lat(),
    bbox.getNorthEast().lng()
    );

  console.log("hDist: " + horizontalDistance);
  console.log("vDist: " + verticalDistance);

  // Doesn't handle cross datezone
  kilometerDLat = (bbox.getNorthEast().lng() - bbox.getSouthWest().lng()) / horizontalDistance;
  loadMarginLat = kilometerDLat * LOAD_MARGIN;
  kilometerDLng = (bbox.getNorthEast().lng() - bbox.getSouthWest().lng()) / verticalDistance;
  loadMarginLng = kilometerDLng * LOAD_MARGIN;

  var m = {loadMarginLat: loadMarginLat, loadMarginLng: loadMarginLng};
  return m;
}

function loadZones() {
  initTime();
  var bbox = map.getBounds();

  var m = calculateMargins(bbox);

  var data = [{
    "northEast" : {"latitude":bbox.getNorthEast().lat() + m.loadMarginLat, "longitude":bbox.getNorthEast().lng() + m.loadMarginLng},
    "southWest" : {"latitude":bbox.getSouthWest().lat() - m.loadMarginLat, "longitude":bbox.getSouthWest().lng() - m.loadMarginLng}
  }];

  $.ajax({
    type: "POST",
    crossDomain: true,
    url: "http://api.turfgame.com/v4/zones",
    contentType: "application/json",
    data: JSON.stringify(data)
  })
  .done(function(res) {
    handleZoneResult(res);
  })
  .fail(function(res) {
    alert("failed: " + JSON.stringify(res));
  });

  measureTime("load initiated");
}

// [{"region":{"id":141,"name":"Stockholm","country":"se"},
//   "id":139,
//   "currentOwner":{"id":9241,"name":"speedmaster100"},
//   "dateLastTaken":"2014-03-15T21:07:12+0000",
//   "totalTakeovers":6590,
//   "takeoverPoints":65,
//   "name":"BearZone",
//   "pointsPerHour":9,
//   "dateCreated":"2010-09-04T16:41:37+0000",
//   "longitude":18.073934,
//   "latitude":59.31514
// }]
function handleZoneResult(res) {
  console.log("Loaded " + res.length + " zones");
  measureTime("Zones loaded");
  var sites = [];
  zones = {};
  for (var i = 0; i < res.length; i++) {
    //Store zone for later lookup
    storeZone(res[i]);

    // Build sites array
    var site = {x: res[i].longitude, y: res[i].latitude};
    sites.push(site);
  }

  var diagram = calculateVoronoi(sites);
  measureTime("voronoi calculated");
  clearOverlays();
  drawVoronoi(diagram);
}

function makeHString(lat, lng)
{
  return "[" + lat + "," + lng + "]";
}

function storeZone(zone)
{
  var hstring = makeHString(zone.latitude, zone.longitude);
  zones[hstring] = zone;
}

function lookupZone(site)
{
  var hstring = makeHString(site.y, site.x);
  return zones[hstring];
}

function placeMarker(zone)
{
  var pos = new google.maps.LatLng(zone.latitude, zone.longitude);
  var owner = "-";
  if (zone.currentOwner != null) {
    owner = zone.currentOwner.name;
  }
  var marker = new google.maps.Marker({
    position: pos,
    map: map,
    icon: "img/red_dot.png",
    title: "Name: " + zone.name + "\n Owner: " + owner
  });
  markersArray.push(marker);
}

function calculateVoronoi(sites)
{
  var mb = map.getBounds();
  var m = calculateMargins(mb);
  var bbox = {
    xl: mb.getSouthWest().lng() - m.loadMarginLng,
    xr: mb.getNorthEast().lng() + m.loadMarginLng,
    yt: mb.getSouthWest().lat() - m.loadMarginLat,
    yb: mb.getNorthEast().lat() + m.loadMarginLat
  };

  var voronoi = new Voronoi();
  return voronoi.compute(sites, bbox);
}

function drawVoronoi(diagram)
{
  for(var i = 0; i < diagram.cells.length; i++) {
    var polyCoords = [];
    var cell = diagram.cells[i];

    if (cell.halfedges.length > 0) {
      for (var c = 0; c < cell.halfedges.length; c++) {
        var edge = cell.halfedges[c];
        var coord = new google.maps.LatLng(edge.getStartpoint().y, edge.getStartpoint().x);
        polyCoords.push(coord);
      }
      // Close the loop
      var edge = cell.halfedges[0];
      var coord = new google.maps.LatLng(edge.getStartpoint().y, edge.getStartpoint().x);
      polyCoords.push(coord);

      var zone = lookupZone(cell.site);
      var col = colorFromZone(zone);
      var opacity = 0.1;
      if (col == "-") {  // hack!
        col = "#FFFFFF";
        opacity = 0;
      }

      placeMarker(zone);
      var polygon = new google.maps.Polygon({
        paths: polyCoords,
        strokeColor: "#000000",
        strokeOpacity: 0.1,
        strokeWeight: 1,
        fillColor: col,
        fillOpacity: opacity,
        title: zone.name
      });

      polygon.setMap(map);
      markersArray.push(polygon);
    }
  }
  measureTime("cells drawn");

  drawBoundaries(diagram);
}

function drawBoundaries(diagram)
{
  for (var i = 0; i < diagram.edges.length; i++)
  {
    var edge = diagram.edges[i];

    // Skip if this is an edge zone
    if (edge.lSite == null || edge.rSite == null) {
      continue;
    }

    lzone = lookupZone(edge.lSite);
    lname = lzone.currentOwner == null ? null : lzone.currentOwner.name;
    rzone = lookupZone(edge.rSite);
    rname = rzone.currentOwner == null ? null : rzone.currentOwner.name;

    // Skip if owner is the same
    if (lname == rname) {
      continue;
    }

    var col = "#000000";
    var opacity = 0.5;
    var weight = 1;
    if (selectedUser != null && (lname == selectedUser || rname == selectedUser))
    {
      col = "#FFFFFF";
      opacity = 1;
      weight = 4;
    }

    // Draw a line
    var start = new google.maps.LatLng(edge.va.y, edge.va.x);
    var stop = new google.maps.LatLng(edge.vb.y, edge.vb.x);
    coordinates = [start, stop];
    var line = new google.maps.Polyline({
      path: coordinates,
      strokeColor: col,
      strokeOpacity: opacity,
      strokeWeight: weight,
      zIndex: 2
    });
    line.setMap(map);
    markersArray.push(line);
  }
}

function clearOverlays() {
  for (var i = 0; i < markersArray.length; i++ ) {
    markersArray[i].setMap(null);
  }
  markersArray = [];
}

function calculateDistance(lat1, lng1, lat2, lng2)
{
  // formula from http://www.movable-type.co.uk/scripts/latlong.html
  // var R = 6371; // km
  // var d = Math.acos(Math.sin(lat1.toRad())*Math.sin(lat2.toRad()) +
  //   Math.cos(lat1.toRad())*Math.cos(lat2.toRad()) *
  //   Math.cos(lng2-lng1).toRad()) * R;
  var R = 111.111;
  var x = (lng2-lng1) * Math.cos((lat1+lat2).toRad()/2);
  var y = (lat2-lat1);
  var d = Math.sqrt(x*x + y*y) * R;

  return d;
}

var geocoder = new google.maps.Geocoder();
function gotoLocation(location) {
  geocoder.geocode(
        {'address': location},
        function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                var loc = results[0].geometry.location;
                console.log("moving to " + location + " @" + loc.lat() + ", " + loc.lng());
                map.panTo(loc);
            }
            else {
                alert(location + " not found: " + status);
            }
        }
    );
}

function colorFromZone(zone) {
  if (zone.currentOwner == null) {
    return "-";
  }

  return colorFromString(zone.currentOwner.name);
}

var B = 0;       // saturation
var T = 0xFF;    // brightness
var D = T - B;
var G = 0x2f;   // color granularity must be 2^x - 1
function colorFromString(str) {
  var hash = str.hashCode();
  var hue = (hash & G);
  var num = hue / (G + 1) * 6;
  var pattern = Math.floor(num);  // 0-5
  var scale = Math.floor((num - pattern) * D + 0.5);

  // console.log("str: " + str);
  // console.log("hash: " + hash.toString(16) + ", hue: " + hue.toString(16) + ", num: " + num);
  // console.log("pattern: " + pattern + ", scale: " + scale);

  var r = 0, g = 0, b = 0;
  switch (pattern)
  {
    case 0:
      r = 0xff;
      g = B + scale;
      break;
    case 1:
      r = B + D - scale;
      g = 0xff;
      break;
    case 2:
      g = 0xff;
      b = B + scale;
      break;
    case 3:
      g = B + D - scale;
      b = 0xff;
      break;
    case 4:
      r = B + scale;
      b = 0xff;
      break;
    case 5:
      r = 0xff;
      b = B + D - scale;
      break;
  }
  return "#" + getHexByte(r) + getHexByte(g) + getHexByte(b);
}

function getHexByte(num)
{
  var n = num & 0xff;
  if (n < 16) {
    return "0" + n.toString(16);
  } else {
    return n.toString(16);
  }
}

// profiling
var _starttime;
var _lasttime;

function initTime() {
  _starttime = (new Date()).getTime();
  _lasttime = _starttime;
  console.log("timer initialized " + _starttime);
}

function measureTime(point)
{
  var time = (new Date()).getTime();
  console.log("MT: " + point + ": " + (time - _lasttime) +  " (" + (time - _starttime) + ")");
  _lasttime = time;
}

google.maps.event.addDomListener(window, 'load', initialize);

<commit_msg>Center zone icon better<commit_after>// ---- Constants ----
// buffer time between map change and reload
var LOAD_DELAY=500;   // in milliseconds
// margin around viewport where zones are loaded and calculated
var LOAD_MARGIN=0.5;   // in kilometers
// marker icon representing a zone
var ZONE_ICON = {
  url: "img/red_dot.png",
  size: new google.maps.Size(10, 10),
  origin: new google.maps.Point(0,0),
  anchor: new google.maps.Point(5, 5)
};

// ---- Variables ----
var map;
var zones = {};
var markersArray = [];
var loadTimer = null;
var selectedUser;

// ---- Prototypes ----
if (typeof(Number.prototype.toRad) === "undefined") {
  Number.prototype.toRad = function() {
    return this * Math.PI / 180;
  }
}

if (typeof(String.prototype.hashCode) === "undefined") {
  // from http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery
  String.prototype.hashCode = function(){
      var hash = 0x55555555, i, char;
      if (this.length == 0) return hash;
      for (i = 0, l = this.length; i < l; i++) {
          char  = this.charCodeAt(i);
          hash  = ((hash<<5)-hash)+char;
          hash |= 0; // Convert to 32bit integer
      }
      return hash;
  }
}

// ---- Code ----
function initialize() {
  // Reduce saturation of the map
  var styles = [
  {
    stylers: [
      { saturation: -80 }
    ]
  }];

  var lat = 59.32893;
  var lng = 18.06491;
  var location = $.url().param('location');
  selectedUser = $.url().param('user');

  var mapOptions = {
    center: new google.maps.LatLng(lat, lng),
    zoom: 14,
    styles: styles
  };
  map = new google.maps.Map(document.getElementById("map-canvas"),
    mapOptions);

  google.maps.event.addListener(map, "bounds_changed", function() {
    if (loadTimer != null) {
      clearTimeout(loadTimer);
    }
    loadTimer = setTimeout(loadZones, LOAD_DELAY);
  });

  if (location != null) {
    gotoLocation(location);
  }
}

function calculateMargins(bbox) {
  var horizontalDistance = calculateDistance(
    bbox.getNorthEast().lat(),
    bbox.getNorthEast().lng(),
    bbox.getNorthEast().lat(),
    bbox.getSouthWest().lng()
    );
  var verticalDistance = calculateDistance(
    bbox.getNorthEast().lat(),
    bbox.getNorthEast().lng(),
    bbox.getSouthWest().lat(),
    bbox.getNorthEast().lng()
    );

  console.log("hDist: " + horizontalDistance);
  console.log("vDist: " + verticalDistance);

  // Doesn't handle cross datezone
  kilometerDLat = (bbox.getNorthEast().lng() - bbox.getSouthWest().lng()) / horizontalDistance;
  loadMarginLat = kilometerDLat * LOAD_MARGIN;
  kilometerDLng = (bbox.getNorthEast().lng() - bbox.getSouthWest().lng()) / verticalDistance;
  loadMarginLng = kilometerDLng * LOAD_MARGIN;

  var m = {loadMarginLat: loadMarginLat, loadMarginLng: loadMarginLng};
  return m;
}

function loadZones() {
  initTime();
  var bbox = map.getBounds();

  var m = calculateMargins(bbox);

  var data = [{
    "northEast" : {"latitude":bbox.getNorthEast().lat() + m.loadMarginLat, "longitude":bbox.getNorthEast().lng() + m.loadMarginLng},
    "southWest" : {"latitude":bbox.getSouthWest().lat() - m.loadMarginLat, "longitude":bbox.getSouthWest().lng() - m.loadMarginLng}
  }];

  $.ajax({
    type: "POST",
    crossDomain: true,
    url: "http://api.turfgame.com/v4/zones",
    contentType: "application/json",
    data: JSON.stringify(data)
  })
  .done(function(res) {
    handleZoneResult(res);
  })
  .fail(function(res) {
    alert("failed: " + JSON.stringify(res));
  });

  measureTime("load initiated");
}

// [{"region":{"id":141,"name":"Stockholm","country":"se"},
//   "id":139,
//   "currentOwner":{"id":9241,"name":"speedmaster100"},
//   "dateLastTaken":"2014-03-15T21:07:12+0000",
//   "totalTakeovers":6590,
//   "takeoverPoints":65,
//   "name":"BearZone",
//   "pointsPerHour":9,
//   "dateCreated":"2010-09-04T16:41:37+0000",
//   "longitude":18.073934,
//   "latitude":59.31514
// }]
function handleZoneResult(res) {
  console.log("Loaded " + res.length + " zones");
  measureTime("Zones loaded");
  var sites = [];
  zones = {};
  for (var i = 0; i < res.length; i++) {
    //Store zone for later lookup
    storeZone(res[i]);

    // Build sites array
    var site = {x: res[i].longitude, y: res[i].latitude};
    sites.push(site);
  }

  var diagram = calculateVoronoi(sites);
  measureTime("voronoi calculated");
  clearOverlays();
  drawVoronoi(diagram);
}

function makeHString(lat, lng)
{
  return "[" + lat + "," + lng + "]";
}

function storeZone(zone)
{
  var hstring = makeHString(zone.latitude, zone.longitude);
  zones[hstring] = zone;
}

function lookupZone(site)
{
  var hstring = makeHString(site.y, site.x);
  return zones[hstring];
}

function placeMarker(zone)
{
  var pos = new google.maps.LatLng(zone.latitude, zone.longitude);
  var owner = "-";
  if (zone.currentOwner != null) {
    owner = zone.currentOwner.name;
  }

  var marker = new google.maps.Marker({
    position: pos,
    map: map,
    icon: ZONE_ICON,
    title: "Name: " + zone.name + "\n Owner: " + owner
  });
  markersArray.push(marker);
}

function calculateVoronoi(sites)
{
  var mb = map.getBounds();
  var m = calculateMargins(mb);
  var bbox = {
    xl: mb.getSouthWest().lng() - m.loadMarginLng,
    xr: mb.getNorthEast().lng() + m.loadMarginLng,
    yt: mb.getSouthWest().lat() - m.loadMarginLat,
    yb: mb.getNorthEast().lat() + m.loadMarginLat
  };

  var voronoi = new Voronoi();
  return voronoi.compute(sites, bbox);
}

function drawVoronoi(diagram)
{
  for(var i = 0; i < diagram.cells.length; i++) {
    var polyCoords = [];
    var cell = diagram.cells[i];

    if (cell.halfedges.length > 0) {
      for (var c = 0; c < cell.halfedges.length; c++) {
        var edge = cell.halfedges[c];
        var coord = new google.maps.LatLng(edge.getStartpoint().y, edge.getStartpoint().x);
        polyCoords.push(coord);
      }
      // Close the loop
      var edge = cell.halfedges[0];
      var coord = new google.maps.LatLng(edge.getStartpoint().y, edge.getStartpoint().x);
      polyCoords.push(coord);

      var zone = lookupZone(cell.site);
      var col = colorFromZone(zone);
      var opacity = 0.1;
      if (col == "-") {  // hack!
        col = "#FFFFFF";
        opacity = 0;
      }

      placeMarker(zone);
      var polygon = new google.maps.Polygon({
        paths: polyCoords,
        strokeColor: "#000000",
        strokeOpacity: 0.1,
        strokeWeight: 1,
        fillColor: col,
        fillOpacity: opacity,
        title: zone.name
      });

      polygon.setMap(map);
      markersArray.push(polygon);
    }
  }
  measureTime("cells drawn");

  drawBoundaries(diagram);
}

function drawBoundaries(diagram)
{
  for (var i = 0; i < diagram.edges.length; i++)
  {
    var edge = diagram.edges[i];

    // Skip if this is an edge zone
    if (edge.lSite == null || edge.rSite == null) {
      continue;
    }

    lzone = lookupZone(edge.lSite);
    lname = lzone.currentOwner == null ? null : lzone.currentOwner.name;
    rzone = lookupZone(edge.rSite);
    rname = rzone.currentOwner == null ? null : rzone.currentOwner.name;

    // Skip if owner is the same
    if (lname == rname) {
      continue;
    }

    var col = "#000000";
    var opacity = 0.5;
    var weight = 1;
    if (selectedUser != null && (lname == selectedUser || rname == selectedUser))
    {
      col = "#FFFFFF";
      opacity = 1;
      weight = 4;
    }

    // Draw a line
    var start = new google.maps.LatLng(edge.va.y, edge.va.x);
    var stop = new google.maps.LatLng(edge.vb.y, edge.vb.x);
    coordinates = [start, stop];
    var line = new google.maps.Polyline({
      path: coordinates,
      strokeColor: col,
      strokeOpacity: opacity,
      strokeWeight: weight,
      zIndex: 2
    });
    line.setMap(map);
    markersArray.push(line);
  }
}

function clearOverlays() {
  for (var i = 0; i < markersArray.length; i++ ) {
    markersArray[i].setMap(null);
  }
  markersArray = [];
}

function calculateDistance(lat1, lng1, lat2, lng2)
{
  // formula from http://www.movable-type.co.uk/scripts/latlong.html
  // var R = 6371; // km
  // var d = Math.acos(Math.sin(lat1.toRad())*Math.sin(lat2.toRad()) +
  //   Math.cos(lat1.toRad())*Math.cos(lat2.toRad()) *
  //   Math.cos(lng2-lng1).toRad()) * R;
  var R = 111.111;
  var x = (lng2-lng1) * Math.cos((lat1+lat2).toRad()/2);
  var y = (lat2-lat1);
  var d = Math.sqrt(x*x + y*y) * R;

  return d;
}

var geocoder = new google.maps.Geocoder();
function gotoLocation(location) {
  geocoder.geocode(
        {'address': location},
        function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                var loc = results[0].geometry.location;
                console.log("moving to " + location + " @" + loc.lat() + ", " + loc.lng());
                map.panTo(loc);
            }
            else {
                alert(location + " not found: " + status);
            }
        }
    );
}

function colorFromZone(zone) {
  if (zone.currentOwner == null) {
    return "-";
  }

  return colorFromString(zone.currentOwner.name);
}

var B = 0;       // saturation
var T = 0xFF;    // brightness
var D = T - B;
var G = 0x2f;   // color granularity must be 2^x - 1
function colorFromString(str) {
  var hash = str.hashCode();
  var hue = (hash & G);
  var num = hue / (G + 1) * 6;
  var pattern = Math.floor(num);  // 0-5
  var scale = Math.floor((num - pattern) * D + 0.5);

  // console.log("str: " + str);
  // console.log("hash: " + hash.toString(16) + ", hue: " + hue.toString(16) + ", num: " + num);
  // console.log("pattern: " + pattern + ", scale: " + scale);

  var r = 0, g = 0, b = 0;
  switch (pattern)
  {
    case 0:
      r = 0xff;
      g = B + scale;
      break;
    case 1:
      r = B + D - scale;
      g = 0xff;
      break;
    case 2:
      g = 0xff;
      b = B + scale;
      break;
    case 3:
      g = B + D - scale;
      b = 0xff;
      break;
    case 4:
      r = B + scale;
      b = 0xff;
      break;
    case 5:
      r = 0xff;
      b = B + D - scale;
      break;
  }
  return "#" + getHexByte(r) + getHexByte(g) + getHexByte(b);
}

function getHexByte(num)
{
  var n = num & 0xff;
  if (n < 16) {
    return "0" + n.toString(16);
  } else {
    return n.toString(16);
  }
}

// profiling
var _starttime;
var _lasttime;

function initTime() {
  _starttime = (new Date()).getTime();
  _lasttime = _starttime;
  console.log("timer initialized " + _starttime);
}

function measureTime(point)
{
  var time = (new Date()).getTime();
  console.log("MT: " + point + ": " + (time - _lasttime) +  " (" + (time - _starttime) + ")");
  _lasttime = time;
}

google.maps.event.addDomListener(window, 'load', initialize);

<|endoftext|>


<commit_before>// Things to abstract out to another file

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
	var cookies = document.cookie.split(';');
	for (var i = 0; i < cookies.length; i++) {
	    var cookie = jQuery.trim(cookies[i]);
	    // Does this cookie string begin with the name we want?
	    if (cookie.substring(0, name.length + 1) == (name + '=')) {
		cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
		break;
	    }
	}
    }
    return cookieValue;
}

function postJSON(url, data, callback) {
    $.ajax({type:'POST',
	    url: url,
		dataType: 'json',
		data: data,
		success: callback,
		headers : {'X-CSRFToken':getCookie('csrftoken')}
  });
}

var global=5;

// Video player

var load_id = 0;

var video_speed = 1.0;

function change_video_speed(speed, youtube_id) {
    new_position = ytplayer.getCurrentTime() * video_speed / speed;
    video_speed = speed;
    ytplayer.loadVideoById(youtube_id, new_position);
}

function caption_at(index) {
    if (captions==0)
	return " ";

    text_array=captions.text

    if ((index>=text_array.length) || (index < 0))
	return " ";
    return text_array[index];
}

function caption_time_at(index) {
    if (captions==0)
	return 0;

    time_array=captions.start;

    if (index < 0)
	return 0;
    if (index>=time_array.length)
	return ytplayer.getDuration();

    return time_array[index] / 1000.0 / video_speed;
}

function caption_index(now) {
    // Returns the index of the current caption, given a time
    now = now * video_speed;

    if (captions==0)
	return 0;

    time_array=captions.start

    // TODO: Bisection would be better, or something incremental
    var i;
    for(i=0;i<captions.start.length; i++) {
	if(time_array[i]>(now*1000)) {
	    return i-1;
	}
    }
    return i-1;
}

function format_time(t)
{
    seconds = Math.round(t);
    minutes = Math.round(seconds / 60);
    hours = Math.round(minutes / 60);
    seconds = seconds % 60;
    minutes = minutes % 60;
    return hours+":"+((minutes < 10)?"0":"")+minutes+":"+((seconds < 10)?"0":"")+(seconds%60);
}

function update_captions(t) {
    var i=caption_index(t);
    $("#vidtime").html(format_time(ytplayer.getCurrentTime())+'/'+format_time(ytplayer.getDuration()));
    var j;
    for(j=1; j<9; j++) {
	$("#std_n"+j).html(caption_at(i-j));
	$("#std_p"+j).html(caption_at(i+j));
    }
    $("#std_0").html(caption_at(i));
}

function title_seek(i) {
    // Seek video forwards or backwards by i subtitles
    current=caption_index(getCurrentTime());
    new_time=caption_time_at(current+i);

    ytplayer.seekTo(new_time, true);
}

function updateHTML(elmId, value) {
    document.getElementById(elmId).innerHTML = value;
}

function setytplayerState(newState) {
    //    updateHTML("playerstate", newState);
}

// Updates server with location in video so we can resume from the same place
// IMPORTANT TODO: Load test
// POSSIBLE FIX: Move to unload() event and similar
var ajax_video=function(){};

function onYouTubePlayerReady(playerId) {
    ytplayer = document.getElementById("myytplayer");
    setInterval(updateytplayerInfo, 500);
    setInterval(ajax_video,5000);
    ytplayer.addEventListener("onStateChange", "onytplayerStateChange");
    ytplayer.addEventListener("onError", "onPlayerError");
    if((typeof load_id != "undefined") && (load_id != 0)) {
	var id=load_id;
	loadNewVideo(id, 0);
    }

}

function videoDestroy() {
    load_id = 0;
    // TODO/BUG: Figure out why removeEventListener doesn't work
    ytplayer.removeEventListener("onStateChange", "onytplayerStateChange");
    ytplayer.removeEventListener("onError", "onPlayerError");
    ytplayer = false;
}

function log_event(e, d) {
    //$("#eventlog").append("
");
    //$("#eventlog").append(JSON.stringify(e));

    // TODO: Decide if we want seperate tracking server.
    // If so, we need to resolve:
    // * AJAX from different domain (XMLHttpRequest cannot load http://localhost:7000/userlog. Origin http://localhost:8000 is not allowed by Access-Control-Allow-Origin.)
    // * Verifying sessions/authentication

    /*window['console'].log(JSON.stringify(e));*/
    $.get("/event",
	  {
	      "event_type" : e,
		  "event" : JSON.stringify(d),
		  "page" : document.URL
		  },
	  function(data) {
	  });
}

function seek_slide(type,oe,value) {
    //log_event('video', [type, value]);
    if(type=='slide') {
	 // HACK/TODO: Youtube recommends this be false for slide and true for stop.
	 // Works better on my system with true/true.
	 // We should test both configurations on low/high bandwidth
	 // connections, and different browsers
	 // One issue is that we query the Youtube window every 250ms for position/state
	 // With false, it returns the old one (ignoring the new seek), and moves the
         // scroll bar to the wrong spot.
	ytplayer.seekTo(value, true);
    } else if (type=='stop') {
	ytplayer.seekTo(value, true);
	log_event('video', [type, value]);
    }

    update_captions(value);
}

function get_state() {
    if (ytplayer)
	return [ytplayer.getPlayerState(),
		ytplayer.getVideoUrl(),
		ytplayer.getDuration(), ytplayer.getCurrentTime(),
		ytplayer.getVideoBytesLoaded(), ytplayer.getVideoBytesTotal(),
		ytplayer.getVideoStartBytes(),
		ytplayer.getVolume(),ytplayer.isMuted(),
		ytplayer.getPlaybackQuality(),
		ytplayer.getAvailableQualityLevels()];
    return [];
}

function onytplayerStateChange(newState) {
    setytplayerState(newState);
    log_event('video', ['State Change',newState, get_state()]);
}

function onPlayerError(errorCode) {
    alert("An error occured: " + errorCode);
}

function updateytplayerInfo() {
    if(ytplayer.getPlayerState()!=3) {
	$("#slider").slider("option","max",ytplayer.getDuration());
	$("#slider").slider("option","value",ytplayer.getCurrentTime());
    }
    if (getPlayerState() == 1){
	update_captions(getCurrentTime());
    }

    //    updateHTML("videoduration", getDuration());
    //    updateHTML("videotime", getCurrentTime());
    //    updateHTML("startbytes", getStartBytes());
    //    updateHTML("volume", getVolume());
}

// functions for the api calls
function loadNewVideo(id, startSeconds) {
    captions={"start":[0],"end":[0],"text":["Attempting to load captions..."]};
    $.getJSON("/static/subs/"+id+".srt.sjson", function(data) {
        captions=data;
    });
    load_id = id;
    //if ((typeof ytplayer != "undefined") && (ytplayer.type=="application/x-shockwave-flash")) {
    // Try it every time. If we fail, we want the error message for now.
    // TODO: Add try/catch
    try {
	ytplayer.loadVideoById(id, parseInt(startSeconds));
        load_id=0;
    }
    catch(e) {
	window['console'].log(JSON.stringify(e));
    }
}

function cueNewVideo(id, startSeconds) {
    if (ytplayer) {
	ytplayer.cueVideoById(id, startSeconds);
    }
}

function play() {
    if (ytplayer) {
	ytplayer.playVideo();
    }
}

function pause() {
    if (ytplayer) {
	ytplayer.pauseVideo();
    }
}

function stop() {
    if (ytplayer) {
	ytplayer.stopVideo();
    }
}

function getPlayerState() {
    if (ytplayer) {
	return ytplayer.getPlayerState();
    }
}

function seekTo(seconds) {
    if (ytplayer) {
	ytplayer.seekTo(seconds, true);
    }
}

function getBytesTotal() {
    if (ytplayer) {
	return ytplayer.getVideoBytesTotal();
    }
}

function getCurrentTime() {
    if (ytplayer) {
	return ytplayer.getCurrentTime();
    }
}

function getDuration() {
    if (ytplayer) {
	return ytplayer.getDuration();
    }
}

function getStartBytes() {
    if (ytplayer) {
	return ytplayer.getVideoStartBytes();
    }
}

function mute() {
    if (ytplayer) {
	ytplayer.mute();
    }
}

function unMute() {
    if (ytplayer) {
	ytplayer.unMute();
    }
}

function getEmbedCode() {
    alert(ytplayer.getVideoEmbedCode());
}

function getVideoUrl() {
    alert(ytplayer.getVideoUrl());
}

function setVolume(newVolume) {
    if (ytplayer) {
	ytplayer.setVolume(newVolume);
    }
}

function getVolume() {
    if (ytplayer) {
	return ytplayer.getVolume();
    }
}

function clearVideo() {
    if (ytplayer) {
	ytplayer.clearVideo();
    }
}<commit_msg>Wiki now supports circuits, modulo bugs<commit_after>// Things to abstract out to another file

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
	var cookies = document.cookie.split(';');
	for (var i = 0; i < cookies.length; i++) {
	    var cookie = jQuery.trim(cookies[i]);
	    // Does this cookie string begin with the name we want?
	    if (cookie.substring(0, name.length + 1) == (name + '=')) {
		cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
		break;
	    }
	}
    }
    return cookieValue;
}

function postJSON(url, data, callback) {
    $.ajax({type:'POST',
	    url: url,
		dataType: 'json',
		data: data,
		success: callback,
		headers : {'X-CSRFToken':getCookie('csrftoken')}
  });
}

// For easy embedding of CSRF in forms
$(function() {
    $('#csrfmiddlewaretoken').attr("value", getCookie('csrftoken'))
});

// For working with circuits in wiki:

function submit_circuit(circuit_id) {
    $("input.schematic").each(function(index,element){ element.schematic.update_value(); });
    postJSON('/save_circuit/'+circuit_id,
	     {'schematic': $('#schematic_'+circuit_id).attr("value")},
	     function(data){ if (data.results=='success') alert("Saved");});
    return false;
}

// Video player

var load_id = 0;

var video_speed = 1.0;

function change_video_speed(speed, youtube_id) {
    new_position = ytplayer.getCurrentTime() * video_speed / speed;
    video_speed = speed;
    ytplayer.loadVideoById(youtube_id, new_position);
}

function caption_at(index) {
    if (captions==0)
	return " ";

    text_array=captions.text

    if ((index>=text_array.length) || (index < 0))
	return " ";
    return text_array[index];
}

function caption_time_at(index) {
    if (captions==0)
	return 0;

    time_array=captions.start;

    if (index < 0)
	return 0;
    if (index>=time_array.length)
	return ytplayer.getDuration();

    return time_array[index] / 1000.0 / video_speed;
}

function caption_index(now) {
    // Returns the index of the current caption, given a time
    now = now * video_speed;

    if (captions==0)
	return 0;

    time_array=captions.start

    // TODO: Bisection would be better, or something incremental
    var i;
    for(i=0;i<captions.start.length; i++) {
	if(time_array[i]>(now*1000)) {
	    return i-1;
	}
    }
    return i-1;
}

function format_time(t)
{
    seconds = Math.round(t);
    minutes = Math.round(seconds / 60);
    hours = Math.round(minutes / 60);
    seconds = seconds % 60;
    minutes = minutes % 60;
    return hours+":"+((minutes < 10)?"0":"")+minutes+":"+((seconds < 10)?"0":"")+(seconds%60);
}

function update_captions(t) {
    var i=caption_index(t);
    $("#vidtime").html(format_time(ytplayer.getCurrentTime())+'/'+format_time(ytplayer.getDuration()));
    var j;
    for(j=1; j<9; j++) {
	$("#std_n"+j).html(caption_at(i-j));
	$("#std_p"+j).html(caption_at(i+j));
    }
    $("#std_0").html(caption_at(i));
}

function title_seek(i) {
    // Seek video forwards or backwards by i subtitles
    current=caption_index(getCurrentTime());
    new_time=caption_time_at(current+i);

    ytplayer.seekTo(new_time, true);
}

function updateHTML(elmId, value) {
    document.getElementById(elmId).innerHTML = value;
}

function setytplayerState(newState) {
    //    updateHTML("playerstate", newState);
}

// Updates server with location in video so we can resume from the same place
// IMPORTANT TODO: Load test
// POSSIBLE FIX: Move to unload() event and similar
var ajax_video=function(){};

function onYouTubePlayerReady(playerId) {
    ytplayer = document.getElementById("myytplayer");
    setInterval(updateytplayerInfo, 500);
    setInterval(ajax_video,5000);
    ytplayer.addEventListener("onStateChange", "onytplayerStateChange");
    ytplayer.addEventListener("onError", "onPlayerError");
    if((typeof load_id != "undefined") && (load_id != 0)) {
	var id=load_id;
	loadNewVideo(id, 0);
    }

}

function videoDestroy() {
    load_id = 0;
    // TODO/BUG: Figure out why removeEventListener doesn't work
    ytplayer.removeEventListener("onStateChange", "onytplayerStateChange");
    ytplayer.removeEventListener("onError", "onPlayerError");
    ytplayer = false;
}

function log_event(e, d) {
    //$("#eventlog").append("
");
    //$("#eventlog").append(JSON.stringify(e));

    // TODO: Decide if we want seperate tracking server.
    // If so, we need to resolve:
    // * AJAX from different domain (XMLHttpRequest cannot load http://localhost:7000/userlog. Origin http://localhost:8000 is not allowed by Access-Control-Allow-Origin.)
    // * Verifying sessions/authentication

    /*window['console'].log(JSON.stringify(e));*/
    $.get("/event",
	  {
	      "event_type" : e,
		  "event" : JSON.stringify(d),
		  "page" : document.URL
		  },
	  function(data) {
	  });
}

function seek_slide(type,oe,value) {
    //log_event('video', [type, value]);
    if(type=='slide') {
	 // HACK/TODO: Youtube recommends this be false for slide and true for stop.
	 // Works better on my system with true/true.
	 // We should test both configurations on low/high bandwidth
	 // connections, and different browsers
	 // One issue is that we query the Youtube window every 250ms for position/state
	 // With false, it returns the old one (ignoring the new seek), and moves the
         // scroll bar to the wrong spot.
	ytplayer.seekTo(value, true);
    } else if (type=='stop') {
	ytplayer.seekTo(value, true);
	log_event('video', [type, value]);
    }

    update_captions(value);
}

function get_state() {
    if (ytplayer)
	return [ytplayer.getPlayerState(),
		ytplayer.getVideoUrl(),
		ytplayer.getDuration(), ytplayer.getCurrentTime(),
		ytplayer.getVideoBytesLoaded(), ytplayer.getVideoBytesTotal(),
		ytplayer.getVideoStartBytes(),
		ytplayer.getVolume(),ytplayer.isMuted(),
		ytplayer.getPlaybackQuality(),
		ytplayer.getAvailableQualityLevels()];
    return [];
}

function onytplayerStateChange(newState) {
    setytplayerState(newState);
    log_event('video', ['State Change',newState, get_state()]);
}

function onPlayerError(errorCode) {
    alert("An error occured: " + errorCode);
}

function updateytplayerInfo() {
    if(ytplayer.getPlayerState()!=3) {
	$("#slider").slider("option","max",ytplayer.getDuration());
	$("#slider").slider("option","value",ytplayer.getCurrentTime());
    }
    if (getPlayerState() == 1){
	update_captions(getCurrentTime());
    }

    //    updateHTML("videoduration", getDuration());
    //    updateHTML("videotime", getCurrentTime());
    //    updateHTML("startbytes", getStartBytes());
    //    updateHTML("volume", getVolume());
}

// functions for the api calls
function loadNewVideo(id, startSeconds) {
    captions={"start":[0],"end":[0],"text":["Attempting to load captions..."]};
    $.getJSON("/static/subs/"+id+".srt.sjson", function(data) {
        captions=data;
    });
    load_id = id;
    //if ((typeof ytplayer != "undefined") && (ytplayer.type=="application/x-shockwave-flash")) {
    // Try it every time. If we fail, we want the error message for now.
    // TODO: Add try/catch
    try {
	ytplayer.loadVideoById(id, parseInt(startSeconds));
        load_id=0;
    }
    catch(e) {
	window['console'].log(JSON.stringify(e));
    }
}

function cueNewVideo(id, startSeconds) {
    if (ytplayer) {
	ytplayer.cueVideoById(id, startSeconds);
    }
}

function play() {
    if (ytplayer) {
	ytplayer.playVideo();
    }
}

function pause() {
    if (ytplayer) {
	ytplayer.pauseVideo();
    }
}

function stop() {
    if (ytplayer) {
	ytplayer.stopVideo();
    }
}

function getPlayerState() {
    if (ytplayer) {
	return ytplayer.getPlayerState();
    }
}

function seekTo(seconds) {
    if (ytplayer) {
	ytplayer.seekTo(seconds, true);
    }
}

function getBytesTotal() {
    if (ytplayer) {
	return ytplayer.getVideoBytesTotal();
    }
}

function getCurrentTime() {
    if (ytplayer) {
	return ytplayer.getCurrentTime();
    }
}

function getDuration() {
    if (ytplayer) {
	return ytplayer.getDuration();
    }
}

function getStartBytes() {
    if (ytplayer) {
	return ytplayer.getVideoStartBytes();
    }
}

function mute() {
    if (ytplayer) {
	ytplayer.mute();
    }
}

function unMute() {
    if (ytplayer) {
	ytplayer.unMute();
    }
}

function getEmbedCode() {
    alert(ytplayer.getVideoEmbedCode());
}

function getVideoUrl() {
    alert(ytplayer.getVideoUrl());
}

function setVolume(newVolume) {
    if (ytplayer) {
	ytplayer.setVolume(newVolume);
    }
}

function getVolume() {
    if (ytplayer) {
	return ytplayer.getVolume();
    }
}

function clearVideo() {
    if (ytplayer) {
	ytplayer.clearVideo();
    }
}<|endoftext|>