<commit_before>const { Context } = require('../core/context');
const { KeyValueCollection } = require('./key_value_collection');
const { PassThrough } = require('stream');

const spaces = /\s+/;
const newline = "\n";

/**
 * ManifestParser parses text-based payload and tag manifests that
 * conform to the BagIt spec. These files have the following format:
 *
 * 924238a7018a567062c6527675fcf1c0  data/docs/index.html
 *
 * The first item on each line is a checksum and the second is the
 * relative path (within the bag) of the file it was calculated from.
 * The two items are separated by one or more spaces.
 *
 * This class has no methods. It simply responds to events on the stream
 * you pipe into it. After parsing the stream, it stores the data it
 * has parsed in bagItFile.keyValueCollection. Within that collection,
 * you can use the first() method to look up the checksum for a file.
 *
 * You can attach your own callback to the ManifestParser.stream end
 * event, if you want to do something with the BagItFile or (more likely)
 * its keyValueCollection when parsing completes.
 *
 * @param {BagItFile} bagItFile - A BagItFile object. If the object
 * does not already have a keyValueCollection, the parser will create
 * one.
 *
 * For more on the BagIt spec,
 * see {@link https://tools.ietf.org/html/draft-kunze-bagit-17|BagIt Spec}
 *
 * For info about how to read the parsed data from the file, see {@link KeyValueCollection}
 *
 * @example
 *
 * // Set up a BagItFile. Note the file itself is a payload manifest.
 * let pathToManifest = "/path/to/bag-info.txt";
 * let stats = fs.statSync(pathToManifest);
 * let bagItFile = new BagItFile(pathToManifest, "manifest-sha256.txt", stats);
 *
 * // Open the BagItFile for reading
 * let stream = fs.createReadStream(pathToManifest);
 *
 * // Create a new ManifestParser to parse the BagItFile
 * let manifestParser = new ManifestParser(bagItFile);
 *
 * // Optional: Hook up your callback to do something with
 * // bagItFile when the parsing is done.
 * manifestParser.stream.on('end', YOUR_CALLBACK_HERE);
 *
 * // Required: Pipe your file reader into the parser.
 * stream.pipe(manifestParser.stream).on('error', function(e){handleError(e)});
 *
 */
class ManifestParser {
    constructor(bagItFile) {
        /**
          * bagItFile is the file that will be parsed.
          * When parsing is complete, bagItFile.keyValueCollection
          * will be populated with relative file paths and
          * the checksum digests that correspond to those paths.
          *
          * @type {BagItFile}
          */
        this.bagItFile = bagItFile;

        /**
          * stream is a PassThrough stream that allows
          * for data to be piped from a ReadStream into
          * the parser. You can attach your own 'data' and
          * 'end' events to this stream, but the parser
          * already does the parsing work for you.
          *
          * @type {stream.PassThrough}
          */
        this.stream = new PassThrough();
        this.stream.setEncoding('utf8');

        /**
         * lastFragment is the last chunk of raw data from
         * the Readable stream.
         *
         * @private
         * @type {string}
         */
        this.lastFragment = '';

        var parser = this;
        if (bagItFile.keyValueCollection == null) {
            bagItFile.keyValueCollection = new KeyValueCollection();
        }

        // Handle line, lines, or data fragments piped in from reader.
        parser.stream.on('data', function(data) {
            var lines = data.split(newline);
            var lastIndex = lines.length - 1;
            for (var i=0; i < lines.length; i++) {
                var line = lines[i];
                if (i == 0) {
                    // First chunk of new data may begin in the middle of a line.
                    line = parser.lastFragment + line;
                    parser.lastFragment = '';
                } else if (i == lastIndex && !data.endsWith(newline)) {
                    // Last chunk of data is an incomplete line fragment
                    parser.lastFragment = line;
                    continue;
                }
                // First item on line is the fixity value.
                // Second item is file name, which may contain multiple spaces.
                if (i < lastIndex) {
                    var fixityValue = line.split(spaces, 1)[0];
                    var filename = line.replace(fixityValue, '').trim();
                    //Context.logger.debug(`"${filename}" = "${fixityValue}"`);
                    parser.bagItFile.keyValueCollection.add(filename, fixityValue);
                }
            }
        });

        // Handle end of stream
        parser.stream.on('end', function() {
            //Context.logger.debug(`Finished parsing manifest ${parser.bagItFile.absPath}`);
        });
    }
}

module.exports.ManifestParser = ManifestParser;
<commit_msg>Ignore trailing blank line when parsing manifests<commit_after>const { Context } = require('../core/context');
const { KeyValueCollection } = require('./key_value_collection');
const { PassThrough } = require('stream');

const spaces = /\s+/;
const newline = "\n";

/**
 * ManifestParser parses text-based payload and tag manifests that
 * conform to the BagIt spec. These files have the following format:
 *
 * 924238a7018a567062c6527675fcf1c0  data/docs/index.html
 *
 * The first item on each line is a checksum and the second is the
 * relative path (within the bag) of the file it was calculated from.
 * The two items are separated by one or more spaces.
 *
 * This class has no methods. It simply responds to events on the stream
 * you pipe into it. After parsing the stream, it stores the data it
 * has parsed in bagItFile.keyValueCollection. Within that collection,
 * you can use the first() method to look up the checksum for a file.
 *
 * You can attach your own callback to the ManifestParser.stream end
 * event, if you want to do something with the BagItFile or (more likely)
 * its keyValueCollection when parsing completes.
 *
 * @param {BagItFile} bagItFile - A BagItFile object. If the object
 * does not already have a keyValueCollection, the parser will create
 * one.
 *
 * For more on the BagIt spec,
 * see {@link https://tools.ietf.org/html/draft-kunze-bagit-17|BagIt Spec}
 *
 * For info about how to read the parsed data from the file, see {@link KeyValueCollection}
 *
 * @example
 *
 * // Set up a BagItFile. Note the file itself is a payload manifest.
 * let pathToManifest = "/path/to/bag-info.txt";
 * let stats = fs.statSync(pathToManifest);
 * let bagItFile = new BagItFile(pathToManifest, "manifest-sha256.txt", stats);
 *
 * // Open the BagItFile for reading
 * let stream = fs.createReadStream(pathToManifest);
 *
 * // Create a new ManifestParser to parse the BagItFile
 * let manifestParser = new ManifestParser(bagItFile);
 *
 * // Optional: Hook up your callback to do something with
 * // bagItFile when the parsing is done.
 * manifestParser.stream.on('end', YOUR_CALLBACK_HERE);
 *
 * // Required: Pipe your file reader into the parser.
 * stream.pipe(manifestParser.stream).on('error', function(e){handleError(e)});
 *
 */
class ManifestParser {
    constructor(bagItFile) {
        /**
          * bagItFile is the file that will be parsed.
          * When parsing is complete, bagItFile.keyValueCollection
          * will be populated with relative file paths and
          * the checksum digests that correspond to those paths.
          *
          * @type {BagItFile}
          */
        this.bagItFile = bagItFile;

        /**
          * stream is a PassThrough stream that allows
          * for data to be piped from a ReadStream into
          * the parser. You can attach your own 'data' and
          * 'end' events to this stream, but the parser
          * already does the parsing work for you.
          *
          * @type {stream.PassThrough}
          */
        this.stream = new PassThrough();
        this.stream.setEncoding('utf8');

        /**
         * lastFragment is the last chunk of raw data from
         * the Readable stream.
         *
         * @private
         * @type {string}
         */
        this.lastFragment = '';

        var parser = this;
        if (bagItFile.keyValueCollection == null) {
            bagItFile.keyValueCollection = new KeyValueCollection();
        }

        // Handle line, lines, or data fragments piped in from reader.
        parser.stream.on('data', function(data) {
            var lines = data.split(newline);
            var lastIndex = lines.length - 1;
            for (var i=0; i < lines.length; i++) {
                var line = lines[i];
                if (i == 0) {
                    // First chunk of new data may begin in the middle of a line.
                    line = parser.lastFragment + line;
                    parser.lastFragment = '';
                } else if (i == lastIndex && !data.endsWith(newline)) {
                    // Last chunk of data is an incomplete line fragment
                    parser.lastFragment = line;
                    continue;
                }
                // First item on line is the fixity value.
                // Second item is file name, which may contain multiple spaces.
                if (i < lastIndex) {
                    var fixityValue = line.split(spaces, 1)[0];
                    var filename = line.replace(fixityValue, '').trim();
                    //Context.logger.debug(`"${filename}" = "${fixityValue}"`);
                    if (filename != '' && fixityValue != '') {
                        parser.bagItFile.keyValueCollection.add(filename, fixityValue);
                    }
                }
            }
        });

        // Handle end of stream
        parser.stream.on('end', function() {
            //Context.logger.debug(`Finished parsing manifest ${parser.bagItFile.absPath}`);
        });
    }
}

module.exports.ManifestParser = ManifestParser;
<|endoftext|>


<commit_before>(function($){

	$.fn.mdl=function(options, callback){

        /*
        | ---------------------------
        | value returned for confirm and prompt
        | ---------------------------
        */
        var retour = false;

        /*
        | ---------------------------
        | Calcul number of items for ids & z-index
        | ---------------------------
        */
        if(	$(".mdl").length	){
        	var n = $(".mdl").length + 1;
        }else{
        	var n = 0;
        }

        /*
        | ---------------------------
        | default params
        | ---------------------------
        */
    	var defauts=
        {
		'type': "modal",		//dialog,confirm,prompt,modal
		'fullscreen': "true",		//Largeur de la galerie
		'overlayClick':"false",
		'content':''
         };

 		/*
 		| ---------------------------
 		| //On fusionne nos deux objets ! =D
 		| ---------------------------
 		*/

        var parametres=$.extend(defauts, options);

		/*
		| ---------------------------
		| add overlay if is not
		| ---------------------------
		*/
		var overlay = $('

');
		if(!$("#mdl-overlay").length){
			$(overlay).appendTo('body');
		}

		/*
		| ---------------------------
		| global returned objects
		| ---------------------------
		*/
        return this.each(function(){

			//On stocke notre élément dans une variable par commodité
			var element=$(this);

			/*
			| ---------------------------
			| //default params
			| ---------------------------
			*/
			var fullscreen = parametres.fullscreen;
			var type = parametres.type;
			var overlayClick = parametres.overlayClick;

		/*
			| ---------------------------
			| or by data
			| ---------------------------
			*/
			if(
				element.attr('data-type')
			){
				type = element.data("type");
			}

			if(
				element.attr('data-fullscreen')
			){
				fullscreen = element.data("fullscreen");

			}

			if(
				element.attr('data-overlayClick')
			){
				overlayClick = element.data("overlayClick");
			}

			/*
			| ---------------------------
			| if modal use the modal exist else create one
			| ---------------------------
			*/
			if(type=="modal"){

				var cible = element.data("target");

			}else{

				/*
				| ---------------------------
				| gestion z-index
				| ---------------------------
				*/
				var zindex = 100000+n;

				/*
				| ---------------------------
				| addmodal
				| ---------------------------
				*/
				var mymodal = $('

');

				$(mymodal).appendTo('body');

				/*
				| ---------------------------
				| ok we have our id!
				| ---------------------------
				*/
				var cible = '#mdl__' + n;
			}

			/*
			| ---------------------------
			| confirm & prompt add buttons and result
			| ---------------------------
			*/
			if(type=="confirm" || type=="prompt"){

				/*
				| ---------------------------
				| add content
				| ---------------------------
				*/
				$(cible+" .mdl-content").html(parametres.content);

				if(type=="prompt"){
					$(cible+" .mdl-content").append("<input type='text' value='' id='response_mdl_"+ n +"' >");
				}

				/*
				| ---------------------------
				| add buttons
				| ---------------------------
				*/
				if(type=="confirm"){
					var btns = $('

No

Yes

');
					$(btns).appendTo(cible+" .mdl-container");
				}

				if(type=="prompt"){

					var btns = $('

Annuler

Valider

');
					$(btns).appendTo(cible+" .mdl-container");
				}

				/*
				| ---------------------------
				| medium format
				| ---------------------------
				*/
				$(cible+" .mdl-container").addClass("medium");

				/*
				| ---------------------------
				| on click event return response
				| ---------------------------
				*/
				$( "body" ).on( "click",cible + " .mdl-buttons a", function(event) {
					event.preventDefault();
					var response = false;

					/*
					| ---------------------------
					| return true or false for confirm
					| ---------------------------
					*/

					response = $(this).data("response");

					/*
					| ---------------------------
					| return value of input for prompt
					| ---------------------------
					*/
					if(type=="prompt"){
						var id = $(this).data("id");
						response = $("#response_mdl_"+id).val();
					}

					close(cible);

					/*
					| ---------------------------
					| return response
					| ---------------------------
					*/

					if(response){
						callback.call(this, response);
					}
					// call the callback and apply the scope:

				});

			}

			/*
			| ---------------------------
			| if fullscreen addclass fullscreen
			| ---------------------------
			*/
			if(fullscreen){		$(cible).addClass("mdl-fullscreen");	}

			/*
			| ---------------------------
			| add close button
			| ---------------------------
			*/
			$(cible).append('

');

			/*
			|
			| on click event add open class css
			|
			*/
			element.click( function() {
				open(cible);

			});

			/*
			|
			| on click event to close button add close class css
			|
			*/
			$( "body" ).on( "click", cible + " .mdl-close", function() {
				close(cible);
			});

			/*
			|
			| close to but by overlay click
			|
			*/
			if(overlayClick){
				$( "body" ).on( "click","#mdl-overlay", function() {

					close(cible);

				});
			}

		});

		function open(cible) {
			$(cible).addClass("open");
			$("#mdl-overlay").addClass("active");
			setTimeout(function(){
				$(cible).addClass("animIn");
				$("#mdl-overlay").addClass("animIn");
			}, 100);
		}

		/*
		|
		| close function
		|
		*/
		function close(cible) {

						if(	$(cible).hasClass("open")	){

							$(cible).removeClass("animIn");
							$(cible).addClass("animOut");
							if(size()==1){
								$("#mdl-overlay").addClass("animOut");
								$("#mdl-overlay").removeClass("animIn");
							}

							setTimeout(function(){

								$(cible).removeClass("open");
								$(cible).removeClass("animOut");
								if(size()==0){
									$("#mdl-overlay").removeClass("animIn");
									$("#mdl-overlay").removeClass("active").removeClass("animOut");
								}

							}, 800);
						}

		}

		/*
		|
		| global size of modals
		|
		*/
		function size() {
			return $(".mdl.open").length;

		}

	};

})(jQuery);

/*
|
| waaaw it's very ugly that !!!!  ... I dont care...it work!
|
*/
function mdl_open(cible) {
	$(cible).addClass("open");
	$("#mdl-overlay").addClass("active");
	setTimeout(function(){
		$(cible).addClass("animIn");
		$("#mdl-overlay").addClass("animIn");
	}, 100);
}

function mdl_close(cible) {

	if( $(cible).hasClass("open")	){

		$(cible).removeClass("animIn");
		$(cible).addClass("animOut");
		if( $(".mdl.open").length == 0){
			$("#mdl-overlay").addClass("animOut");
		}

		setTimeout(function(){

			$(cible).removeClass("open");
			$(cible).removeClass("animOut");
			if( $(".mdl.open").length == 0){
				$("#mdl-overlay").removeClass("animIn");
				$("#mdl-overlay").removeClass("active").removeClass("animOut");
			}

		}, 800);
	}

}

/*--------------------------------------
****** MODAL *****
--------------------------------------*/

	function lunch_mdl(options, callback){

        /*
        | ---------------------------
        | value returned for confirm and prompt
        | ---------------------------
        */
        var retour = false;

        /*
        | ---------------------------
        | Calcul number of items for ids & z-index
        | ---------------------------
        */
        if(	$(".mdl").length	){
        	var n = $(".mdl").length + 1;
        }else{
        	var n = 0;
        }

        /*
        | ---------------------------
        | default params
        | ---------------------------
        */
    	var defauts=
        {
		'type': "modal",		//dialog,confirm,prompt,modal
		'fullscreen': "true",		//Largeur de la galerie
		'overlayClick':"false",
		'content':''
         };

 		/*
 		| ---------------------------
 		| //On fusionne nos deux objets ! =D
 		| ---------------------------
 		*/

        var parametres=$.extend(defauts, options);

		/*
		| ---------------------------
		| add overlay if is not
		| ---------------------------
		*/
		var overlay = $('

');
		if(!$("#mdl-overlay").length){
			$(overlay).appendTo('body');
		}

		/*
		| ---------------------------
		| global returned objects
		| ---------------------------
		*/
        //return this.each(function(){

			//On stocke notre élément dans une variable par commodité
			//var element=$(this);

			/*
			| ---------------------------
			| //default params
			| ---------------------------
			*/
			var fullscreen = parametres.fullscreen;
			var type = parametres.type;
			var overlayClick = parametres.overlayClick;

			/*
			| ---------------------------
			| if modal use the modal exist else create one
			| ---------------------------
			*/
			//if(type=="modal"){

			//	var cible = element.data("target");

			//}else{

				/*
				| ---------------------------
				| gestion z-index
				| ---------------------------
				*/
				var zindex = 100000+n;

				/*
				| ---------------------------
				| addmodal
				| ---------------------------
				*/
				var mymodal = $('

');

				$(mymodal).appendTo('body');

				/*
				| ---------------------------
				| ok we have our id!
				| ---------------------------
				*/
				var cible = '#mdl__' + n;
			//}

			/*
			| ---------------------------
			| confirm & prompt add buttons and result
			| ---------------------------
			*/
			if(type=="confirm" || type=="prompt"){

				/*
				| ---------------------------
				| add content
				| ---------------------------
				*/
				$(cible+" .mdl-content").html(parametres.content);

				if(type=="prompt"){
					$(cible+" .mdl-content").append("<input type='text' value='' id='response_mdl_"+ n +"' >");
				}

				/*
				| ---------------------------
				| add buttons
				| ---------------------------
				*/
				if(type=="confirm"){
					var btns = $('

No

Yes

');
					$(btns).appendTo(cible+" .mdl-container");
				}

				if(type=="prompt"){

					var btns = $('

Annuler

Valider

');
					$(btns).appendTo(cible+" .mdl-container");
				}

				/*
				| ---------------------------
				| medium format
				| ---------------------------
				*/
				$(cible+" .mdl-container").addClass("medium");

				/*
				| ---------------------------
				| on click event return response
				| ---------------------------
				*/
				$( "body" ).on( "click",cible + " .mdl-buttons a", function(event) {
					event.preventDefault();
					var response = false;

					/*
					| ---------------------------
					| return true or false for confirm
					| ---------------------------
					*/

					response = $(this).data("response");

					/*
					| ---------------------------
					| return value of input for prompt
					| ---------------------------
					*/
					if(type=="prompt"){
						var id = $(this).data("id");
						response = $("#response_mdl_"+id).val();
					}

					close(cible);

					/*
					| ---------------------------
					| return response
					| ---------------------------
					*/

					if(response){
						callback.call(this, response);
					}
					// call the callback and apply the scope:

				});

			}

			/*
			| ---------------------------
			| if fullscreen addclass fullscreen
			| ---------------------------
			*/
			if(fullscreen){		$(cible).addClass("mdl-fullscreen");	}

			/*
			| ---------------------------
			| add close button
			| ---------------------------
			*/
			$(cible).append('

');

			/*
			|
			| on click event add open class css
			|
			*/
			//element.click( function() {
				open(cible);

			//});

			/*
			|
			| on click event to close button add close class css
			|
			*/
			$( "body" ).on( "click", cible + " .mdl-close", function() {
				close(cible);
			});

			/*
			|
			| close to but by overlay click
			|
			*/
			if(overlayClick){
				$( "body" ).on( "click","#mdl-overlay", function() {

					close(cible);

				});
			}

		//});

		function open(cible) {
			$(cible).addClass("open");
			$("#mdl-overlay").addClass("active");
			setTimeout(function(){
				$(cible).addClass("animIn");
				$("#mdl-overlay").addClass("animIn");
			}, 100);
		}

		/*
		|
		| close function
		|
		*/
		function close(cible) {

						if(	$(cible).hasClass("open")	){

							$(cible).removeClass("animIn");
							$(cible).addClass("animOut");
							if(size()==1){
								$("#mdl-overlay").addClass("animOut");
								$("#mdl-overlay").removeClass("animIn");
							}

							setTimeout(function(){

								$(cible).removeClass("open");
								$(cible).removeClass("animOut");
								if(size()==0){
									$("#mdl-overlay").removeClass("animIn");
									$("#mdl-overlay").removeClass("active").removeClass("animOut");
								}

							}, 800);
						}

		}

		/*
		|
		| global size of modals
		|
		*/
		function size() {
			return $(".mdl.open").length;

		}

};

<commit_msg>Update mdl.js<commit_after>(function($){

	$.fn.mdl=function(options, callback){

        /*
        | ---------------------------
        | value returned for confirm and prompt
        | ---------------------------
        */
        var retour = false;

        /*
        | ---------------------------
        | Calcul number of items for ids & z-index
        | ---------------------------
        */
        if(	$(".mdl").length	){
        	var n = $(".mdl").length + 1;
        }else{
        	var n = 0;
        }

        /*
        | ---------------------------
        | default params
        | ---------------------------
        */
    	var defauts=
        {
		'type': "modal",		//dialog,confirm,prompt,modal
		'fullscreen': "true",		//Largeur de la galerie
		'overlayClick':"false",
		'content':''
         };

 		/*
 		| ---------------------------
 		| //On fusionne nos deux objets ! =D
 		| ---------------------------
 		*/

        var parametres=$.extend(defauts, options);

		/*
		| ---------------------------
		| add overlay if is not
		| ---------------------------
		*/
		var overlay = $('

');
		if(!$("#mdl-overlay").length){
			$(overlay).appendTo('body');
		}

		/*
		| ---------------------------
		| global returned objects
		| ---------------------------
		*/
        return this.each(function(){

			//On stocke notre élément dans une variable par commodité
			var element=$(this);

			/*
			| ---------------------------
			| //default params
			| ---------------------------
			*/
			var fullscreen = parametres.fullscreen;
			var type = parametres.type;
			var overlayClick = parametres.overlayClick;

		/*
			| ---------------------------
			| or by data
			| ---------------------------
			*/
			if(
				element.attr('data-type')
			){
				type = element.data("type");
			}

			if(
				element.attr('data-fullscreen')
			){
				fullscreen = element.data("fullscreen");

			}

			if(
				element.attr('data-overlayClick')
			){
				overlayClick = element.data("overlayClick");
			}

			/*
			| ---------------------------
			| if modal use the modal exist else create one
			| ---------------------------
			*/
			if(type=="modal"){

				var cible = element.data("target");

			}else{

				/*
				| ---------------------------
				| gestion z-index
				| ---------------------------
				*/
				var zindex = 100000+n;

				/*
				| ---------------------------
				| addmodal
				| ---------------------------
				*/
				var mymodal = $('

');

				$(mymodal).appendTo('body');

				/*
				| ---------------------------
				| ok we have our id!
				| ---------------------------
				*/
				var cible = '#mdl__' + n;
			}

			/*
			| ---------------------------
			| confirm & prompt add buttons and result
			| ---------------------------
			*/
			if(type=="confirm" || type=="prompt"){

				/*
				| ---------------------------
				| add content
				| ---------------------------
				*/
				$(cible+" .mdl-content").html(parametres.content);

				if(type=="prompt"){
					$(cible+" .mdl-content").append("<input type='text' value='' id='response_mdl_"+ n +"' >");
				}

				/*
				| ---------------------------
				| add buttons
				| ---------------------------
				*/
				if(type=="confirm"){
					var btns = $('

Non

Oui

');
					$(btns).appendTo(cible+" .mdl-container");
				}

				if(type=="prompt"){

					var btns = $('

Annuler

Valider

');
					$(btns).appendTo(cible+" .mdl-container");
				}

				/*
				| ---------------------------
				| medium format
				| ---------------------------
				*/
				$(cible+" .mdl-container").addClass("medium");

				/*
				| ---------------------------
				| on click event return response
				| ---------------------------
				*/
				$( "body" ).on( "click",cible + " .mdl-buttons a", function(event) {
					event.preventDefault();
					var response = false;

					/*
					| ---------------------------
					| return true or false for confirm
					| ---------------------------
					*/

					response = $(this).data("response");

					/*
					| ---------------------------
					| return value of input for prompt
					| ---------------------------
					*/
					if(type=="prompt"){
						var id = $(this).data("id");
						response = $("#response_mdl_"+id).val();
					}

					close(cible);

					/*
					| ---------------------------
					| return response
					| ---------------------------
					*/

					if(response){
						callback.call(this, response);
					}
					// call the callback and apply the scope:

				});

			}

			/*
			| ---------------------------
			| if fullscreen addclass fullscreen
			| ---------------------------
			*/
			if(fullscreen){		$(cible).addClass("mdl-fullscreen");	}

			/*
			| ---------------------------
			| add close button
			| ---------------------------
			*/
			$(cible).append('

');

			/*
			|
			| on click event add open class css
			|
			*/
			element.click( function() {
				open(cible);

			});

			/*
			|
			| on click event to close button add close class css
			|
			*/
			$( "body" ).on( "click", cible + " .mdl-close", function() {
				close(cible);
			});

			/*
			|
			| close to but by overlay click
			|
			*/
			if(overlayClick){
				$( "body" ).on( "click","#mdl-overlay", function() {

					close(cible);

				});
			}

		});

		function open(cible) {
			$(cible).addClass("open");
			$("#mdl-overlay").addClass("active");
			setTimeout(function(){
				$(cible).addClass("animIn");
				$("#mdl-overlay").addClass("animIn");
			}, 100);
		}

		/*
		|
		| close function
		|
		*/
		function close(cible) {

						if(	$(cible).hasClass("open")	){

							$(cible).removeClass("animIn");
							$(cible).addClass("animOut");
							if(size()==1){
								$("#mdl-overlay").addClass("animOut");
								$("#mdl-overlay").removeClass("animIn");
							}

							setTimeout(function(){

								$(cible).removeClass("open");
								$(cible).removeClass("animOut");
								if(size()==0){
									$("#mdl-overlay").removeClass("animIn");
									$("#mdl-overlay").removeClass("active").removeClass("animOut");
								}

							}, 800);
						}

		}

		/*
		|
		| global size of modals
		|
		*/
		function size() {
			return $(".mdl.open").length;

		}

	};

})(jQuery);

/*
|
| waaaw it's very ugly that !!!!  ... I dont care...it work!
|
*/
function mdl_open(cible) {
	$(cible).addClass("open");
	$("#mdl-overlay").addClass("active");
	setTimeout(function(){
		$(cible).addClass("animIn");
		$("#mdl-overlay").addClass("animIn");
	}, 100);
}

function mdl_close(cible) {

	if( $(cible).hasClass("open")	){

		$(cible).removeClass("animIn");
		$(cible).addClass("animOut");
		if( $(".mdl.open").length == 0){
			$("#mdl-overlay").addClass("animOut");
		}

		setTimeout(function(){

			$(cible).removeClass("open");
			$(cible).removeClass("animOut");
			if( $(".mdl.open").length == 0){
				$("#mdl-overlay").removeClass("animIn");
				$("#mdl-overlay").removeClass("active").removeClass("animOut");
			}

		}, 800);
	}

}

/*--------------------------------------
****** MODAL *****
--------------------------------------*/

	function lunch_mdl(options, callback){

        /*
        | ---------------------------
        | value returned for confirm and prompt
        | ---------------------------
        */
        var retour = false;

        /*
        | ---------------------------
        | Calcul number of items for ids & z-index
        | ---------------------------
        */
        if(	$(".mdl").length	){
        	var n = $(".mdl").length + 1;
        }else{
        	var n = 0;
        }

        /*
        | ---------------------------
        | default params
        | ---------------------------
        */
    	var defauts=
        {
		'type': "modal",		//dialog,confirm,prompt,modal
		'fullscreen': "true",		//Largeur de la galerie
		'overlayClick':"false",
		'content':''
         };

 		/*
 		| ---------------------------
 		| //On fusionne nos deux objets ! =D
 		| ---------------------------
 		*/

        var parametres=$.extend(defauts, options);

		/*
		| ---------------------------
		| add overlay if is not
		| ---------------------------
		*/
		var overlay = $('

');
		if(!$("#mdl-overlay").length){
			$(overlay).appendTo('body');
		}

		/*
		| ---------------------------
		| global returned objects
		| ---------------------------
		*/
        //return this.each(function(){

			//On stocke notre élément dans une variable par commodité
			//var element=$(this);

			/*
			| ---------------------------
			| //default params
			| ---------------------------
			*/
			var fullscreen = parametres.fullscreen;
			var type = parametres.type;
			var overlayClick = parametres.overlayClick;

			/*
			| ---------------------------
			| if modal use the modal exist else create one
			| ---------------------------
			*/
			//if(type=="modal"){

			//	var cible = element.data("target");

			//}else{

				/*
				| ---------------------------
				| gestion z-index
				| ---------------------------
				*/
				var zindex = 100000+n;

				/*
				| ---------------------------
				| addmodal
				| ---------------------------
				*/
				var mymodal = $('

');

				$(mymodal).appendTo('body');

				/*
				| ---------------------------
				| ok we have our id!
				| ---------------------------
				*/
				var cible = '#mdl__' + n;
			//}

			/*
			| ---------------------------
			| confirm & prompt add buttons and result
			| ---------------------------
			*/
			if(type=="confirm" || type=="prompt"){

				/*
				| ---------------------------
				| add content
				| ---------------------------
				*/
				$(cible+" .mdl-content").html(parametres.content);

				if(type=="prompt"){
					$(cible+" .mdl-content").append("<input type='text' value='' id='response_mdl_"+ n +"' >");
				}

				/*
				| ---------------------------
				| add buttons
				| ---------------------------
				*/
				if(type=="confirm"){
					var btns = $('

No

Yes

');
					$(btns).appendTo(cible+" .mdl-container");
				}

				if(type=="prompt"){

					var btns = $('

Annuler

Valider

');
					$(btns).appendTo(cible+" .mdl-container");
				}

				/*
				| ---------------------------
				| medium format
				| ---------------------------
				*/
				$(cible+" .mdl-container").addClass("medium");

				/*
				| ---------------------------
				| on click event return response
				| ---------------------------
				*/
				$( "body" ).on( "click",cible + " .mdl-buttons a", function(event) {
					event.preventDefault();
					var response = false;

					/*
					| ---------------------------
					| return true or false for confirm
					| ---------------------------
					*/

					response = $(this).data("response");

					/*
					| ---------------------------
					| return value of input for prompt
					| ---------------------------
					*/
					if(type=="prompt"){
						var id = $(this).data("id");
						response = $("#response_mdl_"+id).val();
					}

					close(cible);

					/*
					| ---------------------------
					| return response
					| ---------------------------
					*/

					if(response){
						callback.call(this, response);
					}
					// call the callback and apply the scope:

				});

			}

			/*
			| ---------------------------
			| if fullscreen addclass fullscreen
			| ---------------------------
			*/
			if(fullscreen){		$(cible).addClass("mdl-fullscreen");	}

			/*
			| ---------------------------
			| add close button
			| ---------------------------
			*/
			$(cible).append('

');

			/*
			|
			| on click event add open class css
			|
			*/
			//element.click( function() {
				open(cible);

			//});

			/*
			|
			| on click event to close button add close class css
			|
			*/
			$( "body" ).on( "click", cible + " .mdl-close", function() {
				close(cible);
			});

			/*
			|
			| close to but by overlay click
			|
			*/
			if(overlayClick){
				$( "body" ).on( "click","#mdl-overlay", function() {

					close(cible);

				});
			}

		//});

		function open(cible) {
			$(cible).addClass("open");
			$("#mdl-overlay").addClass("active");
			setTimeout(function(){
				$(cible).addClass("animIn");
				$("#mdl-overlay").addClass("animIn");
			}, 100);
		}

		/*
		|
		| close function
		|
		*/
		function close(cible) {

						if(	$(cible).hasClass("open")	){

							$(cible).removeClass("animIn");
							$(cible).addClass("animOut");
							if(size()==1){
								$("#mdl-overlay").addClass("animOut");
								$("#mdl-overlay").removeClass("animIn");
							}

							setTimeout(function(){

								$(cible).removeClass("open");
								$(cible).removeClass("animOut");
								if(size()==0){
									$("#mdl-overlay").removeClass("animIn");
									$("#mdl-overlay").removeClass("active").removeClass("animOut");
								}

							}, 800);
						}

		}

		/*
		|
		| global size of modals
		|
		*/
		function size() {
			return $(".mdl.open").length;

		}

};

<|endoftext|>


<commit_before>'use strict';

//  ==========================================================================
//  Date getMonth
//  ==========================================================================

	// Syntax
	//dateObj.getMonth()

	// Simple
	var d = new Date();
	var n = d.getMonth();

	console.log(n);
	// return 2

	var Xmas95 = new Date('December 25');
	var month = Xmas95.getMonth();

	console.log(month);
	// return 11<commit_msg>add date getMounth<commit_after>'use strict';

//  ==========================================================================
//  Date getMonth
//  ==========================================================================

	// Syntax
	//dateObj.getMonth()

	// Simple
	var d = new Date();
	var n = d.getMonth();

	console.log(n);
	// return 2

	var Xmas95 = new Date('December 25, 1995 23:15:30');
	var month = Xmas95.getMonth();

	console.log(month);
	// return 11

	var d = new Date();
	var month = new Array();

	month[0]  = "January";
	month[1]  = "February";
	month[2]  = "March";
	month[3]  = "April";
	month[4]  = "May";
	month[5]  = "June";
	month[6]  = "July";
	month[7]  = "August";
	month[8]  = "September";
	month[9]  = "October";
	month[10] = "November";
	month[11] = "December";

	var n = month[d.getMonth()];

	console.log(n);

	console.log(d.getMonth());

	// return March

<|endoftext|>


<commit_before>var SliceDice = function(config) {
    var self = this;

    this.config = {
        sample: [],
        normalize: parseFloat,
        slices: 5,
        decimals: 0
    };
    _.assign(this.config, config);

    this.config.sample = _.map(this.config.sample, this.normalize).sort(function (x, y) {return x - y;});
    this.unique = _.unique(this.config.sample);

    this.max = d3.max(this.config.sample);
    this.min = d3.min(this.config.sample);

    var getScale = function(name) {
        var config = self.config,
            ranges = _.map(_.range(config.slices), function(v, i) {
                return {
                    index: i,
                    start: NaN,
                    end: NaN,
                    data: []
                };
            });

        switch (name) {
            case 'quantile': {
                self.scale = d3.scale.quantile().range(_.range(config.slices)).domain(config.sample);
                _.each(ranges, function(range, i) {
                    range.data = _.filter(config.sample, function(v) { return self.scale(v) == i; });
                    range.start = _.min(range.data);
                    if (i > 0) {
                        ranges[i - 1].end = range.start;
                    }
                    range.end = _.max(range.data);
                });
                return ranges;
            }
            case 'linear': {
                _.each(ranges, function(range, i) {
                    if (i == 0) {
                        range.start = self.min.toFixed(config.decimals);
                    } else {
                        range.start = ranges[i - 1].end;
                    }
                    if (i == (ranges.length - 1)) {
                        range.end = self.max.toFixed(config.decimals);
                    } else {
                        range.end = (self.min + ((self.max - self.min) / config.slices) * (i + 1)).toFixed(config.decimals);
                    }
                });
                self.scale = function(v) {
                    return _.findIndex(ranges, function (range) {
                        if (range.end == self.max && v == range.end) return true;
                        if (v >= parseFloat(range.start) && v < parseFloat(range.end)) return true;
                    });
                };
                _.each(ranges, function(range) {
                    range.data = _.filter(config.sample, function(v) {
                        return self.scale(v) == range.index;
                    });
                });
                return ranges;
            }
            case 'custom': {
                if (config.ranges === undefined) throw 'For custom scales you must provide a "ranges" parameter.';
                ranges = _.map(config.ranges, function(range, i) {
                    return {
                        index: i,
                        start: range.start,
                        end: range.end,
                        data: _.filter(config.sample, function(v) {
                                   if (range.end == self.max && v == range.end) return v;
                                   return v >= range.start && v < range.end;
                             })
                    }
                });
                self.scale = function(v) {
                    return _.findIndex(ranges, function (range) {
                        if (range.end == self.max && v == range.end) return true;
                        if (v >= range.start && v < range.end) return true;
                    });
                };
                return ranges;
            }
            case 'log': {
                throw "Log scales are unimplemented";
            }
        }

        throw "Unknown scale";
    };

    this.ranges = getScale(this.config.scale);
};

SliceDice.prototype.getRange = function(v) {
    if (v <= this.min) return this.ranges[0];
    if (v >= this.max) return _.last(this.ranges);
    return this.ranges[this.scale(v)];
};

SliceDice.prototype.getColors = function(type) {
    switch (type) {
        case 'degrade': {
            var range = _.range(this.config.slices);
            var start = arguments[1] || '#009900';
            var end = arguments[2] || '#003300';
            return _.map(range, d3.scale.linear().range([start, end]).domain([0, range.length - 1]));
        }
        default: {   // 'palette'
            return _.map(_.range(this.config.slices), d3.scale[arguments[1] || 'category20']())
        }
    }
};
<commit_msg>erro nas escalas lineares.<commit_after>var SliceDice = function(config) {
    var self = this;

    this.config = {
        sample: [],
        normalize: parseFloat,
        slices: 5,
        decimals: 0
    };
    _.assign(this.config, config);

    this.config.sample = _.map(this.config.sample, this.normalize).sort(function (x, y) {return x - y;});
    this.unique = _.unique(this.config.sample);

    this.max = d3.max(this.config.sample);
    this.min = d3.min(this.config.sample);

    var getScale = function(name) {
        var config = self.config,
            ranges = _.map(_.range(config.slices), function(v, i) {
                return {
                    index: i,
                    start: NaN,
                    end: NaN,
                    data: []
                };
            });

        switch (name) {
            case 'quantile': {
                self.scale = d3.scale.quantile().range(_.range(config.slices)).domain(config.sample);
                _.each(ranges, function(range, i) {
                    range.data = _.filter(config.sample, function(v) { return self.scale(v) == i; });
                    range.start = _.min(range.data);
                    if (i > 0) {
                        ranges[i - 1].end = range.start;
                    }
                    range.end = _.max(range.data);
                });
                return ranges;
            }
            case 'linear': {
                _.each(ranges, function(range, i) {
                    if (i == 0) {
                        range.start = self.min.toFixed(config.decimals);
                    } else {
                        range.start = ranges[i - 1].end;
                    }
                    if (i == (ranges.length - 1)) {
                        range.end = self.max.toFixed(config.decimals);
                    } else {
                        range.end = (self.min + ((self.max - self.min) / config.slices) * (i + 1)).toFixed(config.decimals);
                    }
                });
                self.scale = function(v) {
                    return _.findIndex(ranges, function (range) {
                        if (range.end == self.max && v == range.end) return true;
                        if (range.start == self.min && v == range.start) return true;
                        if (v > parseFloat(range.start) && v <= parseFloat(range.end)) return true;
                    });
                };
                _.each(ranges, function(range) {
                    range.data = _.filter(config.sample, function(v) {
                        return self.scale(v) == range.index;
                    });
                });
                return ranges;
            }
            case 'custom': {
                if (config.ranges === undefined) throw 'For custom scales you must provide a "ranges" parameter.';
                ranges = _.map(config.ranges, function(range, i) {
                    return {
                        index: i,
                        start: range.start,
                        end: range.end,
                        data: _.filter(config.sample, function(v) {
                                   if (range.end == self.max && v == range.end) return v;
                                   if (range.start == self.min && v == range.start) return v;
                                   return v > range.start && v <= range.end;
                             })
                    }
                });
                self.scale = function(v) {
                    return _.findIndex(ranges, function (range) {
                        if (range.end == self.max && v == range.end) return true;
                        if (range.start == self.min && v == range.start) return true;
                        if (v > range.start && v <= range.end) return true;
                    });
                };
                return ranges;
            }
            case 'log': {
                throw "Log scales are unimplemented";
            }
        }

        throw "Unknown scale";
    };

    this.ranges = getScale(this.config.scale);
};

SliceDice.prototype.getRange = function(v) {
    if (v <= this.min) return this.ranges[0];
    if (v >= this.max) return _.last(this.ranges);
    return this.ranges[this.scale(v)];
};

SliceDice.prototype.getColors = function(type) {
    switch (type) {
        case 'degrade': {
            var range = _.range(this.config.slices);
            var start = arguments[1] || '#009900';
            var end = arguments[2] || '#003300';
            return _.map(range, d3.scale.linear().range([start, end]).domain([0, range.length - 1]));
        }
        default: {   // 'palette'
            return _.map(_.range(this.config.slices), d3.scale[arguments[1] || 'category20']())
        }
    }
};
<|endoftext|>


<commit_before>/*!
 * Escaper
 * https://github.com/kobezzza/Escaper
 *
 * Released under the MIT license
 * https://github.com/kobezzza/Escaper/blob/master/LICENSE
 */

describe('Escaper', function () {
	it('should works with " ... "', function () {
		var str = Escaper.replace('Hello "friend\\\""!');

		expect(str)
			.toBe('Hello __ESCAPER_QUOT__0_!');

		expect(Escaper.paste(str))
			.toBe('Hello "friend\\\""!');

		var str2 = Escaper.replace('Hello "friend\\\""!');

		expect(str2)
			.toBe('Hello __ESCAPER_QUOT__0_!');

		expect(Escaper.paste(str2))
			.toBe('Hello "friend\\\""!');

		var stack = [];
		var str3 = Escaper.replace('Hello "friend\\\""!', false, stack);

		expect(str3)
			.toBe('Hello __ESCAPER_QUOT__0_!');

		expect(Escaper.paste(str3, stack))
			.toBe('Hello "friend\\\""!');

		stack = [];
		var str4 = Escaper.replace('Hello "friend\\\""!', {'"': -1}, stack);

		expect(str4)
			.toBe('Hello !');

		expect(Escaper.paste(str4, stack))
			.toBe('Hello !');
	});

	it("should works with ' ... '", function () {
		var str = Escaper.replace("Hello 'friend\\\''!");

		expect(str)
			.toBe('Hello __ESCAPER_QUOT__1_!');

		expect(Escaper.paste(str))
			.toBe("Hello 'friend\\\''!");

		var stack = [];
		var str2 = Escaper.replace("Hello 'friend\\\''!", false, stack);

		expect(str2)
			.toBe('Hello __ESCAPER_QUOT__0_!');

		expect(Escaper.paste(str2, stack))
			.toBe("Hello 'friend\\\''!");
	});

	it('should works with ` ... `', function () {
		var stack = [];
		var str = Escaper.replace('Hello `friend`!', false, stack);

		expect(str)
			.toBe('Hello __ESCAPER_QUOT__0_!');

		expect(Escaper.paste(str, stack))
			.toBe("Hello `friend`!");

		var str2 = Escaper.replace('Hello `friend${1 + {foo: {}} + `foo` + /1/}`!', false, stack);

		expect(str2)
			.toBe('Hello __ESCAPER_QUOT__1_1 + {foo: {}} + __ESCAPER_QUOT__2_ + __ESCAPER_QUOT__3___ESCAPER_QUOT__4_!');

		expect(Escaper.paste(str2, stack))
			.toBe("Hello `friend${1 + {foo: {}} + `foo` + /1/}`!");

		var str3 = Escaper.replace('Hello `friend\\${foo}`!', false, stack);

		expect(str3)
			.toBe('Hello __ESCAPER_QUOT__5_!');

		expect(Escaper.paste(str3, stack))
			.toBe('Hello `friend\\${foo}`!');

		var str4 = Escaper.replace('Hello `friend${foo/* fooo */}`!', true, stack);

		expect(str4)
			.toBe('Hello __ESCAPER_QUOT__6_foo__ESCAPER_QUOT__7___ESCAPER_QUOT__8_!');

		expect(Escaper.paste(str4, stack))
			.toBe('Hello `friend${foo/* fooo */}`!');
	});

	it("should works with / ... /", function () {
		var stack = [];
		var str = Escaper.replace("Hello + /friend\\//gmi!", false, stack);

		expect(str)
			.toBe('Hello + __ESCAPER_QUOT__0_!');

		expect(Escaper.paste(str, stack))
			.toBe('Hello + /friend\\//gmi!');

		var str2 = Escaper.replace("Hello, /friend\\/[//.]/gmi!", false, stack);

		expect(str2)
			.toBe('Hello, __ESCAPER_QUOT__1_!');

		expect(Escaper.paste(str2, stack))
			.toBe('Hello, /friend\\/[//.]/gmi!');

		var str3 = Escaper.replace('/friend\\/[//.]/gmi!, /friend\\/[//.]/gmi', false, stack);

		expect(str3)
			.toBe('__ESCAPER_QUOT__2_!, __ESCAPER_QUOT__3_');

		expect(Escaper.paste(str3, stack))
			.toBe('/friend\\/[//.]/gmi!, /friend\\/[//.]/gmi');
	});

	it("should works with / ... / (advanced test)", function () {
		var stack = [];
		var str = Escaper.replace('2 >> /foo/ < /bar/ ^ /car/ [/bar/] foo typeof /mu/ /mu/', true, stack);

		expect(str)
			.toBe('2 >> __ESCAPER_QUOT__0_ < __ESCAPER_QUOT__1_ ^ __ESCAPER_QUOT__2_ [__ESCAPER_QUOT__3_] foo typeof __ESCAPER_QUOT__4_ /mu/');

		expect(Escaper.paste(str, stack))
			.toBe('2 >> /foo/ < /bar/ ^ /car/ [/bar/] foo typeof /mu/ /mu/');
	});

	it("should works with single-line comments", function () {
		var stack = [];
		var str = Escaper.replace(
			("Hello // the comment\
\n			Friend!"), true, stack);

		expect(str)
			.toBe('Hello __ESCAPER_QUOT__0_\n\t\t\tFriend!');

		expect(Escaper.paste(str, stack))
			.toBe('Hello // the comment\n\t\t\tFriend!');
	});

	it("should works with //!", function () {
		var stack = [];
		var str = Escaper.replace(
			("Hello // the comment //! fffuuu\
\n//! fffuuuu\
\n			Friend!"), {'//!': true}, stack);

		expect(str)
			.toBe('Hello // the comment //! fffuuu\n__ESCAPER_QUOT__0_\n\t\t\tFriend!');

		expect(Escaper.paste(str, stack))
			.toBe('Hello // the comment //! fffuuu\n//! fffuuuu\n\t\t\tFriend!');
	});

	it("should works with multiline comments", function () {
		var stack = [];
		var str = Escaper.replace('Hello /*/ the comment */ Friend!', true, stack);

		expect(str)
			.toBe('Hello __ESCAPER_QUOT__0_ Friend!');

		expect(Escaper.paste(str, stack))
			.toBe('Hello /*/ the comment */ Friend!');
	});

	it("should works with Snakeskin", function () {
		var stack = [];
		var str = Escaper.replace('foo|replace /hello/g|join "world"', true, stack, true);

		expect(str)
			.toBe('foo|replace __ESCAPER_QUOT__0_|join __ESCAPER_QUOT__1_');

		expect(Escaper.paste(str, stack))
			.toBe('foo|replace /hello/g|join "world"');
	});

	it("should works with custom parameters", function () {
		var stack = [];
		var str = Escaper.replace('"Hello" /* the comment */ + /Friend/gim /** foo */!', {'"': true, '/': true, '/*': true}, stack);

		expect(str)
			.toBe('__ESCAPER_QUOT__0_ __ESCAPER_QUOT__1_ + __ESCAPER_QUOT__2_ /** foo */!');

		expect(Escaper.paste(str, stack))
			.toBe('"Hello" /* the comment */ + /Friend/gim /** foo */!');
	});

	it("should works with deep literals", function () {
		var stack = [];
		var str = Escaper.replace('"Hello" /** "foo" */', {'"': true}, stack);

		expect(str)
			.toBe('__ESCAPER_QUOT__0_ /** "foo" */');

		expect(Escaper.paste(str, stack))
			.toBe('"Hello" /** "foo" */');
	});

	it("should works with @all", function () {
		var stack = [];
		var str = Escaper.replace('"Hello" /* the comment */ + /Friend/gim /** foo */!', {'@all': true, '/*': -1}, stack);

		expect(str)
			.toBe('__ESCAPER_QUOT__0_  + __ESCAPER_QUOT__1_ __ESCAPER_QUOT__2_!');

		expect(Escaper.paste(str, stack))
			.toBe('"Hello"  + /Friend/gim /** foo */!');
	});

	it("should works with @comments", function () {
		var stack = [];
		var str = Escaper.replace('"Hello" /* the comment */ + /Friend/gim /** foo */!', {'@comments': -1}, stack);

		expect(str)
			.toBe('"Hello"  + /Friend/gim !');

		expect(Escaper.paste(str, stack))
			.toBe('"Hello"  + /Friend/gim !');
	});

	it("should works with @comments, @literals and @all", function () {
		var stack = [];
		var str = Escaper.replace('"Hello" /* the comment */ + /Friend/gim /** foo */!', {'@all': -1, '@comments': false, '@literals': true}, stack);

		expect(str)
			.toBe('__ESCAPER_QUOT__0_ /* the comment */ + __ESCAPER_QUOT__1_ /** foo */!');

		expect(Escaper.paste(str, stack))
			.toBe('"Hello" /* the comment */ + /Friend/gim /** foo */!');
	});
});
<commit_msg>:art:<commit_after>/*!
 * Escaper
 * https://github.com/kobezzza/Escaper
 *
 * Released under the MIT license
 * https://github.com/kobezzza/Escaper/blob/master/LICENSE
 */

describe('Escaper', function () {
	it('should work with " ... "', function () {
		var str = Escaper.replace('Hello "friend\\\""!');

		expect(str)
			.toBe('Hello __ESCAPER_QUOT__0_!');

		expect(Escaper.paste(str))
			.toBe('Hello "friend\\\""!');

		var str2 = Escaper.replace('Hello "friend\\\""!');

		expect(str2)
			.toBe('Hello __ESCAPER_QUOT__0_!');

		expect(Escaper.paste(str2))
			.toBe('Hello "friend\\\""!');

		var stack = [];
		var str3 = Escaper.replace('Hello "friend\\\""!', false, stack);

		expect(str3)
			.toBe('Hello __ESCAPER_QUOT__0_!');

		expect(Escaper.paste(str3, stack))
			.toBe('Hello "friend\\\""!');

		stack = [];
		var str4 = Escaper.replace('Hello "friend\\\""!', {'"': -1}, stack);

		expect(str4)
			.toBe('Hello !');

		expect(Escaper.paste(str4, stack))
			.toBe('Hello !');
	});

	it("should work with ' ... '", function () {
		var str = Escaper.replace("Hello 'friend\\\''!");

		expect(str)
			.toBe('Hello __ESCAPER_QUOT__1_!');

		expect(Escaper.paste(str))
			.toBe("Hello 'friend\\\''!");

		var stack = [];
		var str2 = Escaper.replace("Hello 'friend\\\''!", false, stack);

		expect(str2)
			.toBe('Hello __ESCAPER_QUOT__0_!');

		expect(Escaper.paste(str2, stack))
			.toBe("Hello 'friend\\\''!");
	});

	it('should work with ` ... `', function () {
		var stack = [];
		var str = Escaper.replace('Hello `friend`!', false, stack);

		expect(str)
			.toBe('Hello __ESCAPER_QUOT__0_!');

		expect(Escaper.paste(str, stack))
			.toBe("Hello `friend`!");

		var str2 = Escaper.replace('Hello `friend${1 + {foo: {}} + `foo` + /1/}`!', false, stack);

		expect(str2)
			.toBe('Hello __ESCAPER_QUOT__1_1 + {foo: {}} + __ESCAPER_QUOT__2_ + __ESCAPER_QUOT__3___ESCAPER_QUOT__4_!');

		expect(Escaper.paste(str2, stack))
			.toBe("Hello `friend${1 + {foo: {}} + `foo` + /1/}`!");

		var str3 = Escaper.replace('Hello `friend\\${foo}`!', false, stack);

		expect(str3)
			.toBe('Hello __ESCAPER_QUOT__5_!');

		expect(Escaper.paste(str3, stack))
			.toBe('Hello `friend\\${foo}`!');

		var str4 = Escaper.replace('Hello `friend${foo/* fooo */}`!', true, stack);

		expect(str4)
			.toBe('Hello __ESCAPER_QUOT__6_foo__ESCAPER_QUOT__7___ESCAPER_QUOT__8_!');

		expect(Escaper.paste(str4, stack))
			.toBe('Hello `friend${foo/* fooo */}`!');
	});

	it("should work with / ... /", function () {
		var stack = [];
		var str = Escaper.replace("Hello + /friend\\//gmi!", false, stack);

		expect(str)
			.toBe('Hello + __ESCAPER_QUOT__0_!');

		expect(Escaper.paste(str, stack))
			.toBe('Hello + /friend\\//gmi!');

		var str2 = Escaper.replace("Hello, /friend\\/[//.]/gmi!", false, stack);

		expect(str2)
			.toBe('Hello, __ESCAPER_QUOT__1_!');

		expect(Escaper.paste(str2, stack))
			.toBe('Hello, /friend\\/[//.]/gmi!');

		var str3 = Escaper.replace('/friend\\/[//.]/gmi!, /friend\\/[//.]/gmi', false, stack);

		expect(str3)
			.toBe('__ESCAPER_QUOT__2_!, __ESCAPER_QUOT__3_');

		expect(Escaper.paste(str3, stack))
			.toBe('/friend\\/[//.]/gmi!, /friend\\/[//.]/gmi');
	});

	it("should work with / ... / (advanced test)", function () {
		var stack = [];
		var str = Escaper.replace('2 >> /foo/ < /bar/ ^ /car/ [/bar/] foo typeof /mu/ /mu/', true, stack);

		expect(str)
			.toBe('2 >> __ESCAPER_QUOT__0_ < __ESCAPER_QUOT__1_ ^ __ESCAPER_QUOT__2_ [__ESCAPER_QUOT__3_] foo typeof __ESCAPER_QUOT__4_ /mu/');

		expect(Escaper.paste(str, stack))
			.toBe('2 >> /foo/ < /bar/ ^ /car/ [/bar/] foo typeof /mu/ /mu/');
	});

	it("should work with single-line comments", function () {
		var stack = [];
		var str = Escaper.replace(
			("Hello // the comment\
\n			Friend!"), true, stack);

		expect(str)
			.toBe('Hello __ESCAPER_QUOT__0_\n\t\t\tFriend!');

		expect(Escaper.paste(str, stack))
			.toBe('Hello // the comment\n\t\t\tFriend!');
	});

	it("should work with //!", function () {
		var stack = [];
		var str = Escaper.replace(
			("Hello // the comment //! fffuuu\
\n//! fffuuuu\
\n			Friend!"), {'//!': true}, stack);

		expect(str)
			.toBe('Hello // the comment //! fffuuu\n__ESCAPER_QUOT__0_\n\t\t\tFriend!');

		expect(Escaper.paste(str, stack))
			.toBe('Hello // the comment //! fffuuu\n//! fffuuuu\n\t\t\tFriend!');
	});

	it("should work with multiline comments", function () {
		var stack = [];
		var str = Escaper.replace('Hello /*/ the comment */ Friend!', true, stack);

		expect(str)
			.toBe('Hello __ESCAPER_QUOT__0_ Friend!');

		expect(Escaper.paste(str, stack))
			.toBe('Hello /*/ the comment */ Friend!');
	});

	it("should work with Snakeskin", function () {
		var stack = [];
		var str = Escaper.replace('foo|replace /hello/g|join "world"', true, stack, true);

		expect(str)
			.toBe('foo|replace __ESCAPER_QUOT__0_|join __ESCAPER_QUOT__1_');

		expect(Escaper.paste(str, stack))
			.toBe('foo|replace /hello/g|join "world"');
	});

	it("should work with custom parameters", function () {
		var stack = [];
		var str = Escaper.replace('"Hello" /* the comment */ + /Friend/gim /** foo */!', {
			'"': true,
			'/': true,
			'/*': true
		}, stack);

		expect(str)
			.toBe('__ESCAPER_QUOT__0_ __ESCAPER_QUOT__1_ + __ESCAPER_QUOT__2_ /** foo */!');

		expect(Escaper.paste(str, stack))
			.toBe('"Hello" /* the comment */ + /Friend/gim /** foo */!');
	});

	it("should work with deep literals", function () {
		var stack = [];
		var str = Escaper.replace('"Hello" /** "foo" */', {'"': true}, stack);

		expect(str)
			.toBe('__ESCAPER_QUOT__0_ /** "foo" */');

		expect(Escaper.paste(str, stack))
			.toBe('"Hello" /** "foo" */');
	});

	it("should work with @all", function () {
		var stack = [];
		var str = Escaper.replace('"Hello" /* the comment */ + /Friend/gim /** foo */!', {'@all': true, '/*': -1}, stack);

		expect(str)
			.toBe('__ESCAPER_QUOT__0_  + __ESCAPER_QUOT__1_ __ESCAPER_QUOT__2_!');

		expect(Escaper.paste(str, stack))
			.toBe('"Hello"  + /Friend/gim /** foo */!');
	});

	it("should work with @comments", function () {
		var stack = [];
		var str = Escaper.replace('"Hello" /* the comment */ + /Friend/gim /** foo */!', {'@comments': -1}, stack);

		expect(str)
			.toBe('"Hello"  + /Friend/gim !');

		expect(Escaper.paste(str, stack))
			.toBe('"Hello"  + /Friend/gim !');
	});

	it("should work with @comments, @literals and @all", function () {
		var stack = [];
		var str = Escaper.replace('"Hello" /* the comment */ + /Friend/gim /** foo */!', {
			'@all': -1,
			'@comments': false,
			'@literals': true
		}, stack);

		expect(str)
			.toBe('__ESCAPER_QUOT__0_ /* the comment */ + __ESCAPER_QUOT__1_ /** foo */!');

		expect(Escaper.paste(str, stack))
			.toBe('"Hello" /* the comment */ + /Friend/gim /** foo */!');
	});
});
<|endoftext|>


<commit_before>'use strict';

/*
 global window,
 document
 */

/**
 * Wrapper class for localStorage
 */
class Borage {

  /**
   * Retrieves an existing or creates a new localStorage handle using a unique ID.
   * This ID will be prepended to all keys
   *
   * @param {string} uniqueStorageId unique ID to identify app storage keys by
   */
  constructor (uniqueStorageId) {
    this._uniqueStorageId = uniqueStorageId;

    if (typeof window.localStorage.getItem(uniqueStorageId) === 'undefined') {
      window.localStorage.setItem(uniqueStorageId, {});
    }
  }

  /**
   * checks if the key exists in storage
   *
   * @param   {string}  key item to check
   * @returns {boolean}     whether the key exists
   */
  has (key) {
    return window.localStorage.hasOwnProperty(`${this._uniqueStorageId}:${key}`);
  }

  /**
   * retrieves a key from storage. optionally returns a fallback value, if given.
   *
   * @param   {string} key        item to retrieve
   * @param   {*}      [fallback] optional fallback value if the key does not exist
   * @returns {*}                 stored item value or fallback value
   */
  get (key, fallback = undefined) {

    // check if the key exists at all
    if (this.has(key)) {

      // if the key ends in an asterisk, a wildcard key is requested
      if (key.slice(-1) === '*') {

        // so we fetch the index key and additionally its content: keys within the given index
        return JSON.parse(window.localStorage.getItem(`${this._uniqueStorageId}:${key}`))
          .map(subKey => JSON.parse(window.localStorage.getItem(`${this._uniqueStorageId}:${subKey}`)));
      }

      // this is a normal key, so just fetch its value
      return JSON.parse(window.localStorage.getItem(`${this._uniqueStorageId}:${key}`));
    }

    // nothing found, return the fallback value if given
    return fallback;
  }

  /**
   * sets an item to storage
   *
   * @param {string} key   item to set
   * @param {*}      value item value to set. Will be stored as JSON
   */
  set (key, value) {
    if (key.slice(-1) === '*') {
      throw new TypeError('invalid key format: keys may not end in an asterisk')
    }

    Borage._updateIndexKey(`${this._uniqueStorageId}`, key);

    // split the key on ":" signs and create a wildcard entry (*) for all subkeys. That serves
    // as a kind of index for all stored keys:
    // For example, 'app:config:templates:my-navigation-template' will be split into
    // 'app', 'config' and 'templates'. The last key is sliced since it holds a value, not
    // further subkeys.
    // Then, 'app:*', 'app:config:*' and 'app:config:templates:*' are created and the current
    // key is appended to them.
    key.split(':').slice(0, -1).reduce((previous, current) => {
      Borage._updateIndexKey(`${previous}:${current}`, key);

      return previous + ':' + current;
    }, this._uniqueStorageId);

    window.localStorage.setItem(`${this._uniqueStorageId}:${key}`, JSON.stringify(value));
  }

  /**
   * removes a key from storage
   *
   * @param {string} key item to remove
   */
  remove (key) {

    // remove the key itself
    window.localStorage.removeItem(`${this._uniqueStorageId}:${key}`);

    // remove the key from the global index
    Borage._removeIndexKey(this._uniqueStorageId, key);

    // remove the key from all indexes
    key.split(':').reduce((previous, current) => {
      Borage._removeIndexKey(`${previous}:${current}`, key);

      return `${previous}:${current}`;
    }, this._uniqueStorageId);
  }

  /**
   * clears either the whole storage or all subkeys of a specific index.
   * if an index is given, all subkeys will be deleted
   *
   * @example storage.clear('app:config') will delete all keys starting with 'app:config:'
   *
   * @param {string} [index] index to clear. if omitted, will clear the whole storage
   */
  clear (index) {
    if (index) {
      return Borage._getIndex(index).forEach(key => this.remove(key));
    }

    return window.localStorage.clear();
  }

  static _updateIndexKey (index, key) {
    let indexKeys = Borage._getIndex(index);

    indexKeys.push(key);
    window.localStorage.setItem(`${index}:*`, JSON.stringify(Array.from(new Set(indexKeys))));
  }

  /**
   * retrieves a specific index key
   *
   * @param   {string} key index key to retrieve
   * @returns {Array}      array containing all found item keys, not the items themselves
   * @private
   */
  static _getIndex (key) {
    return JSON.parse(window.localStorage.getItem(`${key}:*`)) || [];
  }

  static _setIndex (index, keys) {
    window.localStorage.setItem(`${index}:*`, JSON.stringify(Array.from(new Set(keys))));
  }

  /**
   * removes a key from an index
   *
   * @param {string} index
   * @param {string} key
   * @private
   */
  static _removeIndexKey (index, key) {
    let indexKeys   = Borage._getIndex(index),
        keyPosition = indexKeys.indexOf(key);

    if (keyPosition > -1) {
      indexKeys.splice(keyPosition, 1);
      Borage._setIndex(index, indexKeys);
    }
  }

  get length () {
    return this.get('*').length;
  }

  get [Symbol.iterator] () {
    return this.get('*')[ Symbol.iterator ];
  }
}

export default Borage;
<commit_msg>Updated code formatting<commit_after>'use strict';

/*
 global window,
 document
 */

/**
 * Wrapper class for localStorage
 */
class Borage {

  /**
   * Retrieves an existing or creates a new localStorage handle using a unique ID.
   * This ID will be prepended to all keys
   *
   * @param {string} uniqueStorageId unique ID to identify app storage keys by
   */
  constructor(uniqueStorageId) {
    this._uniqueStorageId = uniqueStorageId;

    if (typeof window.localStorage.getItem(uniqueStorageId) === 'undefined') {
      window.localStorage.setItem(uniqueStorageId, {});
    }
  }

  /**
   * checks if the key exists in storage
   *
   * @param   {string}  key item to check
   * @returns {boolean}     whether the key exists
   */
  has(key) {
    return window.localStorage.hasOwnProperty(`${this._uniqueStorageId}:${key}`);
  }

  /**
   * retrieves a key from storage. optionally returns a fallback value, if given.
   *
   * @param   {string} key        item to retrieve
   * @param   {*}      [fallback] optional fallback value if the key does not exist
   * @returns {*}                 stored item value or fallback value
   */
  get(key, fallback = undefined) {

    // check if the key exists at all
    if (this.has(key)) {

      // if the key ends in an asterisk, a wildcard key is requested
      if (key.slice(- 1) === '*') {

        // so we fetch the index key and additionally its content: keys within the given index
        return JSON.parse(window.localStorage.getItem(`${this._uniqueStorageId}:${key}`))
            .map(subKey => JSON.parse(window.localStorage.getItem(`${this._uniqueStorageId}:${subKey}`)));
      }

      // this is a normal key, so just fetch its value
      return JSON.parse(window.localStorage.getItem(`${this._uniqueStorageId}:${key}`));
    }

    // nothing found, return the fallback value if given
    return fallback;
  }

  /**
   * sets an item to storage
   *
   * @param {string} key   item to set
   * @param {*}      value item value to set. Will be stored as JSON
   */
  set(key, value) {
    if (key.slice(- 1) === '*') {
      throw new TypeError('invalid key format: keys may not end in an asterisk')
    }

    Borage._updateIndexKey(`${this._uniqueStorageId}`, key);

    // split the key on ":" signs and create a wildcard entry (*) for all subkeys. That serves
    // as a kind of index for all stored keys:
    // For example, 'app:config:templates:my-navigation-template' will be split into
    // 'app', 'config' and 'templates'. The last key is sliced since it holds a value, not
    // further subkeys.
    // Then, 'app:*', 'app:config:*' and 'app:config:templates:*' are created and the current
    // key is appended to them.
    key.split(':').slice(0, - 1).reduce((previous, current) => {
      Borage._updateIndexKey(`${previous}:${current}`, key);

      return previous + ':' + current;
    }, this._uniqueStorageId);

    window.localStorage.setItem(`${this._uniqueStorageId}:${key}`, JSON.stringify(value));
  }

  /**
   * removes a key from storage
   *
   * @param {string} key item to remove
   */
  remove(key) {

    // remove the key itself
    window.localStorage.removeItem(`${this._uniqueStorageId}:${key}`);

    // remove the key from the global index
    Borage._removeIndexKey(this._uniqueStorageId, key);

    // remove the key from all indexes
    key.split(':').reduce((previous, current) => {
      Borage._removeIndexKey(`${previous}:${current}`, key);

      return `${previous}:${current}`;
    }, this._uniqueStorageId);
  }

  /**
   * clears either the whole storage or all subkeys of a specific index.
   * if an index is given, all subkeys will be deleted
   *
   * @example storage.clear('app:config') will delete all keys starting with 'app:config:'
   *
   * @param {string} [index] index to clear. if omitted, will clear the whole storage
   */
  clear(index) {
    if (index) {
      return Borage._getIndex(index).forEach(key => this.remove(key));
    }

    return window.localStorage.clear();
  }

  static _updateIndexKey(index, key) {
    let indexKeys = Borage._getIndex(index);

    indexKeys.push(key);
    window.localStorage.setItem(`${index}:*`, JSON.stringify(Array.from(new Set(indexKeys))));
  }

  /**
   * retrieves a specific index key
   *
   * @param   {string} key index key to retrieve
   * @returns {Array}      array containing all found item keys, not the items themselves
   * @private
   */
  static _getIndex(key) {
    return JSON.parse(window.localStorage.getItem(`${key}:*`)) || [];
  }

  static _setIndex(index, keys) {
    window.localStorage.setItem(`${index}:*`, JSON.stringify(Array.from(new Set(keys))));
  }

  /**
   * removes a key from an index
   *
   * @param {string} index
   * @param {string} key
   * @private
   */
  static _removeIndexKey(index, key) {
    let indexKeys   = Borage._getIndex(index),
        keyPosition = indexKeys.indexOf(key);

    if (keyPosition > - 1) {
      indexKeys.splice(keyPosition, 1);
      Borage._setIndex(index, indexKeys);
    }
  }

  get length() {
    return this.get('*').length;
  }

  get [Symbol.iterator]() {
    return this.get('*')[ Symbol.iterator ];
  }
}

export default Borage;
<|endoftext|>


<commit_before>/**
 * CSSS javascript code
 * @author Lea Verou (http://leaverou.me)
 * @version 1.0
 */

(function(){
// Cache <title> element, we may need it for slides that don't have titles
var documentTitle = document.getElementsByTagName('title')[0].textContent;

window.SlideShow = function(container, slide) {
	var me = this;

	container = container || document.body;

	// Current slide
	this.slide = slide || 0;

	// Current .delayed item in the slide
	this.item = 0;

	// Get the slide elements into an array
	this.slides = Array.prototype.slice.apply(container.querySelectorAll('.slide'));

	for(var i=0; i<this.slides.length; i++) {
		var slide = this.slides[i]; // to speed up references

		// Asign ids to slides that don't have one
		if(!slide.id) {
			slide.id = 'slide' + (i+1);
		}

		// Set data-title attribute to the title of the slide
		if(!slide.title) {
			// no title attribute, fetch title from heading(s)
			var heading = slide.querySelector('hgroup') || slide.querySelector('h1,h2,h3,h4,h5,h6');

			if(heading && heading.textContent.trim()) {
				slide.setAttribute('data-title', heading.textContent);
			}
		}
		else {
			// The title attribute is set, use that
			slide.setAttribute('data-title', slide.title);
			slide.removeAttribute('title');
		}
	}

	// If there's already a hash, update current slide number...
	this.goto(location.hash.substr(1) || 0);

	// ...and keep doing so every time the hash changes
	this.onhashchange = function() {
		me.goto(location.hash.substr(1) || 0);
	};
	window.addEventListener('hashchange', this.onhashchange, false);

	// Adjust the font-size when the window is resized
	window.addEventListener('resize', function() {
		me.adjustFontSize();
	}, false);

	// In some browsers DOMContentLoaded is too early, so try again onload
	window.addEventListener('load', function() {
		me.adjustFontSize();
	}, false);

	/**
		Keyboard navigation
		Home : First slide
		End : Last slide
		Up/Right arrow : Next item/slide
		Ctrl + Up/Right arrow : Next slide
		Down/Left arrow : Previous item/slide
		Ctrl + Down/Left arrow : Previous slide
		Ctrl+G : Go to slide...
		Ctrl+H : Show thumbnails and go to slide
		(Shift instead of Ctrl works too)
	*/
	document.addEventListener('keyup', function(evt) {
		if(evt.ctrlKey || evt.shiftKey) {
			switch(evt.keyCode) {
				case 71:
					var slide = prompt('Which slide?');
					me.goto(+slide? slide - 1 : slide);
					break;
				case 72:
					if(document.body.classList.contains('show-thumbnails')) {
						document.body.classList.remove('show-thumbnails');
					}
					else {
						document.body.classList.add('show-thumbnails');

						document.body.addEventListener('click', function(evt) {
							var slide = evt.target;

							while(slide && !slide.classList.contains('slide')) {
								slide = slide.parentNode;
							}

							if(slide) {
								me.goto(slide.id);
								setTimeout(function() { me.adjustFontSize(); }, 1000); // for Opera
							}

							document.body.classList.remove('show-thumbnails');
						}, false);
					}
			}
		}

		if(evt.target === document.body || evt.target === document.body.parentNode) {
			if(evt.keyCode >= 35 && evt.keyCode <= 40) {
				evt.preventDefault();
			}

			switch(evt.keyCode) {
				case 35: // end
					me.end();
					break;
				case 36: // home
					me.start();
					break;
				case 37: // <-
				case 38: // up arrow
					me.previous(evt.ctrlKey || evt.shiftKey);
					break;
				case 39: // ->
				case 40: // down arrow
					me.next(evt.ctrlKey || evt.shiftKey);
					break;
			}
		}
	}, false);
}

SlideShow.prototype = {
	start: function() {
		this.goto(0);
	},

	end: function() {
		this.goto(this.slides.length - 1);
	},

	/**
		@param hard {Boolean} Whether to advance to the next slide (true) or
			just the next step (which could very well be showing a list item)
	 */
	next: function(hard) {
		if(!hard && this.items.length) {
			// If there's no current, then just mark the first one as such
			if(!this.item) {
				this.items[this.item++].classList.add('current');
			}
			// Add .current to current item if it exists, otherwise advance to next slide
			else if(this.item < this.items.length) {
				classes = this.items[this.item - 1].classList; // to speed up lookups

				classes.remove('current');
				classes.add('displayed');

				this.items[this.item++].classList.add('current');
			}
			else {
				this.item = 0;
				this.next(true);
			}
		}
		else {
			this.goto(this.slide + 1);

			this.item = 0;

			// Mark all items as not displayed, if there are any
			if(this.items.length) {
				for (var i=0; i<this.items.length; i++) {
					if(this.items[i].classList) {
						this.items[i].classList.remove('displayed');
						this.items[i].classList.remove('current');
					}
				}
			}
		}
	},

	previous: function(hard) {
		if(!hard && this.item > 0) {
			var classes = this.items[this.item - 1].classList; // to speed up lookups

			classes.remove('current');

			if(this.item > 1) {
				classes = this.items[--this.item - 1].classList;

				classes.remove('displayed');
				classes.add('current');
			}
			else {
				this.item = 0;
			}
		}
		else {

			this.goto(this.slide - 1);

			this.item = this.items.length;

			// Mark all items as displayed, if there are any
			if(this.items.length) {
				for (var i=0; i<this.items.length; i++) {
					if(this.items[i].classList) {
						this.items[i].classList.add('displayed');
					}
				}

				// Mark the last one as current
				var lastItem = this.items[this.items.length - 1];

				lastItem.classList.remove('displayed');
				lastItem.classList.add('current');
			}
		}
	},

	/**
		Go to an aribtary slide
		@param which {String|Integer} Which slide (identifier or slide number)
	*/
	goto: function(which) {
		var slide;

		// We have to remove it to prevent multiple calls to goto messing up
		// our current item (and there's no point either, so we save on performance)
		window.removeEventListener('hashchange', this.onhashchange, false);

		if(which + 0 === which && which in this.slides) { // Argument is a valid slide number
			this.slide = which;

			slide = this.slides[this.slide];
			location.hash = '#' + slide.id;
		}
		else if(which + '' === which) { // Argument is a slide id
			slide = document.getElementById(which);

			if(slide) {
				this.slide = this.slides.indexOf(slide);
				location.hash = '#' + which;
			}
		}

		if(slide) { // Slide actually changed, perform any other tasks needed
			document.title = slide.getAttribute('data-title') || documentTitle;

			this.adjustFontSize();

			// Update items collection
			this.items = this.slides[this.slide].querySelectorAll('.delayed');
			this.item = 0;
		}

		// If you attach the listener immediately again then it will catch the event
		// We have to do it asynchronously
		var me = this;
		setTimeout(function() {
			window.addEventListener('hashchange', me.onhashchange, false);
		}, 1000);
	},

	adjustFontSize: function() {
		// Cache long lookup chains, for performance
		var bodyStyle = document.body.style,
			scrollRoot = document[document.documentElement.scrollHeight? 'documentElement' : 'body'],
			innerHeight = window.innerHeight,
			innerWidth = window.innerWidth;

		// Clear previous styles
		bodyStyle.fontSize = '';

		if(document.body.classList.contains('show-thumbnails')) {
			return;
		}

		for(
			var percent = 100;
			(scrollRoot.scrollHeight > innerHeight || scrollRoot.scrollWidth > innerWidth) && percent >= 35;
			percent-=5
		) {
			bodyStyle.fontSize = percent + '%';
		}

		// Individual slide
		var slide = this.slides[this.slide];

		if(slide.clientHeight && slide.clientWidth) {
			// Strange FF bug: scrollHeight doesn't work properly with overflow:hidden
			slide.style.overflow = 'auto';

			for(
				;
				(slide.scrollHeight > slide.clientHeight || slide.scrollWidth > slide.clientWidth) && percent >= 35;
				percent--
			) {
				bodyStyle.fontSize = percent + '%';
			}

			slide.style.overflow = '';
		}
	}
};

})();<commit_msg>If the slide has the class "dont-resize" then don’t do anything<commit_after>/**
 * CSSS javascript code
 * @author Lea Verou (http://leaverou.me)
 * @version 1.0
 */

(function(){
// Cache <title> element, we may need it for slides that don't have titles
var documentTitle = document.getElementsByTagName('title')[0].textContent;

window.SlideShow = function(container, slide) {
	var me = this;

	container = container || document.body;

	// Current slide
	this.slide = slide || 0;

	// Current .delayed item in the slide
	this.item = 0;

	// Get the slide elements into an array
	this.slides = Array.prototype.slice.apply(container.querySelectorAll('.slide'));

	for(var i=0; i<this.slides.length; i++) {
		var slide = this.slides[i]; // to speed up references

		// Asign ids to slides that don't have one
		if(!slide.id) {
			slide.id = 'slide' + (i+1);
		}

		// Set data-title attribute to the title of the slide
		if(!slide.title) {
			// no title attribute, fetch title from heading(s)
			var heading = slide.querySelector('hgroup') || slide.querySelector('h1,h2,h3,h4,h5,h6');

			if(heading && heading.textContent.trim()) {
				slide.setAttribute('data-title', heading.textContent);
			}
		}
		else {
			// The title attribute is set, use that
			slide.setAttribute('data-title', slide.title);
			slide.removeAttribute('title');
		}
	}

	// If there's already a hash, update current slide number...
	this.goto(location.hash.substr(1) || 0);

	// ...and keep doing so every time the hash changes
	this.onhashchange = function() {
		me.goto(location.hash.substr(1) || 0);
	};
	window.addEventListener('hashchange', this.onhashchange, false);

	// Adjust the font-size when the window is resized
	window.addEventListener('resize', function() {
		me.adjustFontSize();
	}, false);

	// In some browsers DOMContentLoaded is too early, so try again onload
	window.addEventListener('load', function() {
		me.adjustFontSize();
	}, false);

	/**
		Keyboard navigation
		Home : First slide
		End : Last slide
		Up/Right arrow : Next item/slide
		Ctrl + Up/Right arrow : Next slide
		Down/Left arrow : Previous item/slide
		Ctrl + Down/Left arrow : Previous slide
		Ctrl+G : Go to slide...
		Ctrl+H : Show thumbnails and go to slide
		(Shift instead of Ctrl works too)
	*/
	document.addEventListener('keyup', function(evt) {
		if(evt.ctrlKey || evt.shiftKey) {
			switch(evt.keyCode) {
				case 71:
					var slide = prompt('Which slide?');
					me.goto(+slide? slide - 1 : slide);
					break;
				case 72:
					if(document.body.classList.contains('show-thumbnails')) {
						document.body.classList.remove('show-thumbnails');
					}
					else {
						document.body.classList.add('show-thumbnails');

						document.body.addEventListener('click', function(evt) {
							var slide = evt.target;

							while(slide && !slide.classList.contains('slide')) {
								slide = slide.parentNode;
							}

							if(slide) {
								me.goto(slide.id);
								setTimeout(function() { me.adjustFontSize(); }, 1000); // for Opera
							}

							document.body.classList.remove('show-thumbnails');
						}, false);
					}
			}
		}

		if(evt.target === document.body || evt.target === document.body.parentNode) {
			if(evt.keyCode >= 35 && evt.keyCode <= 40) {
				evt.preventDefault();
			}

			switch(evt.keyCode) {
				case 35: // end
					me.end();
					break;
				case 36: // home
					me.start();
					break;
				case 37: // <-
				case 38: // up arrow
					me.previous(evt.ctrlKey || evt.shiftKey);
					break;
				case 39: // ->
				case 40: // down arrow
					me.next(evt.ctrlKey || evt.shiftKey);
					break;
			}
		}
	}, false);
}

SlideShow.prototype = {
	start: function() {
		this.goto(0);
	},

	end: function() {
		this.goto(this.slides.length - 1);
	},

	/**
		@param hard {Boolean} Whether to advance to the next slide (true) or
			just the next step (which could very well be showing a list item)
	 */
	next: function(hard) {
		if(!hard && this.items.length) {
			// If there's no current, then just mark the first one as such
			if(!this.item) {
				this.items[this.item++].classList.add('current');
			}
			// Add .current to current item if it exists, otherwise advance to next slide
			else if(this.item < this.items.length) {
				classes = this.items[this.item - 1].classList; // to speed up lookups

				classes.remove('current');
				classes.add('displayed');

				this.items[this.item++].classList.add('current');
			}
			else {
				this.item = 0;
				this.next(true);
			}
		}
		else {
			this.goto(this.slide + 1);

			this.item = 0;

			// Mark all items as not displayed, if there are any
			if(this.items.length) {
				for (var i=0; i<this.items.length; i++) {
					if(this.items[i].classList) {
						this.items[i].classList.remove('displayed');
						this.items[i].classList.remove('current');
					}
				}
			}
		}
	},

	previous: function(hard) {
		if(!hard && this.item > 0) {
			var classes = this.items[this.item - 1].classList; // to speed up lookups

			classes.remove('current');

			if(this.item > 1) {
				classes = this.items[--this.item - 1].classList;

				classes.remove('displayed');
				classes.add('current');
			}
			else {
				this.item = 0;
			}
		}
		else {

			this.goto(this.slide - 1);

			this.item = this.items.length;

			// Mark all items as displayed, if there are any
			if(this.items.length) {
				for (var i=0; i<this.items.length; i++) {
					if(this.items[i].classList) {
						this.items[i].classList.add('displayed');
					}
				}

				// Mark the last one as current
				var lastItem = this.items[this.items.length - 1];

				lastItem.classList.remove('displayed');
				lastItem.classList.add('current');
			}
		}
	},

	/**
		Go to an aribtary slide
		@param which {String|Integer} Which slide (identifier or slide number)
	*/
	goto: function(which) {
		var slide;

		// We have to remove it to prevent multiple calls to goto messing up
		// our current item (and there's no point either, so we save on performance)
		window.removeEventListener('hashchange', this.onhashchange, false);

		if(which + 0 === which && which in this.slides) { // Argument is a valid slide number
			this.slide = which;

			slide = this.slides[this.slide];
			location.hash = '#' + slide.id;
		}
		else if(which + '' === which) { // Argument is a slide id
			slide = document.getElementById(which);

			if(slide) {
				this.slide = this.slides.indexOf(slide);
				location.hash = '#' + which;
			}
		}

		if(slide) { // Slide actually changed, perform any other tasks needed
			document.title = slide.getAttribute('data-title') || documentTitle;

			this.adjustFontSize();

			// Update items collection
			this.items = this.slides[this.slide].querySelectorAll('.delayed');
			this.item = 0;
		}

		// If you attach the listener immediately again then it will catch the event
		// We have to do it asynchronously
		var me = this;
		setTimeout(function() {
			window.addEventListener('hashchange', me.onhashchange, false);
		}, 1000);
	},

	adjustFontSize: function() {
		// Cache long lookup chains, for performance
		var bodyStyle = document.body.style,
			scrollRoot = document[document.documentElement.scrollHeight? 'documentElement' : 'body'],
			innerHeight = window.innerHeight,
			innerWidth = window.innerWidth;

		// Clear previous styles
		bodyStyle.fontSize = '';

		if(document.body.classList.contains('show-thumbnails')) {
			return;
		}

		for(
			var percent = 100;
			(scrollRoot.scrollHeight > innerHeight || scrollRoot.scrollWidth > innerWidth) && percent >= 35;
			percent-=5
		) {
			bodyStyle.fontSize = percent + '%';
		}

		// Individual slide
		var slide = this.slides[this.slide];

		// If the slide has the class "dont-resize" then don't do anything
		if(slide.classList.contains('dont-resize')) {
			return;
		}

		if(slide.clientHeight && slide.clientWidth) {
			// Strange FF bug: scrollHeight doesn't work properly with overflow:hidden
			slide.style.overflow = 'auto';

			for(
				;
				(slide.scrollHeight > slide.clientHeight || slide.scrollWidth > slide.clientWidth) && percent >= 35;
				percent--
			) {
				bodyStyle.fontSize = percent + '%';
			}

			slide.style.overflow = '';
		}
	}
};

})();<|endoftext|>


<commit_before>var gulp = require('gulp'),
    fs = require('fs'),
    path = require('path'),
    inflection = require('inflection'),
    install = require('gulp-install'),
    conflict = require('gulp-conflict'),
    template = require('gulp-template'),
    rename = require("gulp-rename"),
    inquirer = require('inquirer'),
    license = require('license'),
    gitConfig = require('git-config');

gulp.task('default', function(done) {
  gitConfig(function (err, gitConfig) {
    if (err) { return done(err); }

    license.licenseTypes(function(err, licenseTypes) {
      inquirer.prompt([
        {type: 'input', name: 'name', message: 'Project name', default: gulp.args.join('-')},
        {type: 'input', name: 'description', message: 'Project description', default: 'The best project ever.'},
        {type: 'input', name: 'author_name', message: 'Project author name', default: gitConfig.user.name},
        {type: 'input', name: 'author_email', message: 'Project author name', default: gitConfig.user.email},
        {type: 'input', name: 'github_user_name', message: 'GitHub user name', default: gitConfig.github.user},
        {type: 'list', name: 'licenseType', message: 'Choose your license type', choices: licenseTypes, default: 'mit'},
        {type: 'confirm', name: 'moveon', message: 'OK?'}
      ],

      function(answers) {
        if (!answers.moveon) { return done(); }

        answers.year = new Date().getFullYear();

        license.createLicense({licenseType: answers.licenseType, year: answers.year, organization: answers.author_name}, function(err, licenseString) {
          fs.writeFileSync(__dirname + '/templates/LICENSE', licenseString);
          answers.license = answers.licenseType.toUpperCase();

          gulp.src(__dirname + '/templates/**', {dot: true})
            .pipe(template(answers))
            .pipe(rename(function (file) {
              if (file.basename === 'dot') {
                file.basename = file.basename.replace('dot', '');
              } else {
                file.basename = file.basename.replace('name', answers.name);
              }
            }))
            .pipe(conflict('./'))
            .pipe(gulp.dest('./'))
            .pipe(install())
            .on('finish', done);
        });
      });
    });
  });
});

gulp.task('generate', function(done) {
  inquirer.prompt([
    {type: 'input', name: 'name', message: 'file name', default: gulp.args.join('_')},
    {type: 'confirm', name: 'moveon', message: 'OK?'}
  ],

  function(answers) {
    if (!answers.moveon) { return done(); }

    answers.name = answers.name.replace(/^\/+|\/+$/g, '');
    answers.basename = path.basename(answers.name, '.ts');
    answers.dirname = path.dirname(answers.name);
    answers.classifyName = inflection.classify(answers.basename);

    answers.relativeRootDir = path.relative('src/' + answers.dirname, process.cwd()) || '.';

    gulp.src(__dirname + '/templates-generate/**')
      .pipe(template(answers))
      .pipe(rename(function (file) {
        if (file.basename.indexOf('name') >= 0) {
          file.dirname = path.join(file.dirname, answers.dirname);
          file.basename = file.basename.replace('name', answers.basename);
        }
      }))
      .pipe(conflict('./'))
      .pipe(gulp.dest('./'))
      .pipe(install())
      .on('finish', done);
  });
});
<commit_msg>Fix dotfile detection<commit_after>var gulp = require('gulp'),
    fs = require('fs'),
    path = require('path'),
    inflection = require('inflection'),
    install = require('gulp-install'),
    conflict = require('gulp-conflict'),
    template = require('gulp-template'),
    rename = require("gulp-rename"),
    inquirer = require('inquirer'),
    license = require('license'),
    gitConfig = require('git-config');

gulp.task('default', function(done) {
  gitConfig(function (err, gitConfig) {
    if (err) { return done(err); }

    license.licenseTypes(function(err, licenseTypes) {
      inquirer.prompt([
        {type: 'input', name: 'name', message: 'Project name', default: gulp.args.join('-')},
        {type: 'input', name: 'description', message: 'Project description', default: 'The best project ever.'},
        {type: 'input', name: 'author_name', message: 'Project author name', default: gitConfig.user.name},
        {type: 'input', name: 'author_email', message: 'Project author name', default: gitConfig.user.email},
        {type: 'input', name: 'github_user_name', message: 'GitHub user name', default: gitConfig.github.user},
        {type: 'list', name: 'licenseType', message: 'Choose your license type', choices: licenseTypes, default: 'mit'},
        {type: 'confirm', name: 'moveon', message: 'OK?'}
      ],

      function(answers) {
        if (!answers.moveon) { return done(); }

        answers.year = new Date().getFullYear();

        license.createLicense({licenseType: answers.licenseType, year: answers.year, organization: answers.author_name}, function(err, licenseString) {
          fs.writeFileSync(__dirname + '/templates/LICENSE', licenseString);
          answers.license = answers.licenseType.toUpperCase();

          gulp.src(__dirname + '/templates/**', {dot: true})
            .pipe(template(answers))
            .pipe(rename(function (file) {
              if (file.basename.indexOf('dot') === 0) {
                file.basename = file.basename.replace('dot', '');
              } else {
                file.basename = file.basename.replace('name', answers.name);
              }
            }))
            .pipe(conflict('./'))
            .pipe(gulp.dest('./'))
            .pipe(install())
            .on('finish', done);
        });
      });
    });
  });
});

gulp.task('generate', function(done) {
  inquirer.prompt([
    {type: 'input', name: 'name', message: 'file name', default: gulp.args.join('_')},
    {type: 'confirm', name: 'moveon', message: 'OK?'}
  ],

  function(answers) {
    if (!answers.moveon) { return done(); }

    answers.name = answers.name.replace(/^\/+|\/+$/g, '');
    answers.basename = path.basename(answers.name, '.ts');
    answers.dirname = path.dirname(answers.name);
    answers.classifyName = inflection.classify(answers.basename);

    answers.relativeRootDir = path.relative('src/' + answers.dirname, process.cwd()) || '.';

    gulp.src(__dirname + '/templates-generate/**')
      .pipe(template(answers))
      .pipe(rename(function (file) {
        if (file.basename.indexOf('name') >= 0) {
          file.dirname = path.join(file.dirname, answers.dirname);
          file.basename = file.basename.replace('name', answers.basename);
        }
      }))
      .pipe(conflict('./'))
      .pipe(gulp.dest('./'))
      .pipe(install())
      .on('finish', done);
  });
});
<|endoftext|>