<commit_before>/**
 * Display a nice easy to use multiselect list
 * @Version: 1.3
 * @Author: Patrick Springstubbe
 * @Contact: @JediNobleclem
 * @Website: springstubbe.us
 * @Source: https://github.com/nobleclem/jQuery-MultiSelect
 * @Notes: If select list is hidden on page load use the jquery.actual plugin
 *         to resolve issues with preselected items placeholder text
 *         https://github.com/dreamerslab/jquery.actual
 *
 * Usage:
 *     $('select[multiple]').multiselect();
 *     $('select[multiple]').multiselect({ placeholder: 'Select options' });
 *
 **/
(function($){
    var msCounter = 1;
    $.fn.multiselect = function( options ){
        var defaults = {
            placeholder   : '',    // text to use in dummy input
            columns       : 1,     // how many columns should be use to show options
            maxWidth      : null,  // maximum width of option overlay (or selector)
            minHeight     : 200,   // minimum height of option overlay
            maxHeight     : null,  // maximum height of option overlay
            showCheckbox  : true,  // display the checkbox to the user
            jqActualOpts  : {},    // options for jquery.actual

            // @NOTE: these are for future development
            minSelect     : false, // minimum number of items that can be selected
            maxSelect     : false, // maximum number of items that can be selected
            groupSelect   : false, // select entire optgroup
            selectAllText : false, // add select all option
            searchOptions : false, // enable option search/filtering
        }
        options = $.extend( defaults, options );

        var func = {
            addOption: function( container, option )
            {
                container.text( $(option).text() );
                container.prepend(
                    $('<input type="checkbox" value="" title="" />')
                        .val( $(option).val() )
                        .attr( 'title', $(option).text() )
                        .attr( 'id', 'ms-opt-'+ msCounter )
                );

                if( $(option).attr( 'selected' ) ) {
                    container.addClass('selected');
                    container.find( 'input[type="checkbox"]' ).attr( 'checked', 'checked' );
                }

                var label = $('').attr( 'for', 'ms-opt-'+ msCounter );
                container.wrapInner( label );

                if( !options.showCheckbox ) {
                    container.find('input[id="ms-opt-'+ msCounter +'"]').hide();
                }

                msCounter = msCounter + 1;
            },

            ieVersion: function()
            {
                var myNav = navigator.userAgent.toLowerCase();
                return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : false;
            }
        };

        // menuize each list
        return this.each(function(){
            // make sure this is a select list and not loaded
            if( this.nodeName != 'SELECT' || $(this).hasClass('jqmsLoaded') ) {
                return true;
            }

            // sanity check so we don't double load on a select element
            $(this).addClass('jqmsLoaded');

            // add option container
            $(this).after('
<button>None Selected</button>

');
            var placeholder = $(this).next('.ms-options-wrap').find('> button:first-child');
            var optionsWrap = $(this).next('.ms-options-wrap').find('> .ms-options');
            var optionsList = optionsWrap.find('> ul');
            var hasOptGroup = $(this).find('optgroup').length ? true : false;

            var maxWidth = null;
            if( typeof options.width == 'number' ) {
                optionsWrap.parent().css( 'position', 'relative' );
                maxWidth = options.width;
            }
            else if( typeof options.width == 'string' ) {
                $( options.width ).css( 'position', 'relative' );
                maxWidth = '100%';
            }
            else {
                optionsWrap.parent().css( 'position', 'relative' );
            }

            var maxHeight = ($(window).height() - optionsWrap.offset().top - 20);
            if( options.maxHeight ) {
                maxHeight = ($(window).height() - optionsWrap.offset().top - 20);
                maxHeight = maxHeight < options.minHeight ? options.minHeight : maxheight;
            }

            maxHeight = maxHeight < options.minHeight ? options.minHeight : maxHeight;

            optionsWrap.css({
                maxWidth : maxWidth,
                minHeight: options.minHeight,
                maxHeight: maxHeight,
                overflow : 'auto'
            }).hide();

            // isolate options scroll
            // @source: https://github.com/nobleclem/jQuery-IsolatedScroll
            optionsWrap.bind( 'touchmove mousewheel DOMMouseScroll', function ( e ) {
                if( ($(this).outerHeight() < $(this)[0].scrollHeight) ) {
                    var e0 = e.originalEvent,
                        delta = e0.wheelDelta || -e0.detail;

                    if( ($(this).outerHeight() + $(this)[0].scrollTop) > $(this)[0].scrollHeight ) {
                        e.preventDefault();
                        this.scrollTop += ( delta < 0 ? 1 : -1 );
                    }
                }
            });

            // hide options menus if click happens off of the list placeholder button
            $(window).off('click.ms-hideopts').on('click.ms-hideopts', function( event ){
                if( !$(event.target).closest('.ms-options-wrap').length ) {
                    $('.ms-options-wrap > .ms-options:visible').hide();
                }
            });

            // disable button action
            placeholder.bind('mousedown',function(){
                // hide other menus before showing this one
                $('.ms-options-wrap > .ms-options:visible').each(function(){
                    if( $(this).parent().prev()[0] != optionsWrap.parent().prev()[0] ) {
                        $(this).hide();
                    }
                });

                // show/hide options
                optionsWrap.toggle();

                // recalculate height
                if( optionsWrap.is(':visible') ) {
                    optionsWrap.css( 'maxHeight', '' );

                    var maxHeight = ($(window).height() - optionsWrap.offset().top - 20);
                    if( options.maxHeight ) {
                        maxHeight = ($(window).height() - optionsWrap.offset().top - 20);
                        maxHeight = maxHeight < options.minHeight ? options.minHeight : maxheight;
                    }
                    maxHeight = maxHeight < options.minHeight ? options.minHeight : maxHeight;

                    optionsWrap.css( 'maxHeight', maxHeight );
                }
            }).click(function( event ){ event.preventDefault(); });

            // add placeholder copy
            if( options.placeholder ) {
                placeholder.text( options.placeholder );
            }

            // hide native select list
            $(this).hide();

            // add options to wrapper
            $(this).children().each(function(){
                var container = $('

');

                // add group of items
                if( this.nodeName == 'OPTGROUP' ) {
                    container.addClass('optgroup');
                    container.append(''+ $(this).attr('label') +'');
                    container.find('> .label').css({
                        clear: 'both'
                    });
                    container.append('

');

                    $(this).children('option').each(function(){
                        var gContainer = $('

');
                        func.addOption( gContainer, this );

                        container.find('> ul').append( gContainer );
                    });
                }
                else if( this.nodeName == 'OPTION' ) {
                    func.addOption( container, this );
                }
                else {
                    // bad option
                    return true;
                }

                optionsList.append( container );
            });

            // COLUMNIZE
            if( hasOptGroup ) {
                // float non grouped options
                optionsList.find('> li:not(.optgroup)').css({
                    float: 'left',
                    width: (100 / options.columns) +'%'
                });

                // add CSS3 column styles
                optionsList.find('li.optgroup').css({
                    clear: 'both'
                }).find('> ul').css({
                    'column-count'        : options.columns,
                    'column-gap'          : 0,
                    '-webkit-column-count': options.columns,
                    '-webkit-column-gap'  : 0,
                    '-moz-column-count'   : options.columns,
                    '-moz-column-gap'     : 0
                });

                // for crappy IE versions float grouped options
                if( func.ieVersion() && func.ieVersion() < 10 ) {
                    optionsList.find('li.optgroup > ul > li').css({
                        float: 'left',
                        width: (100 / options.columns) +'%'
                    });
                }
            }
            else {
                // add CSS3 column styles
                optionsList.css({
                    'column-count'        : options.columns,
                    'column-gap'          : 0,
                    '-webkit-column-count': options.columns,
                    '-webkit-column-gap'  : 0,
                    '-moz-column-count'   : options.columns,
                    '-moz-column-gap'     : 0
                });

                // for crappy IE versions float grouped options
                if( func.ieVersion() && func.ieVersion() < 10 ) {
                    optionsList.find('> li').css({
                        float: 'left',
                        width: (100 / options.columns) +'%'
                    });
                }
            }

            // BIND SELECT ACTION
            optionsWrap.find('input[type="checkbox"]').click(function(){
                $(this).closest( 'li' ).toggleClass( 'selected' );

                var select = optionsWrap.parent().prev();

                // toggle clicked option
                select.find('option[value="'+ $(this).val() +'"]').attr(
                    'selected', $(this).is(':checked')
                ).closest('select').trigger('change');

                updatePlaceholderText();
            }).each(function( idx ){
                if( $(this).css('display').match(/block$/) ) {
                    var checkboxWidth = $(this).outerWidth();
                        checkboxWidth = checkboxWidth ? checkboxWidth : 15;

                    $(this).closest('label').css(
                        'padding-left',
                        (parseInt( $(this).closest('label').css('padding-left') ) * 2) + checkboxWidth
                    );
                }
            });

            // update selected placeholder text
            var updatePlaceholderText = function(){
                var select = optionsWrap.parent().prev();

                // get selected options
                var selOpts = [];
                select.find('option[selected="selected"]').each(function(){
                    selOpts.push( $(this).text() );
                });

                // UPDATE PLACEHOLDER TEXT WITH OPTIONS SELECTED
                placeholder.text( selOpts.join( ', ' ) );
                var copy = placeholder.clone().css({
                    display   : 'inline',
                    width     : 'auto',
                    visibility: 'hidden'
                }).appendTo( optionsWrap.parent() );

                // if the jquery.actual plugin is loaded use it to get the widths
                var copyWidth  = (typeof $.fn.actual !== 'undefined') ? copy.actual('width',options.jqActualOpts) : copy.width();
                var placeWidth = (typeof $.fn.actual !== 'undefined') ? placeholder.actual('width',options.jqActualOpts) : placeholder.width();

                // if copy is larger than button width use "# selected"
                if( copyWidth > placeWidth ) {
                    placeholder.text( selOpts.length +' selected' );
                }
                // if options selected then use those
                else if( selOpts.length ) {
                    placeholder.text( selOpts.join( ', ' ) );
                }
                // replace placeholder text
                else {
                    placeholder.text( options.placeholder );
                }

                // remove dummy element
                copy.remove();
            };

            updatePlaceholderText();
        });
    };
}(jQuery));
<commit_msg>New search & select all options, default placeholder text<commit_after>/**
 * Display a nice easy to use multiselect list
 * @Version: 1.4
 * @Author: Patrick Springstubbe
 * @Contact: @JediNobleclem
 * @Website: springstubbe.us
 * @Source: https://github.com/nobleclem/jQuery-MultiSelect
 * @Notes: If select list is hidden on page load use the jquery.actual plugin
 *         to resolve issues with preselected items placeholder text
 *         https://github.com/dreamerslab/jquery.actual
 *
 * Usage:
 *     $('select[multiple]').multiselect();
 *     $('select[multiple]').multiselect({ placeholder: 'Select options' });
 *
 **/
(function($){
    var msCounter = 1;
    $.fn.multiselect = function( options ){
        var defaults = {
            placeholder   : 'Select options', // text to use in dummy input
            columns       : 1,                // how many columns should be use to show options
            search        : false,            // include option search box
            // search filter options
            searchOptions : {
                default      : 'Search', // search input placeholder text
                showOptGroups: false     // show option group titles if no options remaining
            },
            selectAll     : false, // add select all option
            selectGroup   : false, // select entire optgroup
            minHeight     : 200,   // minimum height of option overlay
            maxHeight     : null,  // maximum height of option overlay
            showCheckbox  : true,  // display the checkbox to the user
            jqActualOpts  : {},    // options for jquery.actual

            // @NOTE: these are for future development
            maxWidth      : null,  // maximum width of option overlay (or selector)
            minSelect     : false, // minimum number of items that can be selected
            maxSelect     : false, // maximum number of items that can be selected
        }
        options = $.extend( defaults, options );

        var func = {
            addOption: function( container, option )
            {
                container.text( $(option).text() );
                container.prepend(
                    $('<input type="checkbox" value="" title="" />')
                        .val( $(option).val() )
                        .attr( 'title', $(option).text() )
                        .attr( 'id', 'ms-opt-'+ msCounter )
                );

                if( $(option).attr( 'selected' ) ) {
                    container.addClass('default');
                    container.addClass('selected');
                    container.find( 'input[type="checkbox"]' ).attr( 'checked', 'checked' );
                }

                var label = $('').attr( 'for', 'ms-opt-'+ msCounter );
                container.wrapInner( label );

                if( !options.showCheckbox ) {
                    container.find('input[id="ms-opt-'+ msCounter +'"]').hide();
                }

                msCounter = msCounter + 1;
            },

            ieVersion: function()
            {
                var myNav = navigator.userAgent.toLowerCase();
                return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : false;
            }
        };

        // menuize each list
        return this.each(function(){
            // make sure this is a select list and not loaded
            if( this.nodeName != 'SELECT' || $(this).hasClass('jqmsLoaded') ) {
                return true;
            }

            // sanity check so we don't double load on a select element
            $(this).addClass('jqmsLoaded');

            // add option container
            $(this).after('
<button>None Selected</button>

');
            var placeholder = $(this).next('.ms-options-wrap').find('> button:first-child');
            var optionsWrap = $(this).next('.ms-options-wrap').find('> .ms-options');
            var optionsList = optionsWrap.find('> ul');
            var hasOptGroup = $(this).find('optgroup').length ? true : false;

            var maxWidth = null;
            if( typeof options.width == 'number' ) {
                optionsWrap.parent().css( 'position', 'relative' );
                maxWidth = options.width;
            }
            else if( typeof options.width == 'string' ) {
                $( options.width ).css( 'position', 'relative' );
                maxWidth = '100%';
            }
            else {
                optionsWrap.parent().css( 'position', 'relative' );
            }

            var maxHeight = ($(window).height() - optionsWrap.offset().top - 20);
            if( options.maxHeight ) {
                maxHeight = ($(window).height() - optionsWrap.offset().top - 20);
                maxHeight = maxHeight < options.minHeight ? options.minHeight : maxheight;
            }

            maxHeight = maxHeight < options.minHeight ? options.minHeight : maxHeight;

            optionsWrap.css({
                maxWidth : maxWidth,
                minHeight: options.minHeight,
                maxHeight: maxHeight,
                overflow : 'auto'
            }).hide();

            // isolate options scroll
            // @source: https://github.com/nobleclem/jQuery-IsolatedScroll
            optionsWrap.bind( 'touchmove mousewheel DOMMouseScroll', function ( e ) {
                if( ($(this).outerHeight() < $(this)[0].scrollHeight) ) {
                    var e0 = e.originalEvent,
                        delta = e0.wheelDelta || -e0.detail;

                    if( ($(this).outerHeight() + $(this)[0].scrollTop) > $(this)[0].scrollHeight ) {
                        e.preventDefault();
                        this.scrollTop += ( delta < 0 ? 1 : -1 );
                    }
                }
            });

            // hide options menus if click happens off of the list placeholder button
            $(window).off('click.ms-hideopts').on('click.ms-hideopts', function( event ){
                if( !$(event.target).closest('.ms-options-wrap').length ) {
                    $('.ms-options-wrap > .ms-options:visible').hide();
                }
            });

            // disable button action
            placeholder.bind('mousedown',function(){
                // hide other menus before showing this one
                $('.ms-options-wrap > .ms-options:visible').each(function(){
                    if( $(this).parent().prev()[0] != optionsWrap.parent().prev()[0] ) {
                        $(this).hide();
                    }
                });

                // show/hide options
                optionsWrap.toggle();

                // recalculate height
                if( optionsWrap.is(':visible') ) {
                    optionsWrap.css( 'maxHeight', '' );

                    var maxHeight = ($(window).height() - optionsWrap.offset().top - 20);
                    if( options.maxHeight ) {
                        maxHeight = ($(window).height() - optionsWrap.offset().top - 20);
                        maxHeight = maxHeight < options.minHeight ? options.minHeight : maxheight;
                    }
                    maxHeight = maxHeight < options.minHeight ? options.minHeight : maxHeight;

                    optionsWrap.css( 'maxHeight', maxHeight );
                }
            }).click(function( event ){ event.preventDefault(); });

            // add placeholder copy
            if( options.placeholder ) {
                placeholder.text( options.placeholder );
            }

            // add search box
            if( options.search ) {
                optionsList.before('
<input type="text" value="" placeholder="'+ options.searchOptions.default +'" />
');

                var search = optionsWrap.find('.ms-search input');
                search.on('keyup', function(){
                    optionsList.find('li:not(.optgroup)').each(function(){
                        var optText = $(this).text();

                        if( optText.toLowerCase().indexOf( search.val().toLowerCase() ) > -1 ) {
                            $(this).show();
                        }
                        // don't hide selected items
                        else if( !$(this).hasClass('selected') ) {
                            $(this).hide();
                        }

                        if( !options.searchOptions.showOptGroups && $(this).closest('li.optgroup') ) {
                            $(this).closest('li.optgroup').show();

                            if( $(this).closest('li.optgroup').find('li:visible').length ) {
                                $(this).closest('li.optgroup').show();
                            }
                            else {
                                $(this).closest('li.optgroup').hide();
                            }
                        }
                    });
                });
            }

            // add global select all options
            if( options.selectAll ) {
                optionsList.before('Select all');

                var globalSelectAll = optionsWrap.find('.ms-selectall.global');
            }

            // handle select all option
            optionsWrap.on('click', '.ms-selectall', function( event ){
                event.preventDefault();

                if( $(this).hasClass('global') ) {
                    // check if any selected if so then select them
                    if( optionsList.find('li:not(.optgroup)').filter(':not(.selected)').length ) {
                        optionsList.find('li:not(.optgroup)').filter(':not(.selected)').find('input[type="checkbox"]').trigger('click');
                    }
                    // deselect everything
                    else {
                        optionsList.find('li:not(.optgroup).selected input[type="checkbox"]').trigger('click');
                    }
                }
                else if( $(this).closest('li').hasClass('optgroup') ) {
                    var optgroup = $(this).closest('li.optgroup');

                    // check if any selected if so then select them
                    if( optgroup.find('li:not(.selected)').length ) {
                        optgroup.find('li:not(.selected) input[type="checkbox"]').trigger('click');
                    }
                    // deselect everything
                    else {
                        optgroup.find('li.selected input[type="checkbox"]').trigger('click');
                    }
                }
            });

            // hide native select list
            $(this).hide();

            // add options to wrapper
            $(this).children().each(function(){
                var container = $('

');

                // add group of items
                if( this.nodeName == 'OPTGROUP' ) {
                    container.addClass('optgroup');
                    container.append(''+ $(this).attr('label') +'');
                    container.find('> .label').css({
                        clear: 'both'
                    });

                    if( options.selectGroup ) {
                        container.append('Select all');
                    }

                    container.append('

');

                    $(this).children('option').each(function(){
                        var gContainer = $('

');
                        func.addOption( gContainer, this );

                        container.find('> ul').append( gContainer );
                    });
                }
                else if( this.nodeName == 'OPTION' ) {
                    func.addOption( container, this );
                }
                else {
                    // bad option
                    return true;
                }

                optionsList.append( container );
            });

            // COLUMNIZE
            if( hasOptGroup ) {
                // float non grouped options
                optionsList.find('> li:not(.optgroup)').css({
                    float: 'left',
                    width: (100 / options.columns) +'%'
                });

                // add CSS3 column styles
                optionsList.find('li.optgroup').css({
                    clear: 'both'
                }).find('> ul').css({
                    'column-count'        : options.columns,
                    'column-gap'          : 0,
                    '-webkit-column-count': options.columns,
                    '-webkit-column-gap'  : 0,
                    '-moz-column-count'   : options.columns,
                    '-moz-column-gap'     : 0
                });

                // for crappy IE versions float grouped options
                if( func.ieVersion() && func.ieVersion() < 10 ) {
                    optionsList.find('li.optgroup > ul > li').css({
                        float: 'left',
                        width: (100 / options.columns) +'%'
                    });
                }
            }
            else {
                // add CSS3 column styles
                optionsList.css({
                    'column-count'        : options.columns,
                    'column-gap'          : 0,
                    '-webkit-column-count': options.columns,
                    '-webkit-column-gap'  : 0,
                    '-moz-column-count'   : options.columns,
                    '-moz-column-gap'     : 0
                });

                // for crappy IE versions float grouped options
                if( func.ieVersion() && func.ieVersion() < 10 ) {
                    optionsList.find('> li').css({
                        float: 'left',
                        width: (100 / options.columns) +'%'
                    });
                }
            }

            // BIND SELECT ACTION
            optionsWrap.find('input[type="checkbox"]').click(function(){
                $(this).closest( 'li' ).toggleClass( 'selected' );

                var select = optionsWrap.parent().prev();

                // toggle clicked option
                select.find('option[value="'+ $(this).val() +'"]').attr(
                    'selected', $(this).is(':checked')
                ).closest('select').trigger('change');

                updatePlaceholderText();
            }).each(function( idx ){
                if( $(this).css('display').match(/block$/) ) {
                    var checkboxWidth = $(this).outerWidth();
                        checkboxWidth = checkboxWidth ? checkboxWidth : 15;

                    $(this).closest('label').css(
                        'padding-left',
                        (parseInt( $(this).closest('label').css('padding-left') ) * 2) + checkboxWidth
                    );
                }
            });

            // update selected placeholder text
            var updatePlaceholderText = function(){
                var select = optionsWrap.parent().prev();

                // get selected options
                var selOpts = [];
                select.find('option[selected="selected"]').each(function(){
                    selOpts.push( $(this).text() );
                });

                // UPDATE PLACEHOLDER TEXT WITH OPTIONS SELECTED
                placeholder.text( selOpts.join( ', ' ) );
                var copy = placeholder.clone().css({
                    display   : 'inline',
                    width     : 'auto',
                    visibility: 'hidden'
                }).appendTo( optionsWrap.parent() );

                // if the jquery.actual plugin is loaded use it to get the widths
                var copyWidth  = (typeof $.fn.actual !== 'undefined') ? copy.actual('width',options.jqActualOpts) : copy.width();
                var placeWidth = (typeof $.fn.actual !== 'undefined') ? placeholder.actual('width',options.jqActualOpts) : placeholder.width();

                // if copy is larger than button width use "# selected"
                if( copyWidth > placeWidth ) {
                    placeholder.text( selOpts.length +' selected' );
                }
                // if options selected then use those
                else if( selOpts.length ) {
                    placeholder.text( selOpts.join( ', ' ) );
                }
                // replace placeholder text
                else {
                    placeholder.text( options.placeholder );
                }

                // remove dummy element
                copy.remove();
            };

            updatePlaceholderText();
        });
    };
}(jQuery));
<|endoftext|>


<commit_before>/**
 * Use this jQuery plugin to auto-save and restore form data via
 * jStorage to protect against browser crashes and other accidental
 * interruptions.
 *
 * Usage:
 *
 * 1. Include the script and prerequisites:
 *
 *
 *
 *
 *
 *
 * 2. Initialize the form:
 *
 *
 *
 * 3. Add a restore option if the saved data is detected on page load
 * (using an Elefant template as an example):
 *
 *
Auto-saved data found for this form. Click here to restore.

 *
 * 4. Add class="autosave-clear" to the submit button so saving the form
 * clears the data.
 *
 * 5. To add a cancel link, add the following onclick handler:
 *
 *   onclick="return $.cancel_autosave ('Are you sure you want to cancel?')"
 *
 * The stored key name is determined as follows:
 *
 *   "autosave-" + (pathname + parameters).replace (/[^a-z0-9-]/g, '')
 *
 * So for example if the request is:
 *
 *   /admin/edit?page=index
 *
 * The key name will be:
 *
 *   autosave-admineditpageindex
 *
 */
var autosave_interval = null,
	autosave_focused = false,
	autosave_key_name = 'autosave-' + (window.location.pathname + window.location.search).replace (/[^a-zA-Z0-9-]+/g, '');

(function ($) {
	if ($.jStorage.get (autosave_key_name)) {
		setTimeout (function () {
			var vals = $.parseJSON (lzw_decode ($.jStorage.get (autosave_key_name)));
			$('.autosave-notice').show ();
		}, 100);
	}

	$.cancel_autosave = function (msg) {
		if (confirm (msg)) {
			$.jStorage.deleteKey (autosave_key_name);
			return true;
		}
		return false;
	}

	$.fn.extend ({
		autosave: function (options) {
			var defaults = {
				interval: 10000,
				form: null,
			};

			var options = $.extend (defaults, options);

			// Get the form object
			options.form = this[0];

			// Handler to clear the key (used on submit)
			$('.autosave-clear').click (function () {
				$.jStorage.deleteKey (autosave_key_name);
			});

			// Handler to restore data from the key
			$('.autosave-restore').click (function () {
				var i = 0,
					opts = options,
					vals = $.parseJSON (lzw_decode ($.jStorage.get (autosave_key_name)));

				for (i = 0; i < vals.length; i++) {
					try {
						// Set the field value
						if ($(opts.form.elements[vals[i].name]).is (':radio') || $(opts.form.elements[vals[i].name]).is (':checkbox')) {
							if (vals[i].value) {
								$(opts.form.elements[vals[i].name]).attr ('checked', 'checked');
							} else {
								$(opts.form.elements[vals[i].name]).attr ('checked', null);
							}
						} else {
							opts.form.elements[vals[i].name].value = vals[i].value;
						}

						if (opts.form.elements[vals[i].name].getAttribute ('id') == 'webpage-body') {
							// Set the contents of wysiwyg editor
							$('#webpage-body').redactor ('code.set', vals[i].value, false);
						} else if (opts.form.elements[vals[i].name].getAttribute ('id') == 'code-body') {
							// Set the contents of codemirror editor
							_codemirror.setValue (vals[i].value);
						} else if (opts.form.elements[vals[i].name].getAttribute ('id') == 'tags') {
							// Set the contents of tag-it widget
							$('#tagit').tagit ('removeAll');
							var tags = vals[i].value.split (',');
							for (var t = 0; t < tags.length; t++) {
								$('#tagit').tagit ('createTag', tags[t]);
							}
						}
					} catch (e) {}
				}

				// Clear the key
				$.jStorage.deleteKey (autosave_key_name);

				// Hide the restore notice
				$('.autosave-notice').slideUp ('slow');
				return false;
			});

			// Add a focus handler that triggers saving only once the form is active
			for (var i = 0; i < options.form.elements.length; i++) {
				$(options.form.elements[i]).focus (function () {
					autosave_focused = true;
				});
			}

			// Don't set the interval more than once
			if (autosave_interval != null) {
				return;
			}

			// Set an interval to save the form data
			autosave_interval = setInterval (function () {
				if (autosave_focused === false) {
					return;
				}

				var i = 0,
					opts = options,
					vals = [];

				for (i = 0; i < opts.form.elements.length; i++) {
					if (! opts.form.elements[i].name) {
						// Unnamed fields can be ignored (submit buttons)
						continue;
					}
					if (opts.form.elements[i].getAttribute ('id') == 'webpage-body') {
						// Get the contents from Redactor editor
						vals[i] = {
							name: opts.form.elements[i].name,
							value: $('#webpage-body').redactor ('code.get')
						};
					} else if (opts.form.elements[i].getAttribute ('id') == 'code-body') {
						// Get the contents from codemirror editor
						vals[i] = {
							name: opts.form.elements[i].name,
							value: _codemirror.getValue ()
						};
					} else if ($(opts.form.elements[i]).is (':radio') || $(opts.form.elements[i]).is (':checkbox')) {
						if (opts.form.elements[i].checked) {
							vals[i] = {
								name: opts.form.elements[i].name,
								value: true
							};
						} else {
							vals[i] = {
								name: opts.form.elements[i].name,
								value: false
							};
						}
					} else {
						// Get the contents from the field itself
						vals[i] = {
							name: opts.form.elements[i].name,
							value: opts.form.elements[i].value
						};
					}
				}

				var _json = JSON.stringify (vals);
				$.jStorage.set (autosave_key_name, lzw_encode (_json));
			}, options.interval);
		}
	});
})(jQuery);

// The following are from http://jsolait.net/

// LZW-compress a string
function lzw_encode(s) {
    var dict = {};
    var data = (s + "").split("");
    var out = [];
    var currChar;
    var phrase = data[0];
    var code = 256;
    for (var i=1; i<data.length; i++) {
        currChar=data[i];
        if (dict[phrase + currChar] != null) {
            phrase += currChar;
        }
        else {
            out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
            dict[phrase + currChar] = code;
            code++;
            phrase=currChar;
        }
    }
    out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
    for (var i=0; i<out.length; i++) {
        out[i] = String.fromCharCode(out[i]);
    }
    return out.join("");
}

// Decompress an LZW-encoded string
function lzw_decode(s) {
    var dict = {};
    var data = (s + "").split("");
    var currChar = data[0];
    var oldPhrase = currChar;
    var out = [currChar];
    var code = 256;
    var phrase;
    for (var i=1; i<data.length; i++) {
        var currCode = data[i].charCodeAt(0);
        if (currCode < 256) {
            phrase = data[i];
        }
        else {
           phrase = dict[currCode] ? dict[currCode] : (oldPhrase + currChar);
        }
        out.push(phrase);
        currChar = phrase.charAt(0);
        dict[code] = oldPhrase + currChar;
        code++;
        oldPhrase = phrase;
    }
    return out.join("");
}
<commit_msg>Re-enabling clean on autosave restore<commit_after>/**
 * Use this jQuery plugin to auto-save and restore form data via
 * jStorage to protect against browser crashes and other accidental
 * interruptions.
 *
 * Usage:
 *
 * 1. Include the script and prerequisites:
 *
 *
 *
 *
 *
 *
 * 2. Initialize the form:
 *
 *
 *
 * 3. Add a restore option if the saved data is detected on page load
 * (using an Elefant template as an example):
 *
 *
Auto-saved data found for this form. Click here to restore.

 *
 * 4. Add class="autosave-clear" to the submit button so saving the form
 * clears the data.
 *
 * 5. To add a cancel link, add the following onclick handler:
 *
 *   onclick="return $.cancel_autosave ('Are you sure you want to cancel?')"
 *
 * The stored key name is determined as follows:
 *
 *   "autosave-" + (pathname + parameters).replace (/[^a-z0-9-]/g, '')
 *
 * So for example if the request is:
 *
 *   /admin/edit?page=index
 *
 * The key name will be:
 *
 *   autosave-admineditpageindex
 *
 */
var autosave_interval = null,
	autosave_focused = false,
	autosave_key_name = 'autosave-' + (window.location.pathname + window.location.search).replace (/[^a-zA-Z0-9-]+/g, '');

(function ($) {
	if ($.jStorage.get (autosave_key_name)) {
		setTimeout (function () {
			var vals = $.parseJSON (lzw_decode ($.jStorage.get (autosave_key_name)));
			$('.autosave-notice').show ();
		}, 100);
	}

	$.cancel_autosave = function (msg) {
		if (confirm (msg)) {
			$.jStorage.deleteKey (autosave_key_name);
			return true;
		}
		return false;
	}

	$.fn.extend ({
		autosave: function (options) {
			var defaults = {
				interval: 10000,
				form: null,
			};

			var options = $.extend (defaults, options);

			// Get the form object
			options.form = this[0];

			// Handler to clear the key (used on submit)
			$('.autosave-clear').click (function () {
				$.jStorage.deleteKey (autosave_key_name);
			});

			// Handler to restore data from the key
			$('.autosave-restore').click (function () {
				var i = 0,
					opts = options,
					vals = $.parseJSON (lzw_decode ($.jStorage.get (autosave_key_name)));

				for (i = 0; i < vals.length; i++) {
					try {
						// Set the field value
						if ($(opts.form.elements[vals[i].name]).is (':radio') || $(opts.form.elements[vals[i].name]).is (':checkbox')) {
							if (vals[i].value) {
								$(opts.form.elements[vals[i].name]).attr ('checked', 'checked');
							} else {
								$(opts.form.elements[vals[i].name]).attr ('checked', null);
							}
						} else {
							opts.form.elements[vals[i].name].value = vals[i].value;
						}

						if (opts.form.elements[vals[i].name].getAttribute ('id') == 'webpage-body') {
							// Set the contents of wysiwyg editor
							$('#webpage-body').redactor ('code.set', vals[i].value);
						} else if (opts.form.elements[vals[i].name].getAttribute ('id') == 'code-body') {
							// Set the contents of codemirror editor
							_codemirror.setValue (vals[i].value);
						} else if (opts.form.elements[vals[i].name].getAttribute ('id') == 'tags') {
							// Set the contents of tag-it widget
							$('#tagit').tagit ('removeAll');
							var tags = vals[i].value.split (',');
							for (var t = 0; t < tags.length; t++) {
								$('#tagit').tagit ('createTag', tags[t]);
							}
						}
					} catch (e) {}
				}

				// Clear the key
				$.jStorage.deleteKey (autosave_key_name);

				// Hide the restore notice
				$('.autosave-notice').slideUp ('slow');
				return false;
			});

			// Add a focus handler that triggers saving only once the form is active
			for (var i = 0; i < options.form.elements.length; i++) {
				$(options.form.elements[i]).focus (function () {
					autosave_focused = true;
				});
			}

			// Don't set the interval more than once
			if (autosave_interval != null) {
				return;
			}

			// Set an interval to save the form data
			autosave_interval = setInterval (function () {
				if (autosave_focused === false) {
					return;
				}

				var i = 0,
					opts = options,
					vals = [];

				for (i = 0; i < opts.form.elements.length; i++) {
					if (! opts.form.elements[i].name) {
						// Unnamed fields can be ignored (submit buttons)
						continue;
					}
					if (opts.form.elements[i].getAttribute ('id') == 'webpage-body') {
						// Get the contents from Redactor editor
						vals[i] = {
							name: opts.form.elements[i].name,
							value: $('#webpage-body').redactor ('code.get')
						};
					} else if (opts.form.elements[i].getAttribute ('id') == 'code-body') {
						// Get the contents from codemirror editor
						vals[i] = {
							name: opts.form.elements[i].name,
							value: _codemirror.getValue ()
						};
					} else if ($(opts.form.elements[i]).is (':radio') || $(opts.form.elements[i]).is (':checkbox')) {
						if (opts.form.elements[i].checked) {
							vals[i] = {
								name: opts.form.elements[i].name,
								value: true
							};
						} else {
							vals[i] = {
								name: opts.form.elements[i].name,
								value: false
							};
						}
					} else {
						// Get the contents from the field itself
						vals[i] = {
							name: opts.form.elements[i].name,
							value: opts.form.elements[i].value
						};
					}
				}

				var _json = JSON.stringify (vals);
				$.jStorage.set (autosave_key_name, lzw_encode (_json));
			}, options.interval);
		}
	});
})(jQuery);

// The following are from http://jsolait.net/

// LZW-compress a string
function lzw_encode(s) {
    var dict = {};
    var data = (s + "").split("");
    var out = [];
    var currChar;
    var phrase = data[0];
    var code = 256;
    for (var i=1; i<data.length; i++) {
        currChar=data[i];
        if (dict[phrase + currChar] != null) {
            phrase += currChar;
        }
        else {
            out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
            dict[phrase + currChar] = code;
            code++;
            phrase=currChar;
        }
    }
    out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
    for (var i=0; i<out.length; i++) {
        out[i] = String.fromCharCode(out[i]);
    }
    return out.join("");
}

// Decompress an LZW-encoded string
function lzw_decode(s) {
    var dict = {};
    var data = (s + "").split("");
    var currChar = data[0];
    var oldPhrase = currChar;
    var out = [currChar];
    var code = 256;
    var phrase;
    for (var i=1; i<data.length; i++) {
        var currCode = data[i].charCodeAt(0);
        if (currCode < 256) {
            phrase = data[i];
        }
        else {
           phrase = dict[currCode] ? dict[currCode] : (oldPhrase + currChar);
        }
        out.push(phrase);
        currChar = phrase.charAt(0);
        dict[code] = oldPhrase + currChar;
        code++;
        oldPhrase = phrase;
    }
    return out.join("");
}
<|endoftext|>


<commit_before>// Copyright 2013-2016, University of Colorado Boulder

/**
 * A DerivedProperty is computed based on other properties.  This implementation inherits from Property to (a) simplify
 * implementation and (b) ensure it remains consistent. Note that the setters should not be called directly, so the
 * setters (set, reset and es5 setter) throw an error if used directly.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */

define( function( require ) {
  'use strict';

  // modules
  var axon = require( 'AXON/axon' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Property = require( 'AXON/Property' );
  var Tandem = require( 'TANDEM/Tandem' );
  var TDerivedProperty = require( 'AXON/TDerivedProperty' );

  function equalsFunction( a, b ) {
    return a === b;
  }

  function conjunctionWithProperty( value, property ) {
    return value && property.value;
  }

  function disjunctionWithProperty( value, property ) {
    return value || property.value;
  }

  /**
   * @param {Property[]} dependencies - properties that this property's value is derived from
   * @param {function} derivation - function that derives this property's value, expects args in the same order as dependencies
   * @param {Object} [options] - see Property
   * @constructor
   */
  function DerivedProperty( dependencies, derivation, options ) {

    options = _.extend( {
      tandem: Tandem.tandemOptional()
    }, options );

    this.dependencies = dependencies; // @private

    var initialValue = derivation.apply( null, dependencies.map( function( property ) {return property.get();} ) );

    // We must pass supertype tandem to parent class so addInstance is called only once in the subclassiest constructor.
    Property.call( this, initialValue, _.extend( {}, options, {
      tandem: options.tandem && options.tandem.createSupertypeTandem()
    } ) );

    // @private - for disposal
    this.derivedPropertyTandem = options.tandem;

    var self = this;

    // @private Keep track of listeners so they can be detached
    this.dependencyListeners = [];

    for ( var i = 0; i < dependencies.length; i++ ) {
      var dependency = dependencies[ i ];
      (function( dependency ) {
        var listener = function() {
          Property.prototype.set.call( self, derivation.apply( null, dependencies.map( function( property ) {return property.get();} ) ) );
        };
        self.dependencyListeners.push( listener );
        dependency.lazyLink( listener );
      })( dependency, i );
    }

    // If running as phet-io and a tandem is supplied, register with tandem.
    options.tandem.supplied && options.tandem.addInstance( this, TDerivedProperty( options.phetioValueType ), options );
  }

  axon.register( 'DerivedProperty', DerivedProperty );

  return inherit( Property, DerivedProperty, {

    // @public
    dispose: function() {

      // Unlink from dependent properties
      for ( var i = 0; i < this.dependencies.length; i++ ) {
        var dependency = this.dependencies[ i ];
        dependency.unlink( this.dependencyListeners[ i ] );
      }
      this.dependencies = null;
      this.dependencyListeners = null;

      this.derivedPropertyTandem.removeInstance( this );

      Property.prototype.dispose.call( this );
    },

    /**
     * Override the mutators to provide an error message.  These should not be called directly,
     * the value should only be modified when the dependencies change.
     * @param value
     * @override
     * @public
     */
    set: function( value ) { throw new Error( 'Cannot set values directly to a derived property, tried to set: ' + value ); },

    /**
     * Override the mutators to provide an error message.  These should not be called directly, the value should only be modified
     * when the dependencies change. Keep the newValue output in the string so the argument won't be stripped by minifier
     * (which would cause crashes like https://github.com/phetsims/axon/issues/15)
     * @param newValue
     * @override
     * @public
     */
    set value( newValue ) { throw new Error( 'Cannot es5-set values directly to a derived property, tried to set: ' + newValue ); },

    /**
     * Override get value as well to satisfy the linter which wants get/set pairs (even though it just uses the same code as the superclass).
     * @returns {*}
     * @override
     * @public
     */
    get value() {return Property.prototype.get.call( this );},

    /**
     * Override the mutators to provide an error message.  These should not be called directly,
     * the value should only be modified when the dependencies change.
     * @override
     * @public
     */
    reset: function() { throw new Error( 'Cannot reset a derived property directly' ); }
  }, {

    /**
     * Creates a derived boolean property whose value is true iff firstProperty's value is equal to secondProperty's
     * value.
     * @public
     *
     * @param {Property.<*>} firstProperty
     * @param {Property.<*>} secondProperty
     * @param {Object} [options] - Forwarded to the DerivedProperty
     * @returns {DerivedProperty.<boolean>}
     */
    valueEquals: function( firstProperty, secondProperty, options ) {
      return new DerivedProperty( [ firstProperty, secondProperty ], equalsFunction, options );
    },

    /**
     * Creates a derived boolean property whose value is true iff every input property value is true.
     * @public
     *
     * @param {Array.<Property.<boolean>>} properties
     * @param {Object} [options] - Forwarded to the DerivedProperty
     * @returns {DerivedProperty.<boolean>}
     */
    and: function( properties, options ) {
      return new DerivedProperty( properties, _.reduce.bind( null, properties, conjunctionWithProperty, true ), options ); // TODO: fix
    },

    /**
     * Creates a derived boolean property whose value is true iff any input property value is true.
     * @public
     *
     * @param {Array.<Property.<boolean>>} properties
     * @param {Object} [options] - Forwarded to the DerivedProperty
     * @returns {DerivedProperty.<boolean>}
     */
    or: function( properties, options ) {
      return new DerivedProperty( properties, _.reduce.bind( null, properties, disjunctionWithProperty, false ), options );
    }
  } );
} );<commit_msg>property -> Property throughout documentation<commit_after>// Copyright 2013-2016, University of Colorado Boulder

/**
 * A DerivedProperty is computed based on other Properties.  This implementation inherits from Property to (a) simplify
 * implementation and (b) ensure it remains consistent. Note that the setters should not be called directly, so the
 * setters (set, reset and es5 setter) throw an error if used directly.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */

define( function( require ) {
  'use strict';

  // modules
  var axon = require( 'AXON/axon' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Property = require( 'AXON/Property' );
  var Tandem = require( 'TANDEM/Tandem' );
  var TDerivedProperty = require( 'AXON/TDerivedProperty' );

  function equalsFunction( a, b ) {
    return a === b;
  }

  function conjunctionWithProperty( value, property ) {
    return value && property.value;
  }

  function disjunctionWithProperty( value, property ) {
    return value || property.value;
  }

  /**
   * @param {Property[]} dependencies - Properties that this Property's value is derived from
   * @param {function} derivation - function that derives this Property's value, expects args in the same order as dependencies
   * @param {Object} [options] - see Property
   * @constructor
   */
  function DerivedProperty( dependencies, derivation, options ) {

    options = _.extend( {
      tandem: Tandem.tandemOptional()
    }, options );

    this.dependencies = dependencies; // @private

    var initialValue = derivation.apply( null, dependencies.map( function( property ) {return property.get();} ) );

    // We must pass supertype tandem to parent class so addInstance is called only once in the subclassiest constructor.
    Property.call( this, initialValue, _.extend( {}, options, {
      tandem: options.tandem && options.tandem.createSupertypeTandem()
    } ) );

    // @private - for disposal
    this.derivedPropertyTandem = options.tandem;

    var self = this;

    // @private Keep track of listeners so they can be detached
    this.dependencyListeners = [];

    for ( var i = 0; i < dependencies.length; i++ ) {
      var dependency = dependencies[ i ];
      (function( dependency ) {
        var listener = function() {
          Property.prototype.set.call( self, derivation.apply( null, dependencies.map( function( property ) {return property.get();} ) ) );
        };
        self.dependencyListeners.push( listener );
        dependency.lazyLink( listener );
      })( dependency, i );
    }

    // If running as phet-io and a tandem is supplied, register with tandem.
    options.tandem.supplied && options.tandem.addInstance( this, TDerivedProperty( options.phetioValueType ), options );
  }

  axon.register( 'DerivedProperty', DerivedProperty );

  return inherit( Property, DerivedProperty, {

    // @public
    dispose: function() {

      // Unlink from dependent Properties
      for ( var i = 0; i < this.dependencies.length; i++ ) {
        var dependency = this.dependencies[ i ];
        dependency.unlink( this.dependencyListeners[ i ] );
      }
      this.dependencies = null;
      this.dependencyListeners = null;

      this.derivedPropertyTandem.removeInstance( this );

      Property.prototype.dispose.call( this );
    },

    /**
     * Override the mutators to provide an error message.  These should not be called directly,
     * the value should only be modified when the dependencies change.
     * @param value
     * @override
     * @public
     */
    set: function( value ) { throw new Error( 'Cannot set values directly to a DerivedProperty, tried to set: ' + value ); },

    /**
     * Override the mutators to provide an error message.  These should not be called directly, the value should only be modified
     * when the dependencies change. Keep the newValue output in the string so the argument won't be stripped by minifier
     * (which would cause crashes like https://github.com/phetsims/axon/issues/15)
     * @param newValue
     * @override
     * @public
     */
    set value( newValue ) { throw new Error( 'Cannot es5-set values directly to a DerivedProperty, tried to set: ' + newValue ); },

    /**
     * Override get value as well to satisfy the linter which wants get/set pairs (even though it just uses the same code as the superclass).
     * @returns {*}
     * @override
     * @public
     */
    get value() {return Property.prototype.get.call( this );},

    /**
     * Override the mutators to provide an error message.  These should not be called directly,
     * the value should only be modified when the dependencies change.
     * @override
     * @public
     */
    reset: function() { throw new Error( 'Cannot reset a DerivedProperty directly' ); }
  }, {

    /**
     * Creates a derived boolean Property whose value is true iff firstProperty's value is equal to secondProperty's
     * value.
     * @public
     *
     * @param {Property.<*>} firstProperty
     * @param {Property.<*>} secondProperty
     * @param {Object} [options] - Forwarded to the DerivedProperty
     * @returns {DerivedProperty.<boolean>}
     */
    valueEquals: function( firstProperty, secondProperty, options ) {
      return new DerivedProperty( [ firstProperty, secondProperty ], equalsFunction, options );
    },

    /**
     * Creates a derived boolean Property whose value is true iff every input Property value is true.
     * @public
     *
     * @param {Array.<Property.<boolean>>} properties
     * @param {Object} [options] - Forwarded to the DerivedProperty
     * @returns {DerivedProperty.<boolean>}
     */
    and: function( properties, options ) {
      return new DerivedProperty( properties, _.reduce.bind( null, properties, conjunctionWithProperty, true ), options ); // TODO: fix
    },

    /**
     * Creates a derived boolean Property whose value is true iff any input Property value is true.
     * @public
     *
     * @param {Array.<Property.<boolean>>} properties
     * @param {Object} [options] - Forwarded to the DerivedProperty
     * @returns {DerivedProperty.<boolean>}
     */
    or: function( properties, options ) {
      return new DerivedProperty( properties, _.reduce.bind( null, properties, disjunctionWithProperty, false ), options );
    }
  } );
} );<|endoftext|>


<commit_before>/* ------------------------------------------------------------------------------
 VideoSub v0.9.6

 Original MooTools implementation by [Thomas Sturm](http://www.storiesinflight.com)
 jQuery port by [Max Wheeler](http://www.icelab.com.au)
 Freeware, Attribution Appreciated
 ------------------------------------------------------------------------------ */
(function($) {
    var ajax = $.ajax;
    var tcsecs, timecode_max, timecode_min;
    var css_normal = {
        'position': 'absolute',
        'bottom': '40px',
        'padding': '0 55px',
        'text-align': 'center',
        'color': 'yellow',
        'font-family': 'Helvetica, Arial, sans-serif',
        'font-size': '24px',
        'font-weight': 'normal',
        'text-shadow': '#000000 1px 1px 0px',
        'z-index':'2147483648',
        'left': '0px'
    };
    var css_fullscreen = {
        'position': 'absolute',
        'bottom': '40px',
        'padding': '0px 55px',
        'text-align': 'center',
        'color': 'yellow',
        'font-family': 'Helvetica, Arial, sans-serif',
        'font-size': '34px',
        'font-weight': 'normal',
        'text-shadow': 'rgb(0, 0, 0) 1px 1px 0px',
        'z-index': '2147483648',
        'left': '200px'
    };
    $.fn.videoSub = function(options) {
        var _a, opts;
        if (typeof (typeof (_a = $('<video>').addtrack) !== "undefined" && _a !== null)) {
            opts = $.extend({}, $.fn.videoSub.defaults, options);
            return this.each(function() {
                var $this, _a, bar, container, el, o, src, $body;
                $body = $('body');
                el = this;
                $this = $(this);
                o = (typeof (_a = $.meta) !== "undefined" && _a !== null) ? $.extend(opts, $this.data()) : opts;
                src = $('track', this).attr('src');
                if (typeof src !== "undefined" && src !== null) {
                    container = $('
');
                    container.css('position', 'relative');
                    container = $this.wrap(container).parent();
                    bar = $('
');
                    if (o.useBarDefaultStyle) {
                        bar.css(css_normal);
                        bar.css('width',$this.outerWidth() - 40);
                    }
                    bar.css('left', parseInt(''+(0.625*(parseInt($body.css('width'),10) - 1280)),10)+'px');
                    bar = bar.appendTo(container);
                    el.subtitles = [];
                    el.subcount = 0;
                    el.update = function(req) {
                        var r, records;
                        records = req.replace(/(\r\n|\r|\n)/g, '\n').split('\n\n');
                        r = 0;
                        $(records).each(function(i) {
                            var splits = records[i].split('\n');
                            if (splits.length >= 3) {
                                el.subtitles[r] = [];
                                return (el.subtitles[r++] = splits);
                            }
                        });

                        $this.bind('webkitfullscreenchange',function(e){
                            if (document.webkitIsFullScreen === true) {
                                if (o.useBarDefaultStyle) {
                                    bar.css(css_fullscreen);
                                    var left = parseInt(''+(0.4375*(parseInt($this.outerWidth(),10) - 1280)+200),10)+'px';
                                    bar.css('left', left);
                                }
                            }else {
                                if (o.useBarDefaultStyle){
                                    bar.css(css_normal);
                                    var left = parseInt(''+(0.375*(parseInt($body.css('width'),10) - 1280)),10)+'px';
                                    bar.css('left', left);
                                }
                            }
                        });

                        $this.bind('play', function(e) {
                            return true;//(el.subcount = 0);
                        });
                        $this.bind('ended', function(e) {
                            return true;//(el.subcount = 0);
                        });
                        $this.bind('seeked', function(e) {
                            var _b;
                            el.subcount = 0;
                            _b = [];
                            while (timecode_max(el.subtitles[el.subcount][1]) < el.currentTime.toFixed(1)) {
                                el.subcount++;
                                if (el.subcount > el.subtitles.length - 1) {
                                    el.subcount = el.subtitles.length - 1;
                                    break;
                                }
                            }
                            return _b;
                        });
                        return $this.bind('timeupdate', function(e) {
                            var subtitle;
                            subtitle = '';
                            if (el.currentTime.toFixed(1) > timecode_min(el.subtitles[el.subcount][1]) && el.currentTime.toFixed(1) < timecode_max(el.subtitles[el.subcount][1])) {
                                subtitle = el.subtitles[el.subcount][2];
                                if (el.subtitles[el.subcount][3]) subtitle += '
' + el.subtitles[el.subcount][3];
                                if (el.subtitles[el.subcount][4]) subtitle += '
' + el.subtitles[el.subcount][4];
                            }
                            if (el.currentTime.toFixed(1) > timecode_max(el.subtitles[el.subcount][1]) && el.subcount < (el.subtitles.length - 1)) {
                                el.subcount++;
                            }
                            return bar.html(subtitle);
                        });
                    };
                    EWS.enable(true);
                    return ajax({
                        type: 'GET',
                        url: src,
                        success: el.update
                    });
                }
            });
        }
    };
    timecode_min = function(tc) {
        var tcpair;
        tcpair = tc.split(' --> ');
        return tcsecs(tcpair[0]);
    };
    timecode_max = function(tc) {
        var tcpair;
        tcpair = tc.split(' --> ');
        return tcsecs(tcpair[1]);
    };
    tcsecs = function(tc) {
        var secs, tc1, tc2;
        tc1 = tc.split(',');
        tc2 = tc1[0].split(':');
        return (secs = Math.floor(tc2[0] * 60 * 60) + Math.floor(tc2[1] * 60) + Math.floor(tc2[2]));
    };
    $.fn.videoSub.defaults = {
        containerClass: 'videosub-container',
        barClass: 'videosub-bar',
        useBarDefaultStyle: true
    };
})(jQuery);<commit_msg>Update subtitle position[3]<commit_after>/* ------------------------------------------------------------------------------
 VideoSub v0.9.6

 Original MooTools implementation by [Thomas Sturm](http://www.storiesinflight.com)
 jQuery port by [Max Wheeler](http://www.icelab.com.au)
 Freeware, Attribution Appreciated
 ------------------------------------------------------------------------------ */
(function($) {
    var ajax = $.ajax;
    var tcsecs, timecode_max, timecode_min;
    var css_normal = {
        'position': 'absolute',
        'bottom': '40px',
        'padding': '0 55px',
        'text-align': 'center',
        'color': 'yellow',
        'font-family': 'Helvetica, Arial, sans-serif',
        'font-size': '24px',
        'font-weight': 'normal',
        'text-shadow': '#000000 1px 1px 0px',
        'z-index':'2147483648',
        'left': '0px'
    };
    var css_fullscreen = {
        'position': 'absolute',
        'bottom': '40px',
        'padding': '0px 55px',
        'text-align': 'center',
        'color': 'yellow',
        'font-family': 'Helvetica, Arial, sans-serif',
        'font-size': '34px',
        'font-weight': 'normal',
        'text-shadow': 'rgb(0, 0, 0) 1px 1px 0px',
        'z-index': '2147483648',
        'left': '200px'
    };
    $.fn.videoSub = function(options) {
        var _a, opts;
        if (typeof (typeof (_a = $('<video>').addtrack) !== "undefined" && _a !== null)) {
            opts = $.extend({}, $.fn.videoSub.defaults, options);
            return this.each(function() {
                var $this, _a, bar, container, el, o, src, $body;
                $body = $('body');
                el = this;
                $this = $(this);
                o = (typeof (_a = $.meta) !== "undefined" && _a !== null) ? $.extend(opts, $this.data()) : opts;
                src = $('track', this).attr('src');
                if (typeof src !== "undefined" && src !== null) {
                    container = $('
');
                    container.css('position', 'relative');
                    container = $this.wrap(container).parent();
                    bar = $('
');
                    if (o.useBarDefaultStyle) {
                        bar.css(css_normal);
                        bar.css('width',$this.outerWidth() - 40);
                    }
                    bar.css('left', parseInt(''+(0.375*(parseInt($body.css('width'),10) - 1280)),10)+'px');
                    bar = bar.appendTo(container);
                    el.subtitles = [];
                    el.subcount = 0;
                    el.update = function(req) {
                        var r, records;
                        records = req.replace(/(\r\n|\r|\n)/g, '\n').split('\n\n');
                        r = 0;
                        $(records).each(function(i) {
                            var splits = records[i].split('\n');
                            if (splits.length >= 3) {
                                el.subtitles[r] = [];
                                return (el.subtitles[r++] = splits);
                            }
                        });

                        $this.bind('webkitfullscreenchange',function(e){
                            if (document.webkitIsFullScreen === true) {
                                if (o.useBarDefaultStyle) {
                                    bar.css(css_fullscreen);
                                    var left = parseInt(''+(0.4375*(parseInt($this.outerWidth(),10) - 1280)+200),10)+'px';
                                    bar.css('left', left);
                                }
                            }else {
                                if (o.useBarDefaultStyle){
                                    bar.css(css_normal);
                                    var left = parseInt(''+(0.375*(parseInt($body.css('width'),10) - 1280)),10)+'px';
                                    bar.css('left', left);
                                }
                            }
                        });

                        $this.bind('play', function(e) {
                            return true;//(el.subcount = 0);
                        });
                        $this.bind('ended', function(e) {
                            return true;//(el.subcount = 0);
                        });
                        $this.bind('seeked', function(e) {
                            var _b;
                            el.subcount = 0;
                            _b = [];
                            while (timecode_max(el.subtitles[el.subcount][1]) < el.currentTime.toFixed(1)) {
                                el.subcount++;
                                if (el.subcount > el.subtitles.length - 1) {
                                    el.subcount = el.subtitles.length - 1;
                                    break;
                                }
                            }
                            return _b;
                        });
                        return $this.bind('timeupdate', function(e) {
                            var subtitle;
                            subtitle = '';
                            if (el.currentTime.toFixed(1) > timecode_min(el.subtitles[el.subcount][1]) && el.currentTime.toFixed(1) < timecode_max(el.subtitles[el.subcount][1])) {
                                subtitle = el.subtitles[el.subcount][2];
                                if (el.subtitles[el.subcount][3]) subtitle += '
' + el.subtitles[el.subcount][3];
                                if (el.subtitles[el.subcount][4]) subtitle += '
' + el.subtitles[el.subcount][4];
                            }
                            if (el.currentTime.toFixed(1) > timecode_max(el.subtitles[el.subcount][1]) && el.subcount < (el.subtitles.length - 1)) {
                                el.subcount++;
                            }
                            return bar.html(subtitle);
                        });
                    };
                    EWS.enable(true);
                    return ajax({
                        type: 'GET',
                        url: src,
                        success: el.update
                    });
                }
            });
        }
    };
    timecode_min = function(tc) {
        var tcpair;
        tcpair = tc.split(' --> ');
        return tcsecs(tcpair[0]);
    };
    timecode_max = function(tc) {
        var tcpair;
        tcpair = tc.split(' --> ');
        return tcsecs(tcpair[1]);
    };
    tcsecs = function(tc) {
        var secs, tc1, tc2;
        tc1 = tc.split(',');
        tc2 = tc1[0].split(':');
        return (secs = Math.floor(tc2[0] * 60 * 60) + Math.floor(tc2[1] * 60) + Math.floor(tc2[2]));
    };
    $.fn.videoSub.defaults = {
        containerClass: 'videosub-container',
        barClass: 'videosub-bar',
        useBarDefaultStyle: true
    };
})(jQuery);<|endoftext|>


<commit_before>/**
 * @name Sidebar
 * @class L.Control.Sidebar
 * @extends L.Control
 * @param {string} id - The id of the sidebar element (without the # character)
 * @param {Object} [options] - Optional options object
 * @param {string} [options.position=left] - Position of the sidebar: 'left' or 'right'
 * @see L.control.sidebar
 */
L.Control.Sidebar = L.Control.extend(/** @lends L.Control.Sidebar.prototype */ {
    includes: L.Mixin.Events,

    options: {
        position: 'left'
    },

    initialize: function (id, options) {
        var i, child;

        L.setOptions(this, options);

        // Find sidebar HTMLElement
        this._sidebar = L.DomUtil.get(id);

        // Attach .sidebar-left/right class
        L.DomUtil.addClass(this._sidebar, 'sidebar-' + this.options.position);

        // Attach touch styling if necessary
        if (L.Browser.touch)
            L.DomUtil.addClass(this._sidebar, 'leaflet-touch');

        // Find sidebar > div.sidebar-content
        for (i = this._sidebar.children.length - 1; i >= 0; i--) {
            child = this._sidebar.children[i];
            if (child.tagName == 'DIV' &&
                    L.DomUtil.hasClass(child, 'sidebar-content'))
                this._container = child;
        }

        // Find sidebar ul.sidebar-tabs > li, sidebar .sidebar-tabs > ul > li
        this._tabitems = this._sidebar.querySelectorAll('ul.sidebar-tabs > li, .sidebar-tabs > ul > li');
        for (i = this._tabitems.length - 1; i >= 0; i--) {
            this._tabitems[i]._sidebar = this;
        }

        // Find sidebar > div.sidebar-content > div.sidebar-pane
        this._panes = [];
        this._closeButtons = [];
        for (i = this._container.children.length - 1; i >= 0; i--) {
            child = this._container.children[i];
            if (child.tagName == 'DIV' &&
                L.DomUtil.hasClass(child, 'sidebar-pane')) {
                this._panes.push(child);

                var closeButtons = child.querySelectorAll('.sidebar-close');
                for (var j = 0, len = closeButtons.length; j < len; j++)
                    this._closeButtons.push(closeButtons[j]);
            }
        }
    },

    /**
     * Add this sidebar to the specified map.
     *
     * @param {L.Map} map
     * @returns {Sidebar}
     */
    addTo: function (map) {
        var i, child;

        this._map = map;

        for (i = this._tabitems.length - 1; i >= 0; i--) {
            child = this._tabitems[i];
            var sub = child.querySelector('a');
            if (sub.hasAttribute('href') && sub.getAttribute('href').slice(0,1) == '#') {
                L.DomEvent
                    .on(sub, 'click', L.DomEvent.preventDefault )
                    .on(sub, 'click', this._onClick, child);
            }

        }

        for (i = this._closeButtons.length - 1; i >= 0; i--) {
            child = this._closeButtons[i];
            L.DomEvent.on(child, 'click', this._onCloseClick, this);
        }

        return this;
    },

    /**
     * @deprecated - Please use remove() instead of removeFrom(), as of Leaflet 0.8-dev, the removeFrom() has been replaced with remove()
     * Removes this sidebar from the map.
     * @param {L.Map} map
     * @returns {Sidebar}
     */
     removeFrom: function(map) {
         console.log('removeFrom() has been deprecated, please use remove() instead as support for this function will be ending soon.');
         this.remove(map);
     },

    /**
     * Remove this sidebar from the map.
     *
     * @param {L.Map} map
     * @returns {Sidebar}
     */
    remove: function (map) {
        var i, child;

        this._map = null;

        for (i = this._tabitems.length - 1; i >= 0; i--) {
            child = this._tabitems[i];
            L.DomEvent.off(child.querySelector('a'), 'click', this._onClick);
        }

        for (i = this._closeButtons.length - 1; i >= 0; i--) {
            child = this._closeButtons[i];
            L.DomEvent.off(child, 'click', this._onCloseClick, this);
        }

        return this;
    },

    /**
     * Open sidebar (if necessary) and show the specified tab.
     *
     * @param {string} id - The id of the tab to show (without the # character)
     */
    open: function(id) {
        var i, child;

        // hide old active contents and show new content
        for (i = this._panes.length - 1; i >= 0; i--) {
            child = this._panes[i];
            if (child.id == id)
                L.DomUtil.addClass(child, 'active');
            else if (L.DomUtil.hasClass(child, 'active'))
                L.DomUtil.removeClass(child, 'active');
        }

        // remove old active highlights and set new highlight
        for (i = this._tabitems.length - 1; i >= 0; i--) {
            child = this._tabitems[i];
            if (child.querySelector('a').hash == '#' + id)
                L.DomUtil.addClass(child, 'active');
            else if (L.DomUtil.hasClass(child, 'active'))
                L.DomUtil.removeClass(child, 'active');
        }

        this.fire('content', { id: id });

        // open sidebar (if necessary)
        if (L.DomUtil.hasClass(this._sidebar, 'collapsed')) {
            this.fire('opening');
            L.DomUtil.removeClass(this._sidebar, 'collapsed');
        }

        return this;
    },

    /**
     * Close the sidebar (if necessary).
     */
    close: function() {
        // remove old active highlights
        for (var i = this._tabitems.length - 1; i >= 0; i--) {
            var child = this._tabitems[i];
            if (L.DomUtil.hasClass(child, 'active'))
                L.DomUtil.removeClass(child, 'active');
        }

        // close sidebar
        if (!L.DomUtil.hasClass(this._sidebar, 'collapsed')) {
            this.fire('closing');
            L.DomUtil.addClass(this._sidebar, 'collapsed');
        }

        return this;
    },

    /**
     * @private
     */
    _onClick: function() {
        if (L.DomUtil.hasClass(this, 'active'))
            this._sidebar.close();
        else if (!L.DomUtil.hasClass(this, 'disabled'))
            this._sidebar.open(this.querySelector('a').hash.slice(1));
    },

    /**
     * @private
     */
    _onCloseClick: function () {
        this.close();
    }
});

/**
 * Creates a new sidebar.
 *
 * @example
 * var sidebar = L.control.sidebar('sidebar').addTo(map);
 *
 * @param {string} id - The id of the sidebar element (without the # character)
 * @param {Object} [options] - Optional options object
 * @param {string} [options.position=left] - Position of the sidebar: 'left' or 'right'
 * @returns {Sidebar} A new sidebar instance
 */
L.control.sidebar = function (id, options) {
    return new L.Control.Sidebar(id, options);
};
<commit_msg>leaflet-sidebar: fix formatting<commit_after>/**
 * @name Sidebar
 * @class L.Control.Sidebar
 * @extends L.Control
 * @param {string} id - The id of the sidebar element (without the # character)
 * @param {Object} [options] - Optional options object
 * @param {string} [options.position=left] - Position of the sidebar: 'left' or 'right'
 * @see L.control.sidebar
 */
L.Control.Sidebar = L.Control.extend(/** @lends L.Control.Sidebar.prototype */ {
    includes: L.Mixin.Events,

    options: {
        position: 'left'
    },

    initialize: function (id, options) {
        var i, child;

        L.setOptions(this, options);

        // Find sidebar HTMLElement
        this._sidebar = L.DomUtil.get(id);

        // Attach .sidebar-left/right class
        L.DomUtil.addClass(this._sidebar, 'sidebar-' + this.options.position);

        // Attach touch styling if necessary
        if (L.Browser.touch)
            L.DomUtil.addClass(this._sidebar, 'leaflet-touch');

        // Find sidebar > div.sidebar-content
        for (i = this._sidebar.children.length - 1; i >= 0; i--) {
            child = this._sidebar.children[i];
            if (child.tagName == 'DIV' &&
                    L.DomUtil.hasClass(child, 'sidebar-content'))
                this._container = child;
        }

        // Find sidebar ul.sidebar-tabs > li, sidebar .sidebar-tabs > ul > li
        this._tabitems = this._sidebar.querySelectorAll('ul.sidebar-tabs > li, .sidebar-tabs > ul > li');
        for (i = this._tabitems.length - 1; i >= 0; i--) {
            this._tabitems[i]._sidebar = this;
        }

        // Find sidebar > div.sidebar-content > div.sidebar-pane
        this._panes = [];
        this._closeButtons = [];
        for (i = this._container.children.length - 1; i >= 0; i--) {
            child = this._container.children[i];
            if (child.tagName == 'DIV' &&
                L.DomUtil.hasClass(child, 'sidebar-pane')) {
                this._panes.push(child);

                var closeButtons = child.querySelectorAll('.sidebar-close');
                for (var j = 0, len = closeButtons.length; j < len; j++)
                    this._closeButtons.push(closeButtons[j]);
            }
        }
    },

    /**
     * Add this sidebar to the specified map.
     *
     * @param {L.Map} map
     * @returns {Sidebar}
     */
    addTo: function (map) {
        var i, child;

        this._map = map;

        for (i = this._tabitems.length - 1; i >= 0; i--) {
            child = this._tabitems[i];
            var sub = child.querySelector('a');
            if (sub.hasAttribute('href') && sub.getAttribute('href').slice(0,1) == '#') {
                L.DomEvent
                    .on(sub, 'click', L.DomEvent.preventDefault )
                    .on(sub, 'click', this._onClick, child);
            }
        }

        for (i = this._closeButtons.length - 1; i >= 0; i--) {
            child = this._closeButtons[i];
            L.DomEvent.on(child, 'click', this._onCloseClick, this);
        }

        return this;
    },

    /**
     * @deprecated - Please use remove() instead of removeFrom(), as of Leaflet 0.8-dev, the removeFrom() has been replaced with remove()
     * Removes this sidebar from the map.
     * @param {L.Map} map
     * @returns {Sidebar}
     */
     removeFrom: function(map) {
         console.log('removeFrom() has been deprecated, please use remove() instead as support for this function will be ending soon.');
         this.remove(map);
     },

    /**
     * Remove this sidebar from the map.
     *
     * @param {L.Map} map
     * @returns {Sidebar}
     */
    remove: function (map) {
        var i, child;

        this._map = null;

        for (i = this._tabitems.length - 1; i >= 0; i--) {
            child = this._tabitems[i];
            L.DomEvent.off(child.querySelector('a'), 'click', this._onClick);
        }

        for (i = this._closeButtons.length - 1; i >= 0; i--) {
            child = this._closeButtons[i];
            L.DomEvent.off(child, 'click', this._onCloseClick, this);
        }

        return this;
    },

    /**
     * Open sidebar (if necessary) and show the specified tab.
     *
     * @param {string} id - The id of the tab to show (without the # character)
     */
    open: function(id) {
        var i, child;

        // hide old active contents and show new content
        for (i = this._panes.length - 1; i >= 0; i--) {
            child = this._panes[i];
            if (child.id == id)
                L.DomUtil.addClass(child, 'active');
            else if (L.DomUtil.hasClass(child, 'active'))
                L.DomUtil.removeClass(child, 'active');
        }

        // remove old active highlights and set new highlight
        for (i = this._tabitems.length - 1; i >= 0; i--) {
            child = this._tabitems[i];
            if (child.querySelector('a').hash == '#' + id)
                L.DomUtil.addClass(child, 'active');
            else if (L.DomUtil.hasClass(child, 'active'))
                L.DomUtil.removeClass(child, 'active');
        }

        this.fire('content', { id: id });

        // open sidebar (if necessary)
        if (L.DomUtil.hasClass(this._sidebar, 'collapsed')) {
            this.fire('opening');
            L.DomUtil.removeClass(this._sidebar, 'collapsed');
        }

        return this;
    },

    /**
     * Close the sidebar (if necessary).
     */
    close: function() {
        // remove old active highlights
        for (var i = this._tabitems.length - 1; i >= 0; i--) {
            var child = this._tabitems[i];
            if (L.DomUtil.hasClass(child, 'active'))
                L.DomUtil.removeClass(child, 'active');
        }

        // close sidebar
        if (!L.DomUtil.hasClass(this._sidebar, 'collapsed')) {
            this.fire('closing');
            L.DomUtil.addClass(this._sidebar, 'collapsed');
        }

        return this;
    },

    /**
     * @private
     */
    _onClick: function() {
        if (L.DomUtil.hasClass(this, 'active'))
            this._sidebar.close();
        else if (!L.DomUtil.hasClass(this, 'disabled'))
            this._sidebar.open(this.querySelector('a').hash.slice(1));
    },

    /**
     * @private
     */
    _onCloseClick: function () {
        this.close();
    }
});

/**
 * Creates a new sidebar.
 *
 * @example
 * var sidebar = L.control.sidebar('sidebar').addTo(map);
 *
 * @param {string} id - The id of the sidebar element (without the # character)
 * @param {Object} [options] - Optional options object
 * @param {string} [options.position=left] - Position of the sidebar: 'left' or 'right'
 * @returns {Sidebar} A new sidebar instance
 */
L.control.sidebar = function (id, options) {
    return new L.Control.Sidebar(id, options);
};
<|endoftext|>


<commit_before>/* @flow */
import Relay from 'react-relay/classic';
export type FetchQueryFunction = (query: {query: string, variables: Object}) => Promise<{errors?: Array<Object>, data?: Object}>;

export type QueryRequest = {
    getQueryString: () => string,
    getVariables: () => Object,
    getID: () => string,
    getQuery: () => Relay.QL,
    resolve: (data: any) => void,
    reject: (error: any) => void,
    then: (onResolve: (result: {response: any}) => void, onReject: ?() => void) => Promise<*>
};

// A simple network layer that calls the passed in function to run a query and collects results
export default class ServerNetworkLayer {
    queryResults = {};
    _fetchQuery: FetchQueryFunction;

    constructor(fetchQuery: FetchQueryFunction) {
        this._fetchQuery = fetchQuery;
    }

    supports() {}

    sendQueries(queryRequests: QueryRequest[]) {
        return Promise.all(queryRequests.map(this._sendQuery));
    }

    _sendQuery = (queryRequest: QueryRequest) => {
        return new Promise((resolve, reject) => {
            this._fetchQuery({
                query: queryRequest.getQueryString(),
                variables: queryRequest.getVariables()
            }).then((response) => {
                const {data} = response;
                if ('errors' in response || !data) {
                    const queryName = queryRequest.getQuery().getName();
                    var errorMsg = `Server Error (${queryName})`;
                    try {
                        errorMsg += ` ${JSON.stringify(response.errors)}`;
                    } catch (err) {} // eslint-disable-line no-empty
                    const error = new Error(errorMsg);
                    queryRequest.reject(error);
                    reject(error);
                } else {
                    queryRequest.resolve({response: data});
                    resolve(data);
                    this.queryResults[queryRequest.getID()] = data;
                }
            });
        });
    }
}
<commit_msg>Remove promises from sendQueries<commit_after>/* @flow */
import Relay from 'react-relay/classic';
export type FetchQueryFunction = (query: {query: string, variables: Object}) => Promise<{errors?: Array<Object>, data?: Object}>;

export type QueryRequest = {
    getQueryString: () => string,
    getVariables: () => Object,
    getID: () => string,
    getQuery: () => Relay.QL,
    resolve: (data: any) => void,
    reject: (error: any) => void,
    then: (onResolve: (result: {response: any}) => void, onReject: ?() => void) => Promise<*>
};

// A simple network layer that calls the passed in function to run a query and collects results
export default class ServerNetworkLayer {
    queryResults = {};
    _fetchQuery: FetchQueryFunction;

    constructor(fetchQuery: FetchQueryFunction) {
        this._fetchQuery = fetchQuery;
    }

    supports() {}

    sendQueries(queryRequests: QueryRequest[]) {
        queryRequests.forEach(this._sendQuery);
    }

    _sendQuery = (queryRequest: QueryRequest) => {
        this._fetchQuery({
            query: queryRequest.getQueryString(),
            variables: queryRequest.getVariables()
        }).then((response) => {
            const {data} = response;
            if ('errors' in response || !data) {
                const queryName = queryRequest.getQuery().getName();
                var errorMsg = `Server Error (${queryName})`;
                try {
                    errorMsg += ` ${JSON.stringify(response.errors)}`;
                } catch (err) {} // eslint-disable-line no-empty
                const error = new Error(errorMsg);
                queryRequest.reject(error);
            } else {
                queryRequest.resolve({response: data});
                this.queryResults[queryRequest.getID()] = data;
            }
        });
    }
}
<|endoftext|>