").append( jQuery.parseHTML( responseText ) ).find( selector ) :
-
- // Otherwise use the full result
- responseText );
-
- }).complete( callback && function( jqXHR, status ) {
- self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
- });
+ // Create converters map with lowercased keys
+ if ( dataTypes[ 1 ] ) {
+ for ( conv in s.converters ) {
+ converters[ conv.toLowerCase() ] = s.converters[ conv ];
+ }
}
- return this;
-};
+ current = dataTypes.shift();
-// Attach a bunch of functions for handling common AJAX events
-jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
- jQuery.fn[ type ] = function( fn ){
- return this.on( type, fn );
- };
-});
+ // Convert to each sequential dataType
+ while ( current ) {
+
+ if ( s.responseFields[ current ] ) {
+ jqXHR[ s.responseFields[ current ] ] = response;
+ }
+
+ // Apply the dataFilter if provided
+ if ( !prev && isSuccess && s.dataFilter ) {
+ response = s.dataFilter( response, s.dataType );
+ }
+
+ prev = current;
+ current = dataTypes.shift();
+
+ if ( current ) {
+
+ // There's only work to do if current dataType is non-auto
+ if ( current === "*" ) {
+
+ current = prev;
+
+ // Convert response if prev dataType is non-auto and differs from current
+ } else if ( prev !== "*" && prev !== current ) {
+
+ // Seek a direct converter
+ conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+
+ // If none found, seek a pair
+ if ( !conv ) {
+ for ( conv2 in converters ) {
+
+ // If conv2 outputs current
+ tmp = conv2.split( " " );
+ if ( tmp[ 1 ] === current ) {
+
+ // If prev can be converted to accepted input
+ conv = converters[ prev + " " + tmp[ 0 ] ] ||
+ converters[ "* " + tmp[ 0 ] ];
+ if ( conv ) {
+ // Condense equivalence converters
+ if ( conv === true ) {
+ conv = converters[ conv2 ];
+
+ // Otherwise, insert the intermediate dataType
+ } else if ( converters[ conv2 ] !== true ) {
+ current = tmp[ 0 ];
+ dataTypes.unshift( tmp[ 1 ] );
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ // Apply converter (if not an equivalence)
+ if ( conv !== true ) {
+
+ // Unless errors are allowed to bubble, catch and return them
+ if ( conv && s[ "throws" ] ) {
+ response = conv( response );
+ } else {
+ try {
+ response = conv( response );
+ } catch ( e ) {
+ return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return { state: "success", data: response };
+}
jQuery.extend({
@@ -7169,7 +8020,7 @@ jQuery.extend({
s.type = options.method || options.type || s.method || s.type;
// Extract dataTypes list
- s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""];
+ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
// A cross-domain request is in order when we have a protocol:host:port mismatch
if ( s.crossDomain == null ) {
@@ -7217,7 +8068,7 @@ jQuery.extend({
// If data is available, append data to url
if ( s.data ) {
- cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
+ cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
// #9682: remove data so that it's not used in an eventual retry
delete s.data;
}
@@ -7227,10 +8078,10 @@ jQuery.extend({
s.url = rts.test( cacheURL ) ?
// If there is already a '_' parameter, set its value
- cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :
+ cacheURL.replace( rts, "$1_=" + nonce++ ) :
// Otherwise add one to the end
- cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;
+ cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
}
}
@@ -7454,156 +8305,342 @@ jQuery.each( [ "get", "post" ], function( i, method ) {
};
});
-/* Handles responses to an ajax request:
- * - finds the right dataType (mediates between content-type and expected dataType)
- * - returns the corresponding response
- */
-function ajaxHandleResponses( s, jqXHR, responses ) {
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
+ jQuery.fn[ type ] = function( fn ) {
+ return this.on( type, fn );
+ };
+});
- var ct, type, finalDataType, firstDataType,
- contents = s.contents,
- dataTypes = s.dataTypes;
- // Remove auto dataType and get content-type in the process
- while( dataTypes[ 0 ] === "*" ) {
- dataTypes.shift();
- if ( ct === undefined ) {
- ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
+jQuery._evalUrl = function( url ) {
+ return jQuery.ajax({
+ url: url,
+ type: "GET",
+ dataType: "script",
+ async: false,
+ global: false,
+ "throws": true
+ });
+};
+
+
+jQuery.fn.extend({
+ wrapAll: function( html ) {
+ var wrap;
+
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function( i ) {
+ jQuery( this ).wrapAll( html.call(this, i) );
+ });
}
- }
- // Check if we're dealing with a known content-type
- if ( ct ) {
- for ( type in contents ) {
- if ( contents[ type ] && contents[ type ].test( ct ) ) {
- dataTypes.unshift( type );
- break;
+ if ( this[ 0 ] ) {
+
+ // The elements to wrap the target around
+ wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
+
+ if ( this[ 0 ].parentNode ) {
+ wrap.insertBefore( this[ 0 ] );
}
- }
- }
- // Check to see if we have a response for the expected dataType
- if ( dataTypes[ 0 ] in responses ) {
- finalDataType = dataTypes[ 0 ];
+ wrap.map(function() {
+ var elem = this;
+
+ while ( elem.firstElementChild ) {
+ elem = elem.firstElementChild;
+ }
+
+ return elem;
+ }).append( this );
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function( i ) {
+ jQuery( this ).wrapInner( html.call(this, i) );
+ });
+ }
+
+ return this.each(function() {
+ var self = jQuery( this ),
+ contents = self.contents();
+
+ if ( contents.length ) {
+ contents.wrapAll( html );
+
+ } else {
+ self.append( html );
+ }
+ });
+ },
+
+ wrap: function( html ) {
+ var isFunction = jQuery.isFunction( html );
+
+ return this.each(function( i ) {
+ jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
+ });
+ },
+
+ unwrap: function() {
+ return this.parent().each(function() {
+ if ( !jQuery.nodeName( this, "body" ) ) {
+ jQuery( this ).replaceWith( this.childNodes );
+ }
+ }).end();
+ }
+});
+
+
+jQuery.expr.filters.hidden = function( elem ) {
+ // Support: Opera <= 12.12
+ // Opera reports offsetWidths and offsetHeights less than zero on some elements
+ return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
+};
+jQuery.expr.filters.visible = function( elem ) {
+ return !jQuery.expr.filters.hidden( elem );
+};
+
+
+
+
+var r20 = /%20/g,
+ rbracket = /\[\]$/,
+ rCRLF = /\r?\n/g,
+ rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+ rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+function buildParams( prefix, obj, traditional, add ) {
+ var name;
+
+ if ( jQuery.isArray( obj ) ) {
+ // Serialize array item.
+ jQuery.each( obj, function( i, v ) {
+ if ( traditional || rbracket.test( prefix ) ) {
+ // Treat each array item as a scalar.
+ add( prefix, v );
+
+ } else {
+ // Item is non-scalar (array or object), encode its numeric index.
+ buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
+ }
+ });
+
+ } else if ( !traditional && jQuery.type( obj ) === "object" ) {
+ // Serialize object item.
+ for ( name in obj ) {
+ buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+ }
+
} else {
- // Try convertible dataTypes
- for ( type in responses ) {
- if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
- finalDataType = type;
- break;
- }
- if ( !firstDataType ) {
- firstDataType = type;
- }
- }
- // Or just use first one
- finalDataType = finalDataType || firstDataType;
- }
-
- // If we found a dataType
- // We add the dataType to the list if needed
- // and return the corresponding response
- if ( finalDataType ) {
- if ( finalDataType !== dataTypes[ 0 ] ) {
- dataTypes.unshift( finalDataType );
- }
- return responses[ finalDataType ];
+ // Serialize scalar item.
+ add( prefix, obj );
}
}
-/* Chain conversions given the request and the original response
- * Also sets the responseXXX fields on the jqXHR instance
- */
-function ajaxConvert( s, response, jqXHR, isSuccess ) {
- var conv2, current, conv, tmp, prev,
- converters = {},
- // Work with a copy of dataTypes in case we need to modify it for conversion
- dataTypes = s.dataTypes.slice();
+// Serialize an array of form elements or a set of
+// key/values into a query string
+jQuery.param = function( a, traditional ) {
+ var prefix,
+ s = [],
+ add = function( key, value ) {
+ // If value is a function, invoke it and return its value
+ value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
+ s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+ };
- // Create converters map with lowercased keys
- if ( dataTypes[ 1 ] ) {
- for ( conv in s.converters ) {
- converters[ conv.toLowerCase() ] = s.converters[ conv ];
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
+ if ( traditional === undefined ) {
+ traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
+ }
+
+ // If an array was passed in, assume that it is an array of form elements.
+ if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+ // Serialize the form elements
+ jQuery.each( a, function() {
+ add( this.name, this.value );
+ });
+
+ } else {
+ // If traditional, encode the "old" way (the way 1.3.2 or older
+ // did it), otherwise encode params recursively.
+ for ( prefix in a ) {
+ buildParams( prefix, a[ prefix ], traditional, add );
}
}
- current = dataTypes.shift();
+ // Return the resulting serialization
+ return s.join( "&" ).replace( r20, "+" );
+};
- // Convert to each sequential dataType
- while ( current ) {
+jQuery.fn.extend({
+ serialize: function() {
+ return jQuery.param( this.serializeArray() );
+ },
+ serializeArray: function() {
+ return this.map(function() {
+ // Can add propHook for "elements" to filter or add form elements
+ var elements = jQuery.prop( this, "elements" );
+ return elements ? jQuery.makeArray( elements ) : this;
+ })
+ .filter(function() {
+ var type = this.type;
- if ( s.responseFields[ current ] ) {
- jqXHR[ s.responseFields[ current ] ] = response;
+ // Use .is( ":disabled" ) so that fieldset[disabled] works
+ return this.name && !jQuery( this ).is( ":disabled" ) &&
+ rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
+ ( this.checked || !rcheckableType.test( type ) );
+ })
+ .map(function( i, elem ) {
+ var val = jQuery( this ).val();
+
+ return val == null ?
+ null :
+ jQuery.isArray( val ) ?
+ jQuery.map( val, function( val ) {
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }) :
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }).get();
+ }
+});
+
+
+jQuery.ajaxSettings.xhr = function() {
+ try {
+ return new XMLHttpRequest();
+ } catch( e ) {}
+};
+
+var xhrId = 0,
+ xhrCallbacks = {},
+ xhrSuccessStatus = {
+ // file protocol always yields status code 0, assume 200
+ 0: 200,
+ // Support: IE9
+ // #1450: sometimes IE returns 1223 when it should be 204
+ 1223: 204
+ },
+ xhrSupported = jQuery.ajaxSettings.xhr();
+
+// Support: IE9
+// Open requests must be manually aborted on unload (#5280)
+if ( window.ActiveXObject ) {
+ jQuery( window ).on( "unload", function() {
+ for ( var key in xhrCallbacks ) {
+ xhrCallbacks[ key ]();
}
+ });
+}
- // Apply the dataFilter if provided
- if ( !prev && isSuccess && s.dataFilter ) {
- response = s.dataFilter( response, s.dataType );
- }
+support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
+support.ajax = xhrSupported = !!xhrSupported;
- prev = current;
- current = dataTypes.shift();
+jQuery.ajaxTransport(function( options ) {
+ var callback;
- if ( current ) {
+ // Cross domain only allowed if supported through XMLHttpRequest
+ if ( support.cors || xhrSupported && !options.crossDomain ) {
+ return {
+ send: function( headers, complete ) {
+ var i,
+ xhr = options.xhr(),
+ id = ++xhrId;
- // There's only work to do if current dataType is non-auto
- if ( current === "*" ) {
+ xhr.open( options.type, options.url, options.async, options.username, options.password );
- current = prev;
+ // Apply custom fields if provided
+ if ( options.xhrFields ) {
+ for ( i in options.xhrFields ) {
+ xhr[ i ] = options.xhrFields[ i ];
+ }
+ }
- // Convert response if prev dataType is non-auto and differs from current
- } else if ( prev !== "*" && prev !== current ) {
+ // Override mime type if needed
+ if ( options.mimeType && xhr.overrideMimeType ) {
+ xhr.overrideMimeType( options.mimeType );
+ }
- // Seek a direct converter
- conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+ // X-Requested-With header
+ // For cross-domain requests, seeing as conditions for a preflight are
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
+ // (it can always be set on a per-request basis or even using ajaxSetup)
+ // For same-domain requests, won't change header if already provided.
+ if ( !options.crossDomain && !headers["X-Requested-With"] ) {
+ headers["X-Requested-With"] = "XMLHttpRequest";
+ }
- // If none found, seek a pair
- if ( !conv ) {
- for ( conv2 in converters ) {
+ // Set headers
+ for ( i in headers ) {
+ xhr.setRequestHeader( i, headers[ i ] );
+ }
- // If conv2 outputs current
- tmp = conv2.split( " " );
- if ( tmp[ 1 ] === current ) {
+ // Callback
+ callback = function( type ) {
+ return function() {
+ if ( callback ) {
+ delete xhrCallbacks[ id ];
+ callback = xhr.onload = xhr.onerror = null;
- // If prev can be converted to accepted input
- conv = converters[ prev + " " + tmp[ 0 ] ] ||
- converters[ "* " + tmp[ 0 ] ];
- if ( conv ) {
- // Condense equivalence converters
- if ( conv === true ) {
- conv = converters[ conv2 ];
-
- // Otherwise, insert the intermediate dataType
- } else if ( converters[ conv2 ] !== true ) {
- current = tmp[ 0 ];
- dataTypes.unshift( tmp[ 1 ] );
- }
- break;
+ if ( type === "abort" ) {
+ xhr.abort();
+ } else if ( type === "error" ) {
+ complete(
+ // file: protocol always yields status 0; see #8605, #14207
+ xhr.status,
+ xhr.statusText
+ );
+ } else {
+ complete(
+ xhrSuccessStatus[ xhr.status ] || xhr.status,
+ xhr.statusText,
+ // Support: IE9
+ // Accessing binary-data responseText throws an exception
+ // (#11426)
+ typeof xhr.responseText === "string" ? {
+ text: xhr.responseText
+ } : undefined,
+ xhr.getAllResponseHeaders()
+ );
}
}
+ };
+ };
+
+ // Listen to events
+ xhr.onload = callback();
+ xhr.onerror = callback("error");
+
+ // Create the abort callback
+ callback = xhrCallbacks[ id ] = callback("abort");
+
+ try {
+ // Do send the request (this may raise an exception)
+ xhr.send( options.hasContent && options.data || null );
+ } catch ( e ) {
+ // #14683: Only rethrow if this hasn't been notified as an error yet
+ if ( callback ) {
+ throw e;
}
}
+ },
- // Apply converter (if not an equivalence)
- if ( conv !== true ) {
-
- // Unless errors are allowed to bubble, catch and return them
- if ( conv && s[ "throws" ] ) {
- response = conv( response );
- } else {
- try {
- response = conv( response );
- } catch ( e ) {
- return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
- }
- }
+ abort: function() {
+ if ( callback ) {
+ callback();
}
}
- }
+ };
}
+});
+
+
+
- return { state: "success", data: response };
-}
// Install script dataType
jQuery.ajaxSetup({
accepts: {
@@ -7661,6 +8698,10 @@ jQuery.ajaxTransport( "script", function( s ) {
};
}
});
+
+
+
+
var oldCallbacks = [],
rjsonp = /(=)\?(?=&|$)|\?\?/;
@@ -7668,7 +8709,7 @@ var oldCallbacks = [],
jQuery.ajaxSetup({
jsonp: "callback",
jsonpCallback: function() {
- var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) );
+ var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
this[ callback ] = true;
return callback;
}
@@ -7695,7 +8736,7 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
if ( jsonProp ) {
s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
} else if ( s.jsonp !== false ) {
- s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
+ s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
}
// Use data converter to retrieve json after script execution
@@ -7741,886 +8782,126 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
return "script";
}
});
-jQuery.ajaxSettings.xhr = function() {
- try {
- return new XMLHttpRequest();
- } catch( e ) {}
+
+
+
+
+// data: string of html
+// context (optional): If specified, the fragment will be created in this context, defaults to document
+// keepScripts (optional): If true, will include scripts passed in the html string
+jQuery.parseHTML = function( data, context, keepScripts ) {
+ if ( !data || typeof data !== "string" ) {
+ return null;
+ }
+ if ( typeof context === "boolean" ) {
+ keepScripts = context;
+ context = false;
+ }
+ context = context || document;
+
+ var parsed = rsingleTag.exec( data ),
+ scripts = !keepScripts && [];
+
+ // Single tag
+ if ( parsed ) {
+ return [ context.createElement( parsed[1] ) ];
+ }
+
+ parsed = jQuery.buildFragment( [ data ], context, scripts );
+
+ if ( scripts && scripts.length ) {
+ jQuery( scripts ).remove();
+ }
+
+ return jQuery.merge( [], parsed.childNodes );
};
-var xhrSupported = jQuery.ajaxSettings.xhr(),
- xhrSuccessStatus = {
- // file protocol always yields status code 0, assume 200
- 0: 200,
- // Support: IE9
- // #1450: sometimes IE returns 1223 when it should be 204
- 1223: 204
- },
- // Support: IE9
- // We need to keep track of outbound xhr and abort them manually
- // because IE is not smart enough to do it all by itself
- xhrId = 0,
- xhrCallbacks = {};
-if ( window.ActiveXObject ) {
- jQuery( window ).on( "unload", function() {
- for( var key in xhrCallbacks ) {
- xhrCallbacks[ key ]();
- }
- xhrCallbacks = undefined;
- });
-}
+// Keep a copy of the old load method
+var _load = jQuery.fn.load;
-jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
-jQuery.support.ajax = xhrSupported = !!xhrSupported;
-
-jQuery.ajaxTransport(function( options ) {
- var callback;
- // Cross domain only allowed if supported through XMLHttpRequest
- if ( jQuery.support.cors || xhrSupported && !options.crossDomain ) {
- return {
- send: function( headers, complete ) {
- var i, id,
- xhr = options.xhr();
- xhr.open( options.type, options.url, options.async, options.username, options.password );
- // Apply custom fields if provided
- if ( options.xhrFields ) {
- for ( i in options.xhrFields ) {
- xhr[ i ] = options.xhrFields[ i ];
- }
- }
- // Override mime type if needed
- if ( options.mimeType && xhr.overrideMimeType ) {
- xhr.overrideMimeType( options.mimeType );
- }
- // X-Requested-With header
- // For cross-domain requests, seeing as conditions for a preflight are
- // akin to a jigsaw puzzle, we simply never set it to be sure.
- // (it can always be set on a per-request basis or even using ajaxSetup)
- // For same-domain requests, won't change header if already provided.
- if ( !options.crossDomain && !headers["X-Requested-With"] ) {
- headers["X-Requested-With"] = "XMLHttpRequest";
- }
- // Set headers
- for ( i in headers ) {
- xhr.setRequestHeader( i, headers[ i ] );
- }
- // Callback
- callback = function( type ) {
- return function() {
- if ( callback ) {
- delete xhrCallbacks[ id ];
- callback = xhr.onload = xhr.onerror = null;
- if ( type === "abort" ) {
- xhr.abort();
- } else if ( type === "error" ) {
- complete(
- // file protocol always yields status 0, assume 404
- xhr.status || 404,
- xhr.statusText
- );
- } else {
- complete(
- xhrSuccessStatus[ xhr.status ] || xhr.status,
- xhr.statusText,
- // Support: IE9
- // #11426: When requesting binary data, IE9 will throw an exception
- // on any attempt to access responseText
- typeof xhr.responseText === "string" ? {
- text: xhr.responseText
- } : undefined,
- xhr.getAllResponseHeaders()
- );
- }
- }
- };
- };
- // Listen to events
- xhr.onload = callback();
- xhr.onerror = callback("error");
- // Create the abort callback
- callback = xhrCallbacks[( id = xhrId++ )] = callback("abort");
- // Do send the request
- // This may raise an exception which is actually
- // handled in jQuery.ajax (so no try/catch here)
- xhr.send( options.hasContent && options.data || null );
- },
- abort: function() {
- if ( callback ) {
- callback();
- }
- }
- };
- }
-});
-var fxNow, timerId,
- rfxtypes = /^(?:toggle|show|hide)$/,
- rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
- rrun = /queueHooks$/,
- animationPrefilters = [ defaultPrefilter ],
- tweeners = {
- "*": [function( prop, value ) {
- var tween = this.createTween( prop, value ),
- target = tween.cur(),
- parts = rfxnum.exec( value ),
- unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
-
- // Starting value computation is required for potential unit mismatches
- start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
- rfxnum.exec( jQuery.css( tween.elem, prop ) ),
- scale = 1,
- maxIterations = 20;
-
- if ( start && start[ 3 ] !== unit ) {
- // Trust units reported by jQuery.css
- unit = unit || start[ 3 ];
-
- // Make sure we update the tween properties later on
- parts = parts || [];
-
- // Iteratively approximate from a nonzero starting point
- start = +target || 1;
-
- do {
- // If previous iteration zeroed out, double until we get *something*
- // Use a string for doubling factor so we don't accidentally see scale as unchanged below
- scale = scale || ".5";
-
- // Adjust and apply
- start = start / scale;
- jQuery.style( tween.elem, prop, start + unit );
-
- // Update scale, tolerating zero or NaN from tween.cur()
- // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
- } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
- }
-
- // Update tween properties
- if ( parts ) {
- start = tween.start = +start || +target || 0;
- tween.unit = unit;
- // If a +=/-= token was provided, we're doing a relative animation
- tween.end = parts[ 1 ] ?
- start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
- +parts[ 2 ];
- }
-
- return tween;
- }]
- };
-
-// Animations created synchronously will run synchronously
-function createFxNow() {
- setTimeout(function() {
- fxNow = undefined;
- });
- return ( fxNow = jQuery.now() );
-}
-
-function createTween( value, prop, animation ) {
- var tween,
- collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
- index = 0,
- length = collection.length;
- for ( ; index < length; index++ ) {
- if ( (tween = collection[ index ].call( animation, prop, value )) ) {
-
- // we're done with this property
- return tween;
- }
- }
-}
-
-function Animation( elem, properties, options ) {
- var result,
- stopped,
- index = 0,
- length = animationPrefilters.length,
- deferred = jQuery.Deferred().always( function() {
- // don't match elem in the :animated selector
- delete tick.elem;
- }),
- tick = function() {
- if ( stopped ) {
- return false;
- }
- var currentTime = fxNow || createFxNow(),
- remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
- // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
- temp = remaining / animation.duration || 0,
- percent = 1 - temp,
- index = 0,
- length = animation.tweens.length;
-
- for ( ; index < length ; index++ ) {
- animation.tweens[ index ].run( percent );
- }
-
- deferred.notifyWith( elem, [ animation, percent, remaining ]);
-
- if ( percent < 1 && length ) {
- return remaining;
- } else {
- deferred.resolveWith( elem, [ animation ] );
- return false;
- }
- },
- animation = deferred.promise({
- elem: elem,
- props: jQuery.extend( {}, properties ),
- opts: jQuery.extend( true, { specialEasing: {} }, options ),
- originalProperties: properties,
- originalOptions: options,
- startTime: fxNow || createFxNow(),
- duration: options.duration,
- tweens: [],
- createTween: function( prop, end ) {
- var tween = jQuery.Tween( elem, animation.opts, prop, end,
- animation.opts.specialEasing[ prop ] || animation.opts.easing );
- animation.tweens.push( tween );
- return tween;
- },
- stop: function( gotoEnd ) {
- var index = 0,
- // if we are going to the end, we want to run all the tweens
- // otherwise we skip this part
- length = gotoEnd ? animation.tweens.length : 0;
- if ( stopped ) {
- return this;
- }
- stopped = true;
- for ( ; index < length ; index++ ) {
- animation.tweens[ index ].run( 1 );
- }
-
- // resolve when we played the last frame
- // otherwise, reject
- if ( gotoEnd ) {
- deferred.resolveWith( elem, [ animation, gotoEnd ] );
- } else {
- deferred.rejectWith( elem, [ animation, gotoEnd ] );
- }
- return this;
- }
- }),
- props = animation.props;
-
- propFilter( props, animation.opts.specialEasing );
-
- for ( ; index < length ; index++ ) {
- result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
- if ( result ) {
- return result;
- }
+/**
+ * Load a url into a page
+ */
+jQuery.fn.load = function( url, params, callback ) {
+ if ( typeof url !== "string" && _load ) {
+ return _load.apply( this, arguments );
}
- jQuery.map( props, createTween, animation );
+ var selector, type, response,
+ self = this,
+ off = url.indexOf(" ");
- if ( jQuery.isFunction( animation.opts.start ) ) {
- animation.opts.start.call( elem, animation );
+ if ( off >= 0 ) {
+ selector = jQuery.trim( url.slice( off ) );
+ url = url.slice( 0, off );
}
- jQuery.fx.timer(
- jQuery.extend( tick, {
- elem: elem,
- anim: animation,
- queue: animation.opts.queue
- })
- );
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
- // attach callbacks from options
- return animation.progress( animation.opts.progress )
- .done( animation.opts.done, animation.opts.complete )
- .fail( animation.opts.fail )
- .always( animation.opts.always );
-}
+ // We assume that it's the callback
+ callback = params;
+ params = undefined;
-function propFilter( props, specialEasing ) {
- var index, name, easing, value, hooks;
-
- // camelCase, specialEasing and expand cssHook pass
- for ( index in props ) {
- name = jQuery.camelCase( index );
- easing = specialEasing[ name ];
- value = props[ index ];
- if ( jQuery.isArray( value ) ) {
- easing = value[ 1 ];
- value = props[ index ] = value[ 0 ];
- }
-
- if ( index !== name ) {
- props[ name ] = value;
- delete props[ index ];
- }
-
- hooks = jQuery.cssHooks[ name ];
- if ( hooks && "expand" in hooks ) {
- value = hooks.expand( value );
- delete props[ name ];
-
- // not quite $.extend, this wont overwrite keys already present.
- // also - reusing 'index' from above because we have the correct "name"
- for ( index in value ) {
- if ( !( index in props ) ) {
- props[ index ] = value[ index ];
- specialEasing[ index ] = easing;
- }
- }
- } else {
- specialEasing[ name ] = easing;
- }
+ // Otherwise, build a param string
+ } else if ( params && typeof params === "object" ) {
+ type = "POST";
}
-}
-jQuery.Animation = jQuery.extend( Animation, {
+ // If we have elements to modify, make the request
+ if ( self.length > 0 ) {
+ jQuery.ajax({
+ url: url,
- tweener: function( props, callback ) {
- if ( jQuery.isFunction( props ) ) {
- callback = props;
- props = [ "*" ];
- } else {
- props = props.split(" ");
- }
+ // if "type" variable is undefined, then "GET" method will be used
+ type: type,
+ dataType: "html",
+ data: params
+ }).done(function( responseText ) {
- var prop,
- index = 0,
- length = props.length;
+ // Save response for use in complete callback
+ response = arguments;
- for ( ; index < length ; index++ ) {
- prop = props[ index ];
- tweeners[ prop ] = tweeners[ prop ] || [];
- tweeners[ prop ].unshift( callback );
- }
- },
+ self.html( selector ?
- prefilter: function( callback, prepend ) {
- if ( prepend ) {
- animationPrefilters.unshift( callback );
- } else {
- animationPrefilters.push( callback );
- }
- }
-});
+ // If a selector was specified, locate the right elements in a dummy div
+ // Exclude scripts to avoid IE 'Permission Denied' errors
+ jQuery("
").append( jQuery.parseHTML( responseText ) ).find( selector ) :
-function defaultPrefilter( elem, props, opts ) {
- /* jshint validthis: true */
- var prop, value, toggle, tween, hooks, oldfire,
- anim = this,
- orig = {},
- style = elem.style,
- hidden = elem.nodeType && isHidden( elem ),
- dataShow = data_priv.get( elem, "fxshow" );
+ // Otherwise use the full result
+ responseText );
- // handle queue: false promises
- if ( !opts.queue ) {
- hooks = jQuery._queueHooks( elem, "fx" );
- if ( hooks.unqueued == null ) {
- hooks.unqueued = 0;
- oldfire = hooks.empty.fire;
- hooks.empty.fire = function() {
- if ( !hooks.unqueued ) {
- oldfire();
- }
- };
- }
- hooks.unqueued++;
-
- anim.always(function() {
- // doing this makes sure that the complete handler will be called
- // before this completes
- anim.always(function() {
- hooks.unqueued--;
- if ( !jQuery.queue( elem, "fx" ).length ) {
- hooks.empty.fire();
- }
- });
+ }).complete( callback && function( jqXHR, status ) {
+ self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
});
}
- // height/width overflow pass
- if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
- // Make sure that nothing sneaks out
- // Record all 3 overflow attributes because IE9-10 do not
- // change the overflow attribute when overflowX and
- // overflowY are set to the same value
- opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
-
- // Set display property to inline-block for height/width
- // animations on inline elements that are having width/height animated
- if ( jQuery.css( elem, "display" ) === "inline" &&
- jQuery.css( elem, "float" ) === "none" ) {
-
- style.display = "inline-block";
- }
- }
-
- if ( opts.overflow ) {
- style.overflow = "hidden";
- anim.always(function() {
- style.overflow = opts.overflow[ 0 ];
- style.overflowX = opts.overflow[ 1 ];
- style.overflowY = opts.overflow[ 2 ];
- });
- }
+ return this;
+};
- // show/hide pass
- for ( prop in props ) {
- value = props[ prop ];
- if ( rfxtypes.exec( value ) ) {
- delete props[ prop ];
- toggle = toggle || value === "toggle";
- if ( value === ( hidden ? "hide" : "show" ) ) {
- // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
- if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
- hidden = true;
- } else {
- continue;
- }
- }
- orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
- }
- }
- if ( !jQuery.isEmptyObject( orig ) ) {
- if ( dataShow ) {
- if ( "hidden" in dataShow ) {
- hidden = dataShow.hidden;
- }
- } else {
- dataShow = data_priv.access( elem, "fxshow", {} );
- }
+jQuery.expr.filters.animated = function( elem ) {
+ return jQuery.grep(jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ }).length;
+};
- // store state if its toggle - enables .stop().toggle() to "reverse"
- if ( toggle ) {
- dataShow.hidden = !hidden;
- }
- if ( hidden ) {
- jQuery( elem ).show();
- } else {
- anim.done(function() {
- jQuery( elem ).hide();
- });
- }
- anim.done(function() {
- var prop;
- data_priv.remove( elem, "fxshow" );
- for ( prop in orig ) {
- jQuery.style( elem, prop, orig[ prop ] );
- }
- });
- for ( prop in orig ) {
- tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
- if ( !( prop in dataShow ) ) {
- dataShow[ prop ] = tween.start;
- if ( hidden ) {
- tween.end = tween.start;
- tween.start = prop === "width" || prop === "height" ? 1 : 0;
- }
- }
- }
- }
+
+var docElem = window.document.documentElement;
+
+/**
+ * Gets a window from an element
+ */
+function getWindow( elem ) {
+ return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
}
-function Tween( elem, options, prop, end, easing ) {
- return new Tween.prototype.init( elem, options, prop, end, easing );
-}
-jQuery.Tween = Tween;
-
-Tween.prototype = {
- constructor: Tween,
- init: function( elem, options, prop, end, easing, unit ) {
- this.elem = elem;
- this.prop = prop;
- this.easing = easing || "swing";
- this.options = options;
- this.start = this.now = this.cur();
- this.end = end;
- this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
- },
- cur: function() {
- var hooks = Tween.propHooks[ this.prop ];
-
- return hooks && hooks.get ?
- hooks.get( this ) :
- Tween.propHooks._default.get( this );
- },
- run: function( percent ) {
- var eased,
- hooks = Tween.propHooks[ this.prop ];
-
- if ( this.options.duration ) {
- this.pos = eased = jQuery.easing[ this.easing ](
- percent, this.options.duration * percent, 0, 1, this.options.duration
- );
- } else {
- this.pos = eased = percent;
- }
- this.now = ( this.end - this.start ) * eased + this.start;
-
- if ( this.options.step ) {
- this.options.step.call( this.elem, this.now, this );
- }
-
- if ( hooks && hooks.set ) {
- hooks.set( this );
- } else {
- Tween.propHooks._default.set( this );
- }
- return this;
- }
-};
-
-Tween.prototype.init.prototype = Tween.prototype;
-
-Tween.propHooks = {
- _default: {
- get: function( tween ) {
- var result;
-
- if ( tween.elem[ tween.prop ] != null &&
- (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
- return tween.elem[ tween.prop ];
- }
-
- // passing an empty string as a 3rd parameter to .css will automatically
- // attempt a parseFloat and fallback to a string if the parse fails
- // so, simple values such as "10px" are parsed to Float.
- // complex values such as "rotate(1rad)" are returned as is.
- result = jQuery.css( tween.elem, tween.prop, "" );
- // Empty strings, null, undefined and "auto" are converted to 0.
- return !result || result === "auto" ? 0 : result;
- },
- set: function( tween ) {
- // use step hook for back compat - use cssHook if its there - use .style if its
- // available and use plain properties where available
- if ( jQuery.fx.step[ tween.prop ] ) {
- jQuery.fx.step[ tween.prop ]( tween );
- } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
- jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
- } else {
- tween.elem[ tween.prop ] = tween.now;
- }
- }
- }
-};
-
-// Support: IE9
-// Panic based approach to setting things on disconnected nodes
-
-Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
- set: function( tween ) {
- if ( tween.elem.nodeType && tween.elem.parentNode ) {
- tween.elem[ tween.prop ] = tween.now;
- }
- }
-};
-
-jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
- var cssFn = jQuery.fn[ name ];
- jQuery.fn[ name ] = function( speed, easing, callback ) {
- return speed == null || typeof speed === "boolean" ?
- cssFn.apply( this, arguments ) :
- this.animate( genFx( name, true ), speed, easing, callback );
- };
-});
-
-jQuery.fn.extend({
- fadeTo: function( speed, to, easing, callback ) {
-
- // show any hidden elements after setting opacity to 0
- return this.filter( isHidden ).css( "opacity", 0 ).show()
-
- // animate to the value specified
- .end().animate({ opacity: to }, speed, easing, callback );
- },
- animate: function( prop, speed, easing, callback ) {
- var empty = jQuery.isEmptyObject( prop ),
- optall = jQuery.speed( speed, easing, callback ),
- doAnimation = function() {
- // Operate on a copy of prop so per-property easing won't be lost
- var anim = Animation( this, jQuery.extend( {}, prop ), optall );
-
- // Empty animations, or finishing resolves immediately
- if ( empty || data_priv.get( this, "finish" ) ) {
- anim.stop( true );
- }
- };
- doAnimation.finish = doAnimation;
-
- return empty || optall.queue === false ?
- this.each( doAnimation ) :
- this.queue( optall.queue, doAnimation );
- },
- stop: function( type, clearQueue, gotoEnd ) {
- var stopQueue = function( hooks ) {
- var stop = hooks.stop;
- delete hooks.stop;
- stop( gotoEnd );
- };
-
- if ( typeof type !== "string" ) {
- gotoEnd = clearQueue;
- clearQueue = type;
- type = undefined;
- }
- if ( clearQueue && type !== false ) {
- this.queue( type || "fx", [] );
- }
-
- return this.each(function() {
- var dequeue = true,
- index = type != null && type + "queueHooks",
- timers = jQuery.timers,
- data = data_priv.get( this );
-
- if ( index ) {
- if ( data[ index ] && data[ index ].stop ) {
- stopQueue( data[ index ] );
- }
- } else {
- for ( index in data ) {
- if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
- stopQueue( data[ index ] );
- }
- }
- }
-
- for ( index = timers.length; index--; ) {
- if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
- timers[ index ].anim.stop( gotoEnd );
- dequeue = false;
- timers.splice( index, 1 );
- }
- }
-
- // start the next in the queue if the last step wasn't forced
- // timers currently will call their complete callbacks, which will dequeue
- // but only if they were gotoEnd
- if ( dequeue || !gotoEnd ) {
- jQuery.dequeue( this, type );
- }
- });
- },
- finish: function( type ) {
- if ( type !== false ) {
- type = type || "fx";
- }
- return this.each(function() {
- var index,
- data = data_priv.get( this ),
- queue = data[ type + "queue" ],
- hooks = data[ type + "queueHooks" ],
- timers = jQuery.timers,
- length = queue ? queue.length : 0;
-
- // enable finishing flag on private data
- data.finish = true;
-
- // empty the queue first
- jQuery.queue( this, type, [] );
-
- if ( hooks && hooks.stop ) {
- hooks.stop.call( this, true );
- }
-
- // look for any active animations, and finish them
- for ( index = timers.length; index--; ) {
- if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
- timers[ index ].anim.stop( true );
- timers.splice( index, 1 );
- }
- }
-
- // look for any animations in the old queue and finish them
- for ( index = 0; index < length; index++ ) {
- if ( queue[ index ] && queue[ index ].finish ) {
- queue[ index ].finish.call( this );
- }
- }
-
- // turn off finishing flag
- delete data.finish;
- });
- }
-});
-
-// Generate parameters to create a standard animation
-function genFx( type, includeWidth ) {
- var which,
- attrs = { height: type },
- i = 0;
-
- // if we include width, step value is 1 to do all cssExpand values,
- // if we don't include width, step value is 2 to skip over Left and Right
- includeWidth = includeWidth? 1 : 0;
- for( ; i < 4 ; i += 2 - includeWidth ) {
- which = cssExpand[ i ];
- attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
- }
-
- if ( includeWidth ) {
- attrs.opacity = attrs.width = type;
- }
-
- return attrs;
-}
-
-// Generate shortcuts for custom animations
-jQuery.each({
- slideDown: genFx("show"),
- slideUp: genFx("hide"),
- slideToggle: genFx("toggle"),
- fadeIn: { opacity: "show" },
- fadeOut: { opacity: "hide" },
- fadeToggle: { opacity: "toggle" }
-}, function( name, props ) {
- jQuery.fn[ name ] = function( speed, easing, callback ) {
- return this.animate( props, speed, easing, callback );
- };
-});
-
-jQuery.speed = function( speed, easing, fn ) {
- var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
- complete: fn || !fn && easing ||
- jQuery.isFunction( speed ) && speed,
- duration: speed,
- easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
- };
-
- opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
- opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
-
- // normalize opt.queue - true/undefined/null -> "fx"
- if ( opt.queue == null || opt.queue === true ) {
- opt.queue = "fx";
- }
-
- // Queueing
- opt.old = opt.complete;
-
- opt.complete = function() {
- if ( jQuery.isFunction( opt.old ) ) {
- opt.old.call( this );
- }
-
- if ( opt.queue ) {
- jQuery.dequeue( this, opt.queue );
- }
- };
-
- return opt;
-};
-
-jQuery.easing = {
- linear: function( p ) {
- return p;
- },
- swing: function( p ) {
- return 0.5 - Math.cos( p*Math.PI ) / 2;
- }
-};
-
-jQuery.timers = [];
-jQuery.fx = Tween.prototype.init;
-jQuery.fx.tick = function() {
- var timer,
- timers = jQuery.timers,
- i = 0;
-
- fxNow = jQuery.now();
-
- for ( ; i < timers.length; i++ ) {
- timer = timers[ i ];
- // Checks the timer has not already been removed
- if ( !timer() && timers[ i ] === timer ) {
- timers.splice( i--, 1 );
- }
- }
-
- if ( !timers.length ) {
- jQuery.fx.stop();
- }
- fxNow = undefined;
-};
-
-jQuery.fx.timer = function( timer ) {
- if ( timer() && jQuery.timers.push( timer ) ) {
- jQuery.fx.start();
- }
-};
-
-jQuery.fx.interval = 13;
-
-jQuery.fx.start = function() {
- if ( !timerId ) {
- timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
- }
-};
-
-jQuery.fx.stop = function() {
- clearInterval( timerId );
- timerId = null;
-};
-
-jQuery.fx.speeds = {
- slow: 600,
- fast: 200,
- // Default speed
- _default: 400
-};
-
-// Back Compat <1.8 extension point
-jQuery.fx.step = {};
-
-if ( jQuery.expr && jQuery.expr.filters ) {
- jQuery.expr.filters.animated = function( elem ) {
- return jQuery.grep(jQuery.timers, function( fn ) {
- return elem === fn.elem;
- }).length;
- };
-}
-jQuery.fn.offset = function( options ) {
- if ( arguments.length ) {
- return options === undefined ?
- this :
- this.each(function( i ) {
- jQuery.offset.setOffset( this, options, i );
- });
- }
-
- var docElem, win,
- elem = this[ 0 ],
- box = { top: 0, left: 0 },
- doc = elem && elem.ownerDocument;
-
- if ( !doc ) {
- return;
- }
-
- docElem = doc.documentElement;
-
- // Make sure it's not a disconnected DOM node
- if ( !jQuery.contains( docElem, elem ) ) {
- return box;
- }
-
- // If we don't have gBCR, just use 0,0 rather than error
- // BlackBerry 5, iOS 3 (original iPhone)
- if ( typeof elem.getBoundingClientRect !== core_strundefined ) {
- box = elem.getBoundingClientRect();
- }
- win = getWindow( doc );
- return {
- top: box.top + win.pageYOffset - docElem.clientTop,
- left: box.left + win.pageXOffset - docElem.clientLeft
- };
-};
-
jQuery.offset = {
-
setOffset: function( elem, options, i ) {
var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
position = jQuery.css( elem, "position" ),
@@ -8635,7 +8916,8 @@ jQuery.offset = {
curOffset = curElem.offset();
curCSSTop = jQuery.css( elem, "top" );
curCSSLeft = jQuery.css( elem, "left" );
- calculatePosition = ( position === "absolute" || position === "fixed" ) && ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
+ calculatePosition = ( position === "absolute" || position === "fixed" ) &&
+ ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
// Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
if ( calculatePosition ) {
@@ -8668,8 +8950,43 @@ jQuery.offset = {
}
};
-
jQuery.fn.extend({
+ offset: function( options ) {
+ if ( arguments.length ) {
+ return options === undefined ?
+ this :
+ this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ var docElem, win,
+ elem = this[ 0 ],
+ box = { top: 0, left: 0 },
+ doc = elem && elem.ownerDocument;
+
+ if ( !doc ) {
+ return;
+ }
+
+ docElem = doc.documentElement;
+
+ // Make sure it's not a disconnected DOM node
+ if ( !jQuery.contains( docElem, elem ) ) {
+ return box;
+ }
+
+ // If we don't have gBCR, just use 0,0 rather than error
+ // BlackBerry 5, iOS 3 (original iPhone)
+ if ( typeof elem.getBoundingClientRect !== strundefined ) {
+ box = elem.getBoundingClientRect();
+ }
+ win = getWindow( doc );
+ return {
+ top: box.top + win.pageYOffset - docElem.clientTop,
+ left: box.left + win.pageXOffset - docElem.clientLeft
+ };
+ },
position: function() {
if ( !this[ 0 ] ) {
@@ -8680,7 +8997,7 @@ jQuery.fn.extend({
elem = this[ 0 ],
parentOffset = { top: 0, left: 0 };
- // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
+ // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
if ( jQuery.css( elem, "position" ) === "fixed" ) {
// We assume that getBoundingClientRect is available when computed position is fixed
offset = elem.getBoundingClientRect();
@@ -8711,7 +9028,7 @@ jQuery.fn.extend({
return this.map(function() {
var offsetParent = this.offsetParent || docElem;
- while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
+ while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
offsetParent = offsetParent.offsetParent;
}
@@ -8720,13 +9037,12 @@ jQuery.fn.extend({
}
});
-
// Create scrollLeft and scrollTop methods
-jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
+jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
var top = "pageYOffset" === prop;
jQuery.fn[ method ] = function( val ) {
- return jQuery.access( this, function( elem, method, val ) {
+ return access( this, function( elem, method, val ) {
var win = getWindow( elem );
if ( val === undefined ) {
@@ -8746,9 +9062,25 @@ jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( me
};
});
-function getWindow( elem ) {
- return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
-}
+// Add the top/left cssHooks using jQuery.fn.position
+// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+// getComputedStyle returns percent when specified for top/left/bottom/right
+// rather than make the css module depend on the offset module, we just check for it here
+jQuery.each( [ "top", "left" ], function( i, prop ) {
+ jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
+ function( elem, computed ) {
+ if ( computed ) {
+ computed = curCSS( elem, prop );
+ // if curCSS returns percentage, fallback to offset
+ return rnumnonpx.test( computed ) ?
+ jQuery( elem ).position()[ prop ] + "px" :
+ computed;
+ }
+ }
+ );
+});
+
+
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
@@ -8757,7 +9089,7 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
- return jQuery.access( this, function( elem, type, value ) {
+ return access( this, function( elem, type, value ) {
var doc;
if ( jQuery.isWindow( elem ) ) {
@@ -8790,8 +9122,7 @@ jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
};
});
});
-// Limit scope pollution from any deprecated API
-// (function() {
+
// The number of elements contained in the matched element set
jQuery.fn.size = function() {
@@ -8800,30 +9131,60 @@ jQuery.fn.size = function() {
jQuery.fn.andSelf = jQuery.fn.addBack;
-// })();
-if ( typeof module === "object" && module && typeof module.exports === "object" ) {
- // Expose jQuery as module.exports in loaders that implement the Node
- // module pattern (including browserify). Do not create the global, since
- // the user will be storing it themselves locally, and globals are frowned
- // upon in the Node module world.
- module.exports = jQuery;
-} else {
- // Register as a named AMD module, since jQuery can be concatenated with other
- // files that may use define, but not via a proper concatenation script that
- // understands anonymous AMD modules. A named AMD is safest and most robust
- // way to register. Lowercase jquery is used because AMD module names are
- // derived from file names, and jQuery is normally delivered in a lowercase
- // file name. Do this after creating the global so that if an AMD module wants
- // to call noConflict to hide this version of jQuery, it will work.
- if ( typeof define === "function" && define.amd ) {
- define( "jquery", [], function () { return jQuery; } );
- }
+
+
+
+// Register as a named AMD module, since jQuery can be concatenated with other
+// files that may use define, but not via a proper concatenation script that
+// understands anonymous AMD modules. A named AMD is safest and most robust
+// way to register. Lowercase jquery is used because AMD module names are
+// derived from file names, and jQuery is normally delivered in a lowercase
+// file name. Do this after creating the global so that if an AMD module wants
+// to call noConflict to hide this version of jQuery, it will work.
+
+// Note that for maximum portability, libraries that are not jQuery should
+// declare themselves as anonymous modules, and avoid setting a global if an
+// AMD loader is present. jQuery is a special case. For more information, see
+// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
+
+if ( typeof define === "function" && define.amd ) {
+ define( "jquery", [], function() {
+ return jQuery;
+ });
}
-// If there is a window object, that at least has a document property,
-// define jQuery and $ identifiers
-if ( typeof window === "object" && typeof window.document === "object" ) {
+
+
+
+var
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$;
+
+jQuery.noConflict = function( deep ) {
+ if ( window.$ === jQuery ) {
+ window.$ = _$;
+ }
+
+ if ( deep && window.jQuery === jQuery ) {
+ window.jQuery = _jQuery;
+ }
+
+ return jQuery;
+};
+
+// Expose jQuery and $ identifiers, even in
+// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
+// and CommonJS for browser emulators (#13566)
+if ( typeof noGlobal === strundefined ) {
window.jQuery = window.$ = jQuery;
}
-})( window );
+
+
+
+return jQuery;
+
+}));
diff --git a/src/_h5ai/client/js/lib/jquery.filedrop-0.1.0~0a38cbc.js b/src/_h5ai/client/js/lib/jquery.filedrop-0.1.0~0a38cbc.js
deleted file mode 100644
index f1440142..00000000
--- a/src/_h5ai/client/js/lib/jquery.filedrop-0.1.0~0a38cbc.js
+++ /dev/null
@@ -1,555 +0,0 @@
-/*global jQuery:false, alert:false */
-
-/*
- * Default text - jQuery plugin for html5 dragging files from desktop to browser
- *
- * Author: Weixi Yen
- *
- * Email: [Firstname][Lastname]@gmail.com
- *
- * Copyright (c) 2010 Resopollution
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/mit-license.php
- *
- * Project home:
- * http://www.github.com/weixiyen/jquery-filedrop
- *
- * Version: 0.1.0
- *
- * Features:
- * Allows sending of extra parameters with file.
- * Works with Firefox 3.6+
- * Future-compliant with HTML5 spec (will work with Webkit browsers and IE9)
- * Usage:
- * See README at project homepage
- *
- */
-;(function($) {
-
- jQuery.event.props.push("dataTransfer");
-
- var default_opts = {
- fallback_id: '',
- url: '',
- refresh: 1000,
- paramname: 'userfile',
- requestType: 'POST', // just in case you want to use another HTTP verb
- allowedfileextensions:[],
- allowedfiletypes:[],
- maxfiles: 25, // Ignored if queuefiles is set > 0
- maxfilesize: 1, // MB file size limit
- queuefiles: 0, // Max files before queueing (for large volume uploads)
- queuewait: 200, // Queue wait time if full
- data: {},
- headers: {},
- drop: empty,
- dragStart: empty,
- dragEnter: empty,
- dragOver: empty,
- dragLeave: empty,
- docEnter: empty,
- docOver: empty,
- docLeave: empty,
- beforeEach: empty,
- afterAll: empty,
- rename: empty,
- error: function(err, file, i, status) {
- alert(err);
- },
- uploadStarted: empty,
- uploadFinished: empty,
- progressUpdated: empty,
- globalProgressUpdated: empty,
- speedUpdated: empty
- },
- errors = ["BrowserNotSupported", "TooManyFiles", "FileTooLarge", "FileTypeNotAllowed", "NotFound", "NotReadable", "AbortError", "ReadError", "FileExtensionNotAllowed"];
-
- $.fn.filedrop = function(options) {
- var opts = $.extend({}, default_opts, options),
- global_progress = [],
- doc_leave_timer, stop_loop = false,
- files_count = 0,
- files;
-
- $('#' + opts.fallback_id).css({
- display: 'none',
- width: 0,
- height: 0
- });
-
- this.on('drop', drop).on('dragstart', opts.dragStart).on('dragenter', dragEnter).on('dragover', dragOver).on('dragleave', dragLeave);
- $(document).on('drop', docDrop).on('dragenter', docEnter).on('dragover', docOver).on('dragleave', docLeave);
-
- this.on('click', function(e){
- $('#' + opts.fallback_id).trigger(e);
- });
-
- $('#' + opts.fallback_id).change(function(e) {
- opts.drop(e);
- files = e.target.files;
- files_count = files.length;
- upload();
- });
-
- function drop(e) {
- if( opts.drop.call(this, e) === false ) return false;
- if(!e.dataTransfer)
- return;
- files = e.dataTransfer.files;
- if (files === null || files === undefined || files.length === 0) {
- opts.error(errors[0]);
- return false;
- }
- files_count = files.length;
- upload();
- e.preventDefault();
- return false;
- }
-
- function getBuilder(filename, filedata, mime, boundary) {
- var dashdash = '--',
- crlf = '\r\n',
- builder = '',
- paramname = opts.paramname;
-
- if (opts.data) {
- var params = $.param(opts.data).replace(/\+/g, '%20').split(/&/);
-
- $.each(params, function() {
- var pair = this.split("=", 2),
- name = decodeURIComponent(pair[0]),
- val = decodeURIComponent(pair[1]);
-
- if (pair.length !== 2) {
- return;
- }
-
- builder += dashdash;
- builder += boundary;
- builder += crlf;
- builder += 'Content-Disposition: form-data; name="' + name + '"';
- builder += crlf;
- builder += crlf;
- builder += val;
- builder += crlf;
- });
- }
-
- if (jQuery.isFunction(paramname)){
- paramname = paramname(filename);
- }
-
- builder += dashdash;
- builder += boundary;
- builder += crlf;
- builder += 'Content-Disposition: form-data; name="' + (paramname||"") + '"';
- builder += '; filename="' + filename + '"';
- builder += crlf;
-
- builder += 'Content-Type: ' + mime;
- builder += crlf;
- builder += crlf;
-
- builder += filedata;
- builder += crlf;
-
- builder += dashdash;
- builder += boundary;
- builder += dashdash;
- builder += crlf;
- return builder;
- }
-
- function progress(e) {
- if (e.lengthComputable) {
- var percentage = Math.round((e.loaded * 100) / e.total);
- if (this.currentProgress !== percentage) {
-
- this.currentProgress = percentage;
- opts.progressUpdated(this.index, this.file, this.currentProgress);
-
- global_progress[this.global_progress_index] = this.currentProgress;
- globalProgress();
-
- var elapsed = new Date().getTime();
- var diffTime = elapsed - this.currentStart;
- if (diffTime >= opts.refresh) {
- var diffData = e.loaded - this.startData;
- var speed = diffData / diffTime; // KB per second
- opts.speedUpdated(this.index, this.file, speed);
- this.startData = e.loaded;
- this.currentStart = elapsed;
- }
- }
- }
- }
-
- function globalProgress() {
- if (global_progress.length === 0) {
- return;
- }
-
- var total = 0, index;
- for (index in global_progress) {
- if(global_progress.hasOwnProperty(index)) {
- total = total + global_progress[index];
- }
- }
-
- opts.globalProgressUpdated(Math.round(total / global_progress.length));
- }
-
- // Respond to an upload
- function upload() {
- stop_loop = false;
-
- if (!files) {
- opts.error(errors[0]);
- return false;
- }
-
- if (opts.allowedfiletypes.push && opts.allowedfiletypes.length) {
- for(var fileIndex = files.length;fileIndex--;) {
- if(!files[fileIndex].type || $.inArray(files[fileIndex].type, opts.allowedfiletypes) < 0) {
- opts.error(errors[3], files[fileIndex]);
- return false;
- }
- }
- }
-
- if (opts.allowedfileextensions.push && opts.allowedfileextensions.length) {
- for(var fileIndex = files.length;fileIndex--;) {
- var allowedextension = false;
- for (i=0;i
opts.maxfiles && opts.queuefiles === 0) {
- opts.error(errors[1]);
- return false;
- }
-
- // Define queues to manage upload process
- var workQueue = [];
- var processingQueue = [];
- var doneQueue = [];
-
- // Add everything to the workQueue
- for (var i = 0; i < files_count; i++) {
- workQueue.push(i);
- }
-
- // Helper function to enable pause of processing to wait
- // for in process queue to complete
- var pause = function(timeout) {
- setTimeout(process, timeout);
- return;
- };
-
- // Process an upload, recursive
- var process = function() {
-
- var fileIndex;
-
- if (stop_loop) {
- return false;
- }
-
- // Check to see if are in queue mode
- if (opts.queuefiles > 0 && processingQueue.length >= opts.queuefiles) {
- return pause(opts.queuewait);
- } else {
- // Take first thing off work queue
- fileIndex = workQueue[0];
- workQueue.splice(0, 1);
-
- // Add to processing queue
- processingQueue.push(fileIndex);
- }
-
- try {
- if (beforeEach(files[fileIndex]) !== false) {
- if (fileIndex === files_count) {
- return;
- }
- var reader = new FileReader(),
- max_file_size = 1048576 * opts.maxfilesize;
-
- reader.index = fileIndex;
- if (files[fileIndex].size > max_file_size) {
- opts.error(errors[2], files[fileIndex], fileIndex);
- // Remove from queue
- processingQueue.forEach(function(value, key) {
- if (value === fileIndex) {
- processingQueue.splice(key, 1);
- }
- });
- filesRejected++;
- return true;
- }
-
- reader.onerror = function(e) {
- switch(e.target.error.code) {
- case e.target.error.NOT_FOUND_ERR:
- opts.error(errors[4]);
- return false;
- case e.target.error.NOT_READABLE_ERR:
- opts.error(errors[5]);
- return false;
- case e.target.error.ABORT_ERR:
- opts.error(errors[6]);
- return false;
- default:
- opts.error(errors[7]);
- return false;
- };
- };
-
- reader.onloadend = !opts.beforeSend ? send : function (e) {
- opts.beforeSend(files[fileIndex], fileIndex, function () { send(e); });
- };
-
- reader.readAsDataURL(files[fileIndex]);
-
- } else {
- filesRejected++;
- }
- } catch (err) {
- // Remove from queue
- processingQueue.forEach(function(value, key) {
- if (value === fileIndex) {
- processingQueue.splice(key, 1);
- }
- });
- opts.error(errors[0]);
- return false;
- }
-
- // If we still have work to do,
- if (workQueue.length > 0) {
- process();
- }
- };
-
- var send = function(e) {
-
- var fileIndex = (e.srcElement || e.target).index;
-
- // Sometimes the index is not attached to the
- // event object. Find it by size. Hack for sure.
- if (e.target.index === undefined) {
- e.target.index = getIndexBySize(e.total);
- }
-
- var xhr = new XMLHttpRequest(),
- upload = xhr.upload,
- file = files[e.target.index],
- index = e.target.index,
- start_time = new Date().getTime(),
- boundary = '------multipartformboundary' + (new Date()).getTime(),
- global_progress_index = global_progress.length,
- builder,
- newName = rename(file.name),
- mime = file.type;
-
- if (opts.withCredentials) {
- xhr.withCredentials = opts.withCredentials;
- }
-
- var data = atob(e.target.result.split(',')[1]);
- if (typeof newName === "string") {
- builder = getBuilder(newName, data, mime, boundary);
- } else {
- builder = getBuilder(file.name, data, mime, boundary);
- }
-
- upload.index = index;
- upload.file = file;
- upload.downloadStartTime = start_time;
- upload.currentStart = start_time;
- upload.currentProgress = 0;
- upload.global_progress_index = global_progress_index;
- upload.startData = 0;
- upload.addEventListener("progress", progress, false);
-
- // Allow url to be a method
- if (jQuery.isFunction(opts.url)) {
- xhr.open(opts.requestType, opts.url(), true);
- } else {
- xhr.open(opts.requestType, opts.url, true);
- }
-
- xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' + boundary);
- xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
-
- // Add headers
- $.each(opts.headers, function(k, v) {
- xhr.setRequestHeader(k, v);
- });
-
- xhr.sendAsBinary(builder);
-
- global_progress[global_progress_index] = 0;
- globalProgress();
-
- opts.uploadStarted(index, file, files_count);
-
- xhr.onload = function() {
- var serverResponse = null;
-
- if (xhr.responseText) {
- try {
- serverResponse = jQuery.parseJSON(xhr.responseText);
- }
- catch (e) {
- serverResponse = xhr.responseText;
- }
- }
-
- var now = new Date().getTime(),
- timeDiff = now - start_time,
- result = opts.uploadFinished(index, file, serverResponse, timeDiff, xhr);
- filesDone++;
-
- // Remove from processing queue
- processingQueue.forEach(function(value, key) {
- if (value === fileIndex) {
- processingQueue.splice(key, 1);
- }
- });
-
- // Add to donequeue
- doneQueue.push(fileIndex);
-
- // Make sure the global progress is updated
- global_progress[global_progress_index] = 100;
- globalProgress();
-
- if (filesDone === (files_count - filesRejected)) {
- afterAll();
- }
- if (result === false) {
- stop_loop = true;
- }
-
-
- // Pass any errors to the error option
- if (xhr.status < 200 || xhr.status > 299) {
- opts.error(xhr.statusText, file, fileIndex, xhr.status);
- }
- };
- };
-
- // Initiate the processing loop
- process();
- }
-
- function getIndexBySize(size) {
- for (var i = 0; i < files_count; i++) {
- if (files[i].size === size) {
- return i;
- }
- }
-
- return undefined;
- }
-
- function rename(name) {
- return opts.rename(name);
- }
-
- function beforeEach(file) {
- return opts.beforeEach(file);
- }
-
- function afterAll() {
- return opts.afterAll();
- }
-
- function dragEnter(e) {
- clearTimeout(doc_leave_timer);
- e.preventDefault();
- opts.dragEnter.call(this, e);
- }
-
- function dragOver(e) {
- clearTimeout(doc_leave_timer);
- e.preventDefault();
- opts.docOver.call(this, e);
- opts.dragOver.call(this, e);
- }
-
- function dragLeave(e) {
- clearTimeout(doc_leave_timer);
- opts.dragLeave.call(this, e);
- e.stopPropagation();
- }
-
- function docDrop(e) {
- e.preventDefault();
- opts.docLeave.call(this, e);
- return false;
- }
-
- function docEnter(e) {
- clearTimeout(doc_leave_timer);
- e.preventDefault();
- opts.docEnter.call(this, e);
- return false;
- }
-
- function docOver(e) {
- clearTimeout(doc_leave_timer);
- e.preventDefault();
- opts.docOver.call(this, e);
- return false;
- }
-
- function docLeave(e) {
- doc_leave_timer = setTimeout((function(_this) {
- return function() {
- opts.docLeave.call(_this, e);
- };
- })(this), 200);
- }
-
- return this;
- };
-
- function empty() {}
-
- try {
- if (XMLHttpRequest.prototype.sendAsBinary) {
- return;
- }
- XMLHttpRequest.prototype.sendAsBinary = function(datastr) {
- function byteValue(x) {
- return x.charCodeAt(0) & 0xff;
- }
- var ords = Array.prototype.map.call(datastr, byteValue);
- var ui8a = new Uint8Array(ords);
-
- // Not pretty: Chrome 22 deprecated sending ArrayBuffer, moving instead
- // to sending ArrayBufferView. Sadly, no proper way to detect this
- // functionality has been discovered. Happily, Chrome 22 also introduced
- // the base ArrayBufferView class, not present in Chrome 21.
- if ('ArrayBufferView' in window)
- this.send(ui8a);
- else
- this.send(ui8a.buffer);
- };
- } catch (e) {}
-
-})(jQuery);
diff --git a/src/_h5ai/client/js/lib/json2-2013-05-26.js b/src/_h5ai/client/js/lib/json2-2014-02-04.js
similarity index 98%
rename from src/_h5ai/client/js/lib/json2-2013-05-26.js
rename to src/_h5ai/client/js/lib/json2-2014-02-04.js
index d89ecc7a..deb88ec9 100644
--- a/src/_h5ai/client/js/lib/json2-2013-05-26.js
+++ b/src/_h5ai/client/js/lib/json2-2014-02-04.js
@@ -1,6 +1,6 @@
/*
json2.js
- 2013-05-26
+ 2014-02-04
Public Domain.
@@ -192,19 +192,11 @@ if (typeof JSON !== 'object') {
};
}
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ var cx,
+ escapable,
gap,
indent,
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- },
+ meta,
rep;
@@ -356,6 +348,16 @@ if (typeof JSON !== 'object') {
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
+ escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+ meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ };
JSON.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
@@ -403,6 +405,7 @@ if (typeof JSON !== 'object') {
// If the JSON object does not yet have a parse method, give it one.
if (typeof JSON.parse !== 'function') {
+ cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
JSON.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
diff --git a/src/_h5ai/client/js/lib/markdown-0.4.0-9c21acdf08.js b/src/_h5ai/client/js/lib/markdown-0.5.0.js
similarity index 94%
rename from src/_h5ai/client/js/lib/markdown-0.4.0-9c21acdf08.js
rename to src/_h5ai/client/js/lib/markdown-0.5.0.js
index c50d243d..d365cfa0 100644
--- a/src/_h5ai/client/js/lib/markdown-0.4.0-9c21acdf08.js
+++ b/src/_h5ai/client/js/lib/markdown-0.5.0.js
@@ -825,10 +825,12 @@ Markdown.dialects.Gruber.inline = {
"]": function () {},
"}": function () {},
+ __escape__ : /^\\[\\`\*_{}\[\]()#\+.!\-]/,
+
"\\": function escaped( text ) {
// [ length of input processed, node/children to add... ]
// Only esacape: \ ` * _ { } [ ] ( ) # * + - . !
- if ( text.match( /^\\[\\`\*_{}\[\]()#\+.!\-]/ ) )
+ if ( this.dialect.inline.__escape__.exec( text ) )
return [ 2, text.charAt( 1 ) ];
else
// Not an esacpe
@@ -1287,7 +1289,7 @@ Markdown.dialects.Maruku.block.definition_list = function definition_list( block
// one or more terms followed by one or more definitions, in a single block
var tight = /^((?:[^\s:].*\n)+):\s+([\s\S]+)$/,
list = [ "dl" ],
- i;
+ i, m;
// see if we're dealing with a tight or loose block
if ( ( m = block.match( tight ) ) ) {
@@ -1321,6 +1323,72 @@ Markdown.dialects.Maruku.block.definition_list = function definition_list( block
return [ list ];
};
+// splits on unescaped instances of @ch. If @ch is not a character the result
+// can be unpredictable
+
+Markdown.dialects.Maruku.block.table = function table (block, next) {
+
+ var _split_on_unescaped = function(s, ch) {
+ ch = ch || '\\s';
+ if (ch.match(/^[\\|\[\]{}?*.+^$]$/)) { ch = '\\' + ch; }
+ var res = [ ],
+ r = new RegExp('^((?:\\\\.|[^\\\\' + ch + '])*)' + ch + '(.*)'),
+ m;
+ while(m = s.match(r)) {
+ res.push(m[1]);
+ s = m[2];
+ }
+ res.push(s);
+ return res;
+ }
+
+ var leading_pipe = /^ {0,3}\|(.+)\n {0,3}\|\s*([\-:]+[\-| :]*)\n((?:\s*\|.*(?:\n|$))*)(?=\n|$)/,
+ // find at least an unescaped pipe in each line
+ no_leading_pipe = /^ {0,3}(\S(?:\\.|[^\\|])*\|.*)\n {0,3}([\-:]+\s*\|[\-| :]*)\n((?:(?:\\.|[^\\|])*\|.*(?:\n|$))*)(?=\n|$)/,
+ i, m;
+ if (m = block.match(leading_pipe)) {
+ // remove leading pipes in contents
+ // (header and horizontal rule already have the leading pipe left out)
+ m[3] = m[3].replace(/^\s*\|/gm, '');
+ } else if (! ( m = block.match(no_leading_pipe))) {
+ return undefined;
+ }
+
+ var table = [ "table", [ "thead", [ "tr" ] ], [ "tbody" ] ];
+
+ // remove trailing pipes, then split on pipes
+ // (no escaped pipes are allowed in horizontal rule)
+ m[2] = m[2].replace(/\|\s*$/, '').split('|');
+
+ // process alignment
+ var html_attrs = [ ];
+ forEach (m[2], function (s) {
+ if (s.match(/^\s*-+:\s*$/)) html_attrs.push({align: "right"});
+ else if (s.match(/^\s*:-+\s*$/)) html_attrs.push({align: "left"});
+ else if (s.match(/^\s*:-+:\s*$/)) html_attrs.push({align: "center"});
+ else html_attrs.push({});
+ });
+
+ // now for the header, avoid escaped pipes
+ m[1] = _split_on_unescaped(m[1].replace(/\|\s*$/, ''), '|');
+ for (i = 0; i < m[1].length; i++) {
+ table[1][1].push(['th', html_attrs[i] || {}].concat(
+ this.processInline(m[1][i].trim())));
+ }
+
+ // now for body contents
+ forEach (m[3].replace(/\|\s*$/mg, '').split('\n'), function (row) {
+ var html_row = ['tr'];
+ row = _split_on_unescaped(row, '|');
+ for (i = 0; i < row.length; i++) {
+ html_row.push(['td', html_attrs[i] || {}].concat(this.processInline(row[i].trim())));
+ }
+ table[2].push(html_row);
+ }, this);
+
+ return [table];
+}
+
Markdown.dialects.Maruku.inline[ "{:" ] = function inline_meta( text, matches, out ) {
if ( !out.length ) {
return [ 2, "{:" ];
@@ -1358,6 +1426,8 @@ Markdown.dialects.Maruku.inline[ "{:" ] = function inline_meta( text, matches, o
return [ m[ 0 ].length, "" ];
};
+Markdown.dialects.Maruku.inline.__escape__ = /^\\[\\`\*_{}\[\]()#\+.!\-|:]/;
+
Markdown.buildBlockOrder ( Markdown.dialects.Maruku.block );
Markdown.buildInlinePatterns( Markdown.dialects.Maruku.inline );
@@ -1603,7 +1673,8 @@ function convert_tree_to_html( tree, references, options ) {
if ( attrs ) {
// if there are keys, skip over it
for ( var key in jsonml[ 1 ] ) {
- i = 2;
+ i = 2;
+ break;
}
// if there aren't, remove it
if ( i === 1 ) {
diff --git a/src/_h5ai/client/js/lib/modernizr-2.6.2.js b/src/_h5ai/client/js/lib/modernizr-2.6.2.js
deleted file mode 100644
index 17158e12..00000000
--- a/src/_h5ai/client/js/lib/modernizr-2.6.2.js
+++ /dev/null
@@ -1,418 +0,0 @@
-/* Modernizr 2.6.2 (Custom Build) | MIT & BSD
- * Build: http://modernizr.com/download/#-opacity-rgba-canvas-history-audio-video-localstorage-shiv-cssclasses-prefixes
- */
-;
-
-
-
-window.Modernizr = (function( window, document, undefined ) {
-
- var version = '2.6.2',
-
- Modernizr = {},
-
- enableClasses = true,
-
- docElement = document.documentElement,
-
- mod = 'modernizr',
- modElem = document.createElement(mod),
- mStyle = modElem.style,
-
- inputElem ,
-
-
- toString = {}.toString,
-
- prefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
-
-
-
- tests = {},
- inputs = {},
- attrs = {},
-
- classes = [],
-
- slice = classes.slice,
-
- featureName,
-
-
-
- _hasOwnProperty = ({}).hasOwnProperty, hasOwnProp;
-
- if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) {
- hasOwnProp = function (object, property) {
- return _hasOwnProperty.call(object, property);
- };
- }
- else {
- hasOwnProp = function (object, property) {
- return ((property in object) && is(object.constructor.prototype[property], 'undefined'));
- };
- }
-
-
- if (!Function.prototype.bind) {
- Function.prototype.bind = function bind(that) {
-
- var target = this;
-
- if (typeof target != "function") {
- throw new TypeError();
- }
-
- var args = slice.call(arguments, 1),
- bound = function () {
-
- if (this instanceof bound) {
-
- var F = function(){};
- F.prototype = target.prototype;
- var self = new F();
-
- var result = target.apply(
- self,
- args.concat(slice.call(arguments))
- );
- if (Object(result) === result) {
- return result;
- }
- return self;
-
- } else {
-
- return target.apply(
- that,
- args.concat(slice.call(arguments))
- );
-
- }
-
- };
-
- return bound;
- };
- }
-
- function setCss( str ) {
- mStyle.cssText = str;
- }
-
- function setCssAll( str1, str2 ) {
- return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
- }
-
- function is( obj, type ) {
- return typeof obj === type;
- }
-
- function contains( str, substr ) {
- return !!~('' + str).indexOf(substr);
- }
-
-
- function testDOMProps( props, obj, elem ) {
- for ( var i in props ) {
- var item = obj[props[i]];
- if ( item !== undefined) {
-
- if (elem === false) return props[i];
-
- if (is(item, 'function')){
- return item.bind(elem || obj);
- }
-
- return item;
- }
- }
- return false;
- } tests['canvas'] = function() {
- var elem = document.createElement('canvas');
- return !!(elem.getContext && elem.getContext('2d'));
- };
-
- tests['history'] = function() {
- return !!(window.history && history.pushState);
- }; tests['rgba'] = function() {
- setCss('background-color:rgba(150,255,150,.5)');
-
- return contains(mStyle.backgroundColor, 'rgba');
- }; tests['opacity'] = function() {
- setCssAll('opacity:.55');
-
- return (/^0.55$/).test(mStyle.opacity);
- };
-
-
- tests['video'] = function() {
- var elem = document.createElement('video'),
- bool = false;
-
- try {
- if ( bool = !!elem.canPlayType ) {
- bool = new Boolean(bool);
- bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,'');
-
- bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,'');
-
- bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,'');
- }
-
- } catch(e) { }
-
- return bool;
- };
-
- tests['audio'] = function() {
- var elem = document.createElement('audio'),
- bool = false;
-
- try {
- if ( bool = !!elem.canPlayType ) {
- bool = new Boolean(bool);
- bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,'');
- bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,'');
-
- bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,'');
- bool.m4a = ( elem.canPlayType('audio/x-m4a;') ||
- elem.canPlayType('audio/aac;')) .replace(/^no$/,'');
- }
- } catch(e) { }
-
- return bool;
- };
-
-
- tests['localstorage'] = function() {
- try {
- localStorage.setItem(mod, mod);
- localStorage.removeItem(mod);
- return true;
- } catch(e) {
- return false;
- }
- };
-
-
- for ( var feature in tests ) {
- if ( hasOwnProp(tests, feature) ) {
- featureName = feature.toLowerCase();
- Modernizr[featureName] = tests[feature]();
-
- classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
- }
- }
-
-
-
- Modernizr.addTest = function ( feature, test ) {
- if ( typeof feature == 'object' ) {
- for ( var key in feature ) {
- if ( hasOwnProp( feature, key ) ) {
- Modernizr.addTest( key, feature[ key ] );
- }
- }
- } else {
-
- feature = feature.toLowerCase();
-
- if ( Modernizr[feature] !== undefined ) {
- return Modernizr;
- }
-
- test = typeof test == 'function' ? test() : test;
-
- if (typeof enableClasses !== "undefined" && enableClasses) {
- docElement.className += ' ' + (test ? '' : 'no-') + feature;
- }
- Modernizr[feature] = test;
-
- }
-
- return Modernizr;
- };
-
-
- setCss('');
- modElem = inputElem = null;
-
- ;(function(window, document) {
- var options = window.html5 || {};
-
- var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i;
-
- var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i;
-
- var supportsHtml5Styles;
-
- var expando = '_html5shiv';
-
- var expanID = 0;
-
- var expandoData = {};
-
- var supportsUnknownElements;
-
- (function() {
- try {
- var a = document.createElement('a');
- a.innerHTML = '';
- supportsHtml5Styles = ('hidden' in a);
-
- supportsUnknownElements = a.childNodes.length == 1 || (function() {
- (document.createElement)('a');
- var frag = document.createDocumentFragment();
- return (
- typeof frag.cloneNode == 'undefined' ||
- typeof frag.createDocumentFragment == 'undefined' ||
- typeof frag.createElement == 'undefined'
- );
- }());
- } catch(e) {
- supportsHtml5Styles = true;
- supportsUnknownElements = true;
- }
-
- }()); function addStyleSheet(ownerDocument, cssText) {
- var p = ownerDocument.createElement('p'),
- parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement;
-
- p.innerHTML = 'x';
- return parent.insertBefore(p.lastChild, parent.firstChild);
- }
-
- function getElements() {
- var elements = html5.elements;
- return typeof elements == 'string' ? elements.split(' ') : elements;
- }
-
- function getExpandoData(ownerDocument) {
- var data = expandoData[ownerDocument[expando]];
- if (!data) {
- data = {};
- expanID++;
- ownerDocument[expando] = expanID;
- expandoData[expanID] = data;
- }
- return data;
- }
-
- function createElement(nodeName, ownerDocument, data){
- if (!ownerDocument) {
- ownerDocument = document;
- }
- if(supportsUnknownElements){
- return ownerDocument.createElement(nodeName);
- }
- if (!data) {
- data = getExpandoData(ownerDocument);
- }
- var node;
-
- if (data.cache[nodeName]) {
- node = data.cache[nodeName].cloneNode();
- } else if (saveClones.test(nodeName)) {
- node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode();
- } else {
- node = data.createElem(nodeName);
- }
-
- return node.canHaveChildren && !reSkip.test(nodeName) ? data.frag.appendChild(node) : node;
- }
-
- function createDocumentFragment(ownerDocument, data){
- if (!ownerDocument) {
- ownerDocument = document;
- }
- if(supportsUnknownElements){
- return ownerDocument.createDocumentFragment();
- }
- data = data || getExpandoData(ownerDocument);
- var clone = data.frag.cloneNode(),
- i = 0,
- elems = getElements(),
- l = elems.length;
- for(;i",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b)}(this,b),e._version=d,e._prefixes=m,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+q.join(" "):""),e}(this,this.document);
\ No newline at end of file
diff --git a/src/_h5ai/client/js/lib/moment-2.1.0.js b/src/_h5ai/client/js/lib/moment-2.1.0.js
deleted file mode 100644
index c8a870e8..00000000
--- a/src/_h5ai/client/js/lib/moment-2.1.0.js
+++ /dev/null
@@ -1,1662 +0,0 @@
-// moment.js
-// version : 2.1.0
-// author : Tim Wood
-// license : MIT
-// momentjs.com
-
-(function (undefined) {
-
- /************************************
- Constants
- ************************************/
-
- var moment,
- VERSION = "2.1.0",
- round = Math.round, i,
- // internal storage for language config files
- languages = {},
-
- // check for nodeJS
- hasModule = (typeof module !== 'undefined' && module.exports),
-
- // ASP.NET json date format regex
- aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
- aspNetTimeSpanJsonRegex = /(\-)?(\d*)?\.?(\d+)\:(\d+)\:(\d+)\.?(\d{3})?/,
-
- // format tokens
- formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,
- localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,
-
- // parsing token regexes
- parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99
- parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999
- parseTokenThreeDigits = /\d{3}/, // 000 - 999
- parseTokenFourDigits = /\d{1,4}/, // 0 - 9999
- parseTokenSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
- parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic.
- parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/i, // +00:00 -00:00 +0000 -0000 or Z
- parseTokenT = /T/i, // T (ISO seperator)
- parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
-
- // preliminary iso regex
- // 0000-00-00 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000
- isoRegex = /^\s*\d{4}-\d\d-\d\d((T| )(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,
- isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
-
- // iso time formats and regexes
- isoTimes = [
- ['HH:mm:ss.S', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/],
- ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
- ['HH:mm', /(T| )\d\d:\d\d/],
- ['HH', /(T| )\d\d/]
- ],
-
- // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"]
- parseTimezoneChunker = /([\+\-]|\d\d)/gi,
-
- // getter and setter names
- proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
- unitMillisecondFactors = {
- 'Milliseconds' : 1,
- 'Seconds' : 1e3,
- 'Minutes' : 6e4,
- 'Hours' : 36e5,
- 'Days' : 864e5,
- 'Months' : 2592e6,
- 'Years' : 31536e6
- },
-
- unitAliases = {
- ms : 'millisecond',
- s : 'second',
- m : 'minute',
- h : 'hour',
- d : 'day',
- w : 'week',
- M : 'month',
- y : 'year'
- },
-
- // format function strings
- formatFunctions = {},
-
- // tokens to ordinalize and pad
- ordinalizeTokens = 'DDD w W M D d'.split(' '),
- paddedTokens = 'M D H h m s w W'.split(' '),
-
- formatTokenFunctions = {
- M : function () {
- return this.month() + 1;
- },
- MMM : function (format) {
- return this.lang().monthsShort(this, format);
- },
- MMMM : function (format) {
- return this.lang().months(this, format);
- },
- D : function () {
- return this.date();
- },
- DDD : function () {
- return this.dayOfYear();
- },
- d : function () {
- return this.day();
- },
- dd : function (format) {
- return this.lang().weekdaysMin(this, format);
- },
- ddd : function (format) {
- return this.lang().weekdaysShort(this, format);
- },
- dddd : function (format) {
- return this.lang().weekdays(this, format);
- },
- w : function () {
- return this.week();
- },
- W : function () {
- return this.isoWeek();
- },
- YY : function () {
- return leftZeroFill(this.year() % 100, 2);
- },
- YYYY : function () {
- return leftZeroFill(this.year(), 4);
- },
- YYYYY : function () {
- return leftZeroFill(this.year(), 5);
- },
- gg : function () {
- return leftZeroFill(this.weekYear() % 100, 2);
- },
- gggg : function () {
- return this.weekYear();
- },
- ggggg : function () {
- return leftZeroFill(this.weekYear(), 5);
- },
- GG : function () {
- return leftZeroFill(this.isoWeekYear() % 100, 2);
- },
- GGGG : function () {
- return this.isoWeekYear();
- },
- GGGGG : function () {
- return leftZeroFill(this.isoWeekYear(), 5);
- },
- e : function () {
- return this.weekday();
- },
- E : function () {
- return this.isoWeekday();
- },
- a : function () {
- return this.lang().meridiem(this.hours(), this.minutes(), true);
- },
- A : function () {
- return this.lang().meridiem(this.hours(), this.minutes(), false);
- },
- H : function () {
- return this.hours();
- },
- h : function () {
- return this.hours() % 12 || 12;
- },
- m : function () {
- return this.minutes();
- },
- s : function () {
- return this.seconds();
- },
- S : function () {
- return ~~(this.milliseconds() / 100);
- },
- SS : function () {
- return leftZeroFill(~~(this.milliseconds() / 10), 2);
- },
- SSS : function () {
- return leftZeroFill(this.milliseconds(), 3);
- },
- Z : function () {
- var a = -this.zone(),
- b = "+";
- if (a < 0) {
- a = -a;
- b = "-";
- }
- return b + leftZeroFill(~~(a / 60), 2) + ":" + leftZeroFill(~~a % 60, 2);
- },
- ZZ : function () {
- var a = -this.zone(),
- b = "+";
- if (a < 0) {
- a = -a;
- b = "-";
- }
- return b + leftZeroFill(~~(10 * a / 6), 4);
- },
- z : function () {
- return this.zoneAbbr();
- },
- zz : function () {
- return this.zoneName();
- },
- X : function () {
- return this.unix();
- }
- };
-
- function padToken(func, count) {
- return function (a) {
- return leftZeroFill(func.call(this, a), count);
- };
- }
- function ordinalizeToken(func, period) {
- return function (a) {
- return this.lang().ordinal(func.call(this, a), period);
- };
- }
-
- while (ordinalizeTokens.length) {
- i = ordinalizeTokens.pop();
- formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);
- }
- while (paddedTokens.length) {
- i = paddedTokens.pop();
- formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);
- }
- formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);
-
-
- /************************************
- Constructors
- ************************************/
-
- function Language() {
-
- }
-
- // Moment prototype object
- function Moment(config) {
- extend(this, config);
- }
-
- // Duration Constructor
- function Duration(duration) {
- var years = duration.years || duration.year || duration.y || 0,
- months = duration.months || duration.month || duration.M || 0,
- weeks = duration.weeks || duration.week || duration.w || 0,
- days = duration.days || duration.day || duration.d || 0,
- hours = duration.hours || duration.hour || duration.h || 0,
- minutes = duration.minutes || duration.minute || duration.m || 0,
- seconds = duration.seconds || duration.second || duration.s || 0,
- milliseconds = duration.milliseconds || duration.millisecond || duration.ms || 0;
-
- // store reference to input for deterministic cloning
- this._input = duration;
-
- // representation for dateAddRemove
- this._milliseconds = milliseconds +
- seconds * 1e3 + // 1000
- minutes * 6e4 + // 1000 * 60
- hours * 36e5; // 1000 * 60 * 60
- // Because of dateAddRemove treats 24 hours as different from a
- // day when working around DST, we need to store them separately
- this._days = days +
- weeks * 7;
- // It is impossible translate months into days without knowing
- // which months you are are talking about, so we have to store
- // it separately.
- this._months = months +
- years * 12;
-
- this._data = {};
-
- this._bubble();
- }
-
-
- /************************************
- Helpers
- ************************************/
-
-
- function extend(a, b) {
- for (var i in b) {
- if (b.hasOwnProperty(i)) {
- a[i] = b[i];
- }
- }
- return a;
- }
-
- function absRound(number) {
- if (number < 0) {
- return Math.ceil(number);
- } else {
- return Math.floor(number);
- }
- }
-
- // left zero fill a number
- // see http://jsperf.com/left-zero-filling for performance comparison
- function leftZeroFill(number, targetLength) {
- var output = number + '';
- while (output.length < targetLength) {
- output = '0' + output;
- }
- return output;
- }
-
- // helper function for _.addTime and _.subtractTime
- function addOrSubtractDurationFromMoment(mom, duration, isAdding, ignoreUpdateOffset) {
- var milliseconds = duration._milliseconds,
- days = duration._days,
- months = duration._months,
- minutes,
- hours,
- currentDate;
-
- if (milliseconds) {
- mom._d.setTime(+mom._d + milliseconds * isAdding);
- }
- // store the minutes and hours so we can restore them
- if (days || months) {
- minutes = mom.minute();
- hours = mom.hour();
- }
- if (days) {
- mom.date(mom.date() + days * isAdding);
- }
- if (months) {
- mom.month(mom.month() + months * isAdding);
- }
- if (milliseconds && !ignoreUpdateOffset) {
- moment.updateOffset(mom);
- }
- // restore the minutes and hours after possibly changing dst
- if (days || months) {
- mom.minute(minutes);
- mom.hour(hours);
- }
- }
-
- // check if is an array
- function isArray(input) {
- return Object.prototype.toString.call(input) === '[object Array]';
- }
-
- // compare two arrays, return the number of differences
- function compareArrays(array1, array2) {
- var len = Math.min(array1.length, array2.length),
- lengthDiff = Math.abs(array1.length - array2.length),
- diffs = 0,
- i;
- for (i = 0; i < len; i++) {
- if (~~array1[i] !== ~~array2[i]) {
- diffs++;
- }
- }
- return diffs + lengthDiff;
- }
-
- function normalizeUnits(units) {
- return units ? unitAliases[units] || units.toLowerCase().replace(/(.)s$/, '$1') : units;
- }
-
-
- /************************************
- Languages
- ************************************/
-
-
- Language.prototype = {
- set : function (config) {
- var prop, i;
- for (i in config) {
- prop = config[i];
- if (typeof prop === 'function') {
- this[i] = prop;
- } else {
- this['_' + i] = prop;
- }
- }
- },
-
- _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
- months : function (m) {
- return this._months[m.month()];
- },
-
- _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
- monthsShort : function (m) {
- return this._monthsShort[m.month()];
- },
-
- monthsParse : function (monthName) {
- var i, mom, regex;
-
- if (!this._monthsParse) {
- this._monthsParse = [];
- }
-
- for (i = 0; i < 12; i++) {
- // make the regex if we don't have it already
- if (!this._monthsParse[i]) {
- mom = moment([2000, i]);
- regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
- this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
- }
- // test the regex
- if (this._monthsParse[i].test(monthName)) {
- return i;
- }
- }
- },
-
- _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
- weekdays : function (m) {
- return this._weekdays[m.day()];
- },
-
- _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
- weekdaysShort : function (m) {
- return this._weekdaysShort[m.day()];
- },
-
- _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
- weekdaysMin : function (m) {
- return this._weekdaysMin[m.day()];
- },
-
- weekdaysParse : function (weekdayName) {
- var i, mom, regex;
-
- if (!this._weekdaysParse) {
- this._weekdaysParse = [];
- }
-
- for (i = 0; i < 7; i++) {
- // make the regex if we don't have it already
- if (!this._weekdaysParse[i]) {
- mom = moment([2000, 1]).day(i);
- regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
- this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
- }
- // test the regex
- if (this._weekdaysParse[i].test(weekdayName)) {
- return i;
- }
- }
- },
-
- _longDateFormat : {
- LT : "h:mm A",
- L : "MM/DD/YYYY",
- LL : "MMMM D YYYY",
- LLL : "MMMM D YYYY LT",
- LLLL : "dddd, MMMM D YYYY LT"
- },
- longDateFormat : function (key) {
- var output = this._longDateFormat[key];
- if (!output && this._longDateFormat[key.toUpperCase()]) {
- output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
- return val.slice(1);
- });
- this._longDateFormat[key] = output;
- }
- return output;
- },
-
- isPM : function (input) {
- return ((input + '').toLowerCase()[0] === 'p');
- },
-
- _meridiemParse : /[ap]\.?m?\.?/i,
- meridiem : function (hours, minutes, isLower) {
- if (hours > 11) {
- return isLower ? 'pm' : 'PM';
- } else {
- return isLower ? 'am' : 'AM';
- }
- },
-
- _calendar : {
- sameDay : '[Today at] LT',
- nextDay : '[Tomorrow at] LT',
- nextWeek : 'dddd [at] LT',
- lastDay : '[Yesterday at] LT',
- lastWeek : '[Last] dddd [at] LT',
- sameElse : 'L'
- },
- calendar : function (key, mom) {
- var output = this._calendar[key];
- return typeof output === 'function' ? output.apply(mom) : output;
- },
-
- _relativeTime : {
- future : "in %s",
- past : "%s ago",
- s : "a few seconds",
- m : "a minute",
- mm : "%d minutes",
- h : "an hour",
- hh : "%d hours",
- d : "a day",
- dd : "%d days",
- M : "a month",
- MM : "%d months",
- y : "a year",
- yy : "%d years"
- },
- relativeTime : function (number, withoutSuffix, string, isFuture) {
- var output = this._relativeTime[string];
- return (typeof output === 'function') ?
- output(number, withoutSuffix, string, isFuture) :
- output.replace(/%d/i, number);
- },
- pastFuture : function (diff, output) {
- var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
- return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
- },
-
- ordinal : function (number) {
- return this._ordinal.replace("%d", number);
- },
- _ordinal : "%d",
-
- preparse : function (string) {
- return string;
- },
-
- postformat : function (string) {
- return string;
- },
-
- week : function (mom) {
- return weekOfYear(mom, this._week.dow, this._week.doy).week;
- },
- _week : {
- dow : 0, // Sunday is the first day of the week.
- doy : 6 // The week that contains Jan 1st is the first week of the year.
- }
- };
-
- // Loads a language definition into the `languages` cache. The function
- // takes a key and optionally values. If not in the browser and no values
- // are provided, it will load the language file module. As a convenience,
- // this function also returns the language values.
- function loadLang(key, values) {
- values.abbr = key;
- if (!languages[key]) {
- languages[key] = new Language();
- }
- languages[key].set(values);
- return languages[key];
- }
-
- // Determines which language definition to use and returns it.
- //
- // With no parameters, it will return the global language. If you
- // pass in a language key, such as 'en', it will return the
- // definition for 'en', so long as 'en' has already been loaded using
- // moment.lang.
- function getLangDefinition(key) {
- if (!key) {
- return moment.fn._lang;
- }
- if (!languages[key] && hasModule) {
- try {
- require('./lang/' + key);
- } catch (e) {
- // call with no params to set to default
- return moment.fn._lang;
- }
- }
- return languages[key];
- }
-
-
- /************************************
- Formatting
- ************************************/
-
-
- function removeFormattingTokens(input) {
- if (input.match(/\[.*\]/)) {
- return input.replace(/^\[|\]$/g, "");
- }
- return input.replace(/\\/g, "");
- }
-
- function makeFormatFunction(format) {
- var array = format.match(formattingTokens), i, length;
-
- for (i = 0, length = array.length; i < length; i++) {
- if (formatTokenFunctions[array[i]]) {
- array[i] = formatTokenFunctions[array[i]];
- } else {
- array[i] = removeFormattingTokens(array[i]);
- }
- }
-
- return function (mom) {
- var output = "";
- for (i = 0; i < length; i++) {
- output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
- }
- return output;
- };
- }
-
- // format date using native date object
- function formatMoment(m, format) {
- var i = 5;
-
- function replaceLongDateFormatTokens(input) {
- return m.lang().longDateFormat(input) || input;
- }
-
- while (i-- && localFormattingTokens.test(format)) {
- format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
- }
-
- if (!formatFunctions[format]) {
- formatFunctions[format] = makeFormatFunction(format);
- }
-
- return formatFunctions[format](m);
- }
-
-
- /************************************
- Parsing
- ************************************/
-
-
- // get the regex to find the next token
- function getParseRegexForToken(token, config) {
- switch (token) {
- case 'DDDD':
- return parseTokenThreeDigits;
- case 'YYYY':
- return parseTokenFourDigits;
- case 'YYYYY':
- return parseTokenSixDigits;
- case 'S':
- case 'SS':
- case 'SSS':
- case 'DDD':
- return parseTokenOneToThreeDigits;
- case 'MMM':
- case 'MMMM':
- case 'dd':
- case 'ddd':
- case 'dddd':
- return parseTokenWord;
- case 'a':
- case 'A':
- return getLangDefinition(config._l)._meridiemParse;
- case 'X':
- return parseTokenTimestampMs;
- case 'Z':
- case 'ZZ':
- return parseTokenTimezone;
- case 'T':
- return parseTokenT;
- case 'MM':
- case 'DD':
- case 'YY':
- case 'HH':
- case 'hh':
- case 'mm':
- case 'ss':
- case 'M':
- case 'D':
- case 'd':
- case 'H':
- case 'h':
- case 'm':
- case 's':
- return parseTokenOneOrTwoDigits;
- default :
- return new RegExp(token.replace('\\', ''));
- }
- }
-
- function timezoneMinutesFromString(string) {
- var tzchunk = (parseTokenTimezone.exec(string) || [])[0],
- parts = (tzchunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
- minutes = +(parts[1] * 60) + ~~parts[2];
-
- return parts[0] === '+' ? -minutes : minutes;
- }
-
- // function to convert string input to date
- function addTimeToArrayFromToken(token, input, config) {
- var a, datePartArray = config._a;
-
- switch (token) {
- // MONTH
- case 'M' : // fall through to MM
- case 'MM' :
- datePartArray[1] = (input == null) ? 0 : ~~input - 1;
- break;
- case 'MMM' : // fall through to MMMM
- case 'MMMM' :
- a = getLangDefinition(config._l).monthsParse(input);
- // if we didn't find a month name, mark the date as invalid.
- if (a != null) {
- datePartArray[1] = a;
- } else {
- config._isValid = false;
- }
- break;
- // DAY OF MONTH
- case 'D' : // fall through to DDDD
- case 'DD' : // fall through to DDDD
- case 'DDD' : // fall through to DDDD
- case 'DDDD' :
- if (input != null) {
- datePartArray[2] = ~~input;
- }
- break;
- // YEAR
- case 'YY' :
- datePartArray[0] = ~~input + (~~input > 68 ? 1900 : 2000);
- break;
- case 'YYYY' :
- case 'YYYYY' :
- datePartArray[0] = ~~input;
- break;
- // AM / PM
- case 'a' : // fall through to A
- case 'A' :
- config._isPm = getLangDefinition(config._l).isPM(input);
- break;
- // 24 HOUR
- case 'H' : // fall through to hh
- case 'HH' : // fall through to hh
- case 'h' : // fall through to hh
- case 'hh' :
- datePartArray[3] = ~~input;
- break;
- // MINUTE
- case 'm' : // fall through to mm
- case 'mm' :
- datePartArray[4] = ~~input;
- break;
- // SECOND
- case 's' : // fall through to ss
- case 'ss' :
- datePartArray[5] = ~~input;
- break;
- // MILLISECOND
- case 'S' :
- case 'SS' :
- case 'SSS' :
- datePartArray[6] = ~~ (('0.' + input) * 1000);
- break;
- // UNIX TIMESTAMP WITH MS
- case 'X':
- config._d = new Date(parseFloat(input) * 1000);
- break;
- // TIMEZONE
- case 'Z' : // fall through to ZZ
- case 'ZZ' :
- config._useUTC = true;
- config._tzm = timezoneMinutesFromString(input);
- break;
- }
-
- // if the input is null, the date is not valid
- if (input == null) {
- config._isValid = false;
- }
- }
-
- // convert an array to a date.
- // the array should mirror the parameters below
- // note: all values past the year are optional and will default to the lowest possible value.
- // [year, month, day , hour, minute, second, millisecond]
- function dateFromArray(config) {
- var i, date, input = [];
-
- if (config._d) {
- return;
- }
-
- for (i = 0; i < 7; i++) {
- config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
- }
-
- // add the offsets to the time to be parsed so that we can have a clean array for checking isValid
- input[3] += ~~((config._tzm || 0) / 60);
- input[4] += ~~((config._tzm || 0) % 60);
-
- date = new Date(0);
-
- if (config._useUTC) {
- date.setUTCFullYear(input[0], input[1], input[2]);
- date.setUTCHours(input[3], input[4], input[5], input[6]);
- } else {
- date.setFullYear(input[0], input[1], input[2]);
- date.setHours(input[3], input[4], input[5], input[6]);
- }
-
- config._d = date;
- }
-
- // date from string and format string
- function makeDateFromStringAndFormat(config) {
- // This array is used to make a Date, either with `new Date` or `Date.UTC`
- var tokens = config._f.match(formattingTokens),
- string = config._i,
- i, parsedInput;
-
- config._a = [];
-
- for (i = 0; i < tokens.length; i++) {
- parsedInput = (getParseRegexForToken(tokens[i], config).exec(string) || [])[0];
- if (parsedInput) {
- string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
- }
- // don't parse if its not a known token
- if (formatTokenFunctions[tokens[i]]) {
- addTimeToArrayFromToken(tokens[i], parsedInput, config);
- }
- }
-
- // add remaining unparsed input to the string
- if (string) {
- config._il = string;
- }
-
- // handle am pm
- if (config._isPm && config._a[3] < 12) {
- config._a[3] += 12;
- }
- // if is 12 am, change hours to 0
- if (config._isPm === false && config._a[3] === 12) {
- config._a[3] = 0;
- }
- // return
- dateFromArray(config);
- }
-
- // date from string and array of format strings
- function makeDateFromStringAndArray(config) {
- var tempConfig,
- tempMoment,
- bestMoment,
-
- scoreToBeat = 99,
- i,
- currentScore;
-
- for (i = 0; i < config._f.length; i++) {
- tempConfig = extend({}, config);
- tempConfig._f = config._f[i];
- makeDateFromStringAndFormat(tempConfig);
- tempMoment = new Moment(tempConfig);
-
- currentScore = compareArrays(tempConfig._a, tempMoment.toArray());
-
- // if there is any input that was not parsed
- // add a penalty for that format
- if (tempMoment._il) {
- currentScore += tempMoment._il.length;
- }
-
- if (currentScore < scoreToBeat) {
- scoreToBeat = currentScore;
- bestMoment = tempMoment;
- }
- }
-
- extend(config, bestMoment);
- }
-
- // date from iso format
- function makeDateFromString(config) {
- var i,
- string = config._i,
- match = isoRegex.exec(string);
-
- if (match) {
- // match[2] should be "T" or undefined
- config._f = 'YYYY-MM-DD' + (match[2] || " ");
- for (i = 0; i < 4; i++) {
- if (isoTimes[i][1].exec(string)) {
- config._f += isoTimes[i][0];
- break;
- }
- }
- if (parseTokenTimezone.exec(string)) {
- config._f += " Z";
- }
- makeDateFromStringAndFormat(config);
- } else {
- config._d = new Date(string);
- }
- }
-
- function makeDateFromInput(config) {
- var input = config._i,
- matched = aspNetJsonRegex.exec(input);
-
- if (input === undefined) {
- config._d = new Date();
- } else if (matched) {
- config._d = new Date(+matched[1]);
- } else if (typeof input === 'string') {
- makeDateFromString(config);
- } else if (isArray(input)) {
- config._a = input.slice(0);
- dateFromArray(config);
- } else {
- config._d = input instanceof Date ? new Date(+input) : new Date(input);
- }
- }
-
-
- /************************************
- Relative Time
- ************************************/
-
-
- // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
- function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) {
- return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
- }
-
- function relativeTime(milliseconds, withoutSuffix, lang) {
- var seconds = round(Math.abs(milliseconds) / 1000),
- minutes = round(seconds / 60),
- hours = round(minutes / 60),
- days = round(hours / 24),
- years = round(days / 365),
- args = seconds < 45 && ['s', seconds] ||
- minutes === 1 && ['m'] ||
- minutes < 45 && ['mm', minutes] ||
- hours === 1 && ['h'] ||
- hours < 22 && ['hh', hours] ||
- days === 1 && ['d'] ||
- days <= 25 && ['dd', days] ||
- days <= 45 && ['M'] ||
- days < 345 && ['MM', round(days / 30)] ||
- years === 1 && ['y'] || ['yy', years];
- args[2] = withoutSuffix;
- args[3] = milliseconds > 0;
- args[4] = lang;
- return substituteTimeAgo.apply({}, args);
- }
-
-
- /************************************
- Week of Year
- ************************************/
-
-
- // firstDayOfWeek 0 = sun, 6 = sat
- // the day of the week that starts the week
- // (usually sunday or monday)
- // firstDayOfWeekOfYear 0 = sun, 6 = sat
- // the first week is the week that contains the first
- // of this day of the week
- // (eg. ISO weeks use thursday (4))
- function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
- var end = firstDayOfWeekOfYear - firstDayOfWeek,
- daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
- adjustedMoment;
-
-
- if (daysToDayOfWeek > end) {
- daysToDayOfWeek -= 7;
- }
-
- if (daysToDayOfWeek < end - 7) {
- daysToDayOfWeek += 7;
- }
-
- adjustedMoment = moment(mom).add('d', daysToDayOfWeek);
- return {
- week: Math.ceil(adjustedMoment.dayOfYear() / 7),
- year: adjustedMoment.year()
- };
- }
-
-
- /************************************
- Top Level Functions
- ************************************/
-
- function makeMoment(config) {
- var input = config._i,
- format = config._f;
-
- if (input === null || input === '') {
- return null;
- }
-
- if (typeof input === 'string') {
- config._i = input = getLangDefinition().preparse(input);
- }
-
- if (moment.isMoment(input)) {
- config = extend({}, input);
- config._d = new Date(+input._d);
- } else if (format) {
- if (isArray(format)) {
- makeDateFromStringAndArray(config);
- } else {
- makeDateFromStringAndFormat(config);
- }
- } else {
- makeDateFromInput(config);
- }
-
- return new Moment(config);
- }
-
- moment = function (input, format, lang) {
- return makeMoment({
- _i : input,
- _f : format,
- _l : lang,
- _isUTC : false
- });
- };
-
- // creating with utc
- moment.utc = function (input, format, lang) {
- return makeMoment({
- _useUTC : true,
- _isUTC : true,
- _l : lang,
- _i : input,
- _f : format
- });
- };
-
- // creating with unix timestamp (in seconds)
- moment.unix = function (input) {
- return moment(input * 1000);
- };
-
- // duration
- moment.duration = function (input, key) {
- var isDuration = moment.isDuration(input),
- isNumber = (typeof input === 'number'),
- duration = (isDuration ? input._input : (isNumber ? {} : input)),
- matched = aspNetTimeSpanJsonRegex.exec(input),
- sign,
- ret;
-
- if (isNumber) {
- if (key) {
- duration[key] = input;
- } else {
- duration.milliseconds = input;
- }
- } else if (matched) {
- sign = (matched[1] === "-") ? -1 : 1;
- duration = {
- y: 0,
- d: ~~matched[2] * sign,
- h: ~~matched[3] * sign,
- m: ~~matched[4] * sign,
- s: ~~matched[5] * sign,
- ms: ~~matched[6] * sign
- };
- }
-
- ret = new Duration(duration);
-
- if (isDuration && input.hasOwnProperty('_lang')) {
- ret._lang = input._lang;
- }
-
- return ret;
- };
-
- // version number
- moment.version = VERSION;
-
- // default format
- moment.defaultFormat = isoFormat;
-
- // This function will be called whenever a moment is mutated.
- // It is intended to keep the offset in sync with the timezone.
- moment.updateOffset = function () {};
-
- // This function will load languages and then set the global language. If
- // no arguments are passed in, it will simply return the current global
- // language key.
- moment.lang = function (key, values) {
- if (!key) {
- return moment.fn._lang._abbr;
- }
- if (values) {
- loadLang(key, values);
- } else if (!languages[key]) {
- getLangDefinition(key);
- }
- moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key);
- };
-
- // returns language data
- moment.langData = function (key) {
- if (key && key._lang && key._lang._abbr) {
- key = key._lang._abbr;
- }
- return getLangDefinition(key);
- };
-
- // compare moment object
- moment.isMoment = function (obj) {
- return obj instanceof Moment;
- };
-
- // for typechecking Duration objects
- moment.isDuration = function (obj) {
- return obj instanceof Duration;
- };
-
-
- /************************************
- Moment Prototype
- ************************************/
-
-
- moment.fn = Moment.prototype = {
-
- clone : function () {
- return moment(this);
- },
-
- valueOf : function () {
- return +this._d + ((this._offset || 0) * 60000);
- },
-
- unix : function () {
- return Math.floor(+this / 1000);
- },
-
- toString : function () {
- return this.format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
- },
-
- toDate : function () {
- return this._offset ? new Date(+this) : this._d;
- },
-
- toISOString : function () {
- return formatMoment(moment(this).utc(), 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
- },
-
- toArray : function () {
- var m = this;
- return [
- m.year(),
- m.month(),
- m.date(),
- m.hours(),
- m.minutes(),
- m.seconds(),
- m.milliseconds()
- ];
- },
-
- isValid : function () {
- if (this._isValid == null) {
- if (this._a) {
- this._isValid = !compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray());
- } else {
- this._isValid = !isNaN(this._d.getTime());
- }
- }
- return !!this._isValid;
- },
-
- utc : function () {
- return this.zone(0);
- },
-
- local : function () {
- this.zone(0);
- this._isUTC = false;
- return this;
- },
-
- format : function (inputString) {
- var output = formatMoment(this, inputString || moment.defaultFormat);
- return this.lang().postformat(output);
- },
-
- add : function (input, val) {
- var dur;
- // switch args to support add('s', 1) and add(1, 's')
- if (typeof input === 'string') {
- dur = moment.duration(+val, input);
- } else {
- dur = moment.duration(input, val);
- }
- addOrSubtractDurationFromMoment(this, dur, 1);
- return this;
- },
-
- subtract : function (input, val) {
- var dur;
- // switch args to support subtract('s', 1) and subtract(1, 's')
- if (typeof input === 'string') {
- dur = moment.duration(+val, input);
- } else {
- dur = moment.duration(input, val);
- }
- addOrSubtractDurationFromMoment(this, dur, -1);
- return this;
- },
-
- diff : function (input, units, asFloat) {
- var that = this._isUTC ? moment(input).zone(this._offset || 0) : moment(input).local(),
- zoneDiff = (this.zone() - that.zone()) * 6e4,
- diff, output;
-
- units = normalizeUnits(units);
-
- if (units === 'year' || units === 'month') {
- // average number of days in the months in the given dates
- diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2
- // difference in months
- output = ((this.year() - that.year()) * 12) + (this.month() - that.month());
- // adjust by taking difference in days, average number of days
- // and dst in the given months.
- output += ((this - moment(this).startOf('month')) -
- (that - moment(that).startOf('month'))) / diff;
- // same as above but with zones, to negate all dst
- output -= ((this.zone() - moment(this).startOf('month').zone()) -
- (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff;
- if (units === 'year') {
- output = output / 12;
- }
- } else {
- diff = (this - that);
- output = units === 'second' ? diff / 1e3 : // 1000
- units === 'minute' ? diff / 6e4 : // 1000 * 60
- units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
- units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
- units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
- diff;
- }
- return asFloat ? output : absRound(output);
- },
-
- from : function (time, withoutSuffix) {
- return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix);
- },
-
- fromNow : function (withoutSuffix) {
- return this.from(moment(), withoutSuffix);
- },
-
- calendar : function () {
- var diff = this.diff(moment().startOf('day'), 'days', true),
- format = diff < -6 ? 'sameElse' :
- diff < -1 ? 'lastWeek' :
- diff < 0 ? 'lastDay' :
- diff < 1 ? 'sameDay' :
- diff < 2 ? 'nextDay' :
- diff < 7 ? 'nextWeek' : 'sameElse';
- return this.format(this.lang().calendar(format, this));
- },
-
- isLeapYear : function () {
- var year = this.year();
- return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
- },
-
- isDST : function () {
- return (this.zone() < this.clone().month(0).zone() ||
- this.zone() < this.clone().month(5).zone());
- },
-
- day : function (input) {
- var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
- if (input != null) {
- if (typeof input === 'string') {
- input = this.lang().weekdaysParse(input);
- if (typeof input !== 'number') {
- return this;
- }
- }
- return this.add({ d : input - day });
- } else {
- return day;
- }
- },
-
- month : function (input) {
- var utc = this._isUTC ? 'UTC' : '',
- dayOfMonth,
- daysInMonth;
-
- if (input != null) {
- if (typeof input === 'string') {
- input = this.lang().monthsParse(input);
- if (typeof input !== 'number') {
- return this;
- }
- }
-
- dayOfMonth = this.date();
- this.date(1);
- this._d['set' + utc + 'Month'](input);
- this.date(Math.min(dayOfMonth, this.daysInMonth()));
-
- moment.updateOffset(this);
- return this;
- } else {
- return this._d['get' + utc + 'Month']();
- }
- },
-
- startOf: function (units) {
- units = normalizeUnits(units);
- // the following switch intentionally omits break keywords
- // to utilize falling through the cases.
- switch (units) {
- case 'year':
- this.month(0);
- /* falls through */
- case 'month':
- this.date(1);
- /* falls through */
- case 'week':
- case 'day':
- this.hours(0);
- /* falls through */
- case 'hour':
- this.minutes(0);
- /* falls through */
- case 'minute':
- this.seconds(0);
- /* falls through */
- case 'second':
- this.milliseconds(0);
- /* falls through */
- }
-
- // weeks are a special case
- if (units === 'week') {
- this.weekday(0);
- }
-
- return this;
- },
-
- endOf: function (units) {
- return this.startOf(units).add(units, 1).subtract('ms', 1);
- },
-
- isAfter: function (input, units) {
- units = typeof units !== 'undefined' ? units : 'millisecond';
- return +this.clone().startOf(units) > +moment(input).startOf(units);
- },
-
- isBefore: function (input, units) {
- units = typeof units !== 'undefined' ? units : 'millisecond';
- return +this.clone().startOf(units) < +moment(input).startOf(units);
- },
-
- isSame: function (input, units) {
- units = typeof units !== 'undefined' ? units : 'millisecond';
- return +this.clone().startOf(units) === +moment(input).startOf(units);
- },
-
- min: function (other) {
- other = moment.apply(null, arguments);
- return other < this ? this : other;
- },
-
- max: function (other) {
- other = moment.apply(null, arguments);
- return other > this ? this : other;
- },
-
- zone : function (input) {
- var offset = this._offset || 0;
- if (input != null) {
- if (typeof input === "string") {
- input = timezoneMinutesFromString(input);
- }
- if (Math.abs(input) < 16) {
- input = input * 60;
- }
- this._offset = input;
- this._isUTC = true;
- if (offset !== input) {
- addOrSubtractDurationFromMoment(this, moment.duration(offset - input, 'm'), 1, true);
- }
- } else {
- return this._isUTC ? offset : this._d.getTimezoneOffset();
- }
- return this;
- },
-
- zoneAbbr : function () {
- return this._isUTC ? "UTC" : "";
- },
-
- zoneName : function () {
- return this._isUTC ? "Coordinated Universal Time" : "";
- },
-
- daysInMonth : function () {
- return moment.utc([this.year(), this.month() + 1, 0]).date();
- },
-
- dayOfYear : function (input) {
- var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
- return input == null ? dayOfYear : this.add("d", (input - dayOfYear));
- },
-
- weekYear : function (input) {
- var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year;
- return input == null ? year : this.add("y", (input - year));
- },
-
- isoWeekYear : function (input) {
- var year = weekOfYear(this, 1, 4).year;
- return input == null ? year : this.add("y", (input - year));
- },
-
- week : function (input) {
- var week = this.lang().week(this);
- return input == null ? week : this.add("d", (input - week) * 7);
- },
-
- isoWeek : function (input) {
- var week = weekOfYear(this, 1, 4).week;
- return input == null ? week : this.add("d", (input - week) * 7);
- },
-
- weekday : function (input) {
- var weekday = (this._d.getDay() + 7 - this.lang()._week.dow) % 7;
- return input == null ? weekday : this.add("d", input - weekday);
- },
-
- isoWeekday : function (input) {
- // behaves the same as moment#day except
- // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
- // as a setter, sunday should belong to the previous week.
- return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
- },
-
- // If passed a language key, it will set the language for this
- // instance. Otherwise, it will return the language configuration
- // variables for this instance.
- lang : function (key) {
- if (key === undefined) {
- return this._lang;
- } else {
- this._lang = getLangDefinition(key);
- return this;
- }
- }
- };
-
- // helper for adding shortcuts
- function makeGetterAndSetter(name, key) {
- moment.fn[name] = moment.fn[name + 's'] = function (input) {
- var utc = this._isUTC ? 'UTC' : '';
- if (input != null) {
- this._d['set' + utc + key](input);
- moment.updateOffset(this);
- return this;
- } else {
- return this._d['get' + utc + key]();
- }
- };
- }
-
- // loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds)
- for (i = 0; i < proxyGettersAndSetters.length; i ++) {
- makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase().replace(/s$/, ''), proxyGettersAndSetters[i]);
- }
-
- // add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear')
- makeGetterAndSetter('year', 'FullYear');
-
- // add plural methods
- moment.fn.days = moment.fn.day;
- moment.fn.months = moment.fn.month;
- moment.fn.weeks = moment.fn.week;
- moment.fn.isoWeeks = moment.fn.isoWeek;
-
- // add aliased format methods
- moment.fn.toJSON = moment.fn.toISOString;
-
- /************************************
- Duration Prototype
- ************************************/
-
-
- moment.duration.fn = Duration.prototype = {
- _bubble : function () {
- var milliseconds = this._milliseconds,
- days = this._days,
- months = this._months,
- data = this._data,
- seconds, minutes, hours, years;
-
- // The following code bubbles up values, see the tests for
- // examples of what that means.
- data.milliseconds = milliseconds % 1000;
-
- seconds = absRound(milliseconds / 1000);
- data.seconds = seconds % 60;
-
- minutes = absRound(seconds / 60);
- data.minutes = minutes % 60;
-
- hours = absRound(minutes / 60);
- data.hours = hours % 24;
-
- days += absRound(hours / 24);
- data.days = days % 30;
-
- months += absRound(days / 30);
- data.months = months % 12;
-
- years = absRound(months / 12);
- data.years = years;
- },
-
- weeks : function () {
- return absRound(this.days() / 7);
- },
-
- valueOf : function () {
- return this._milliseconds +
- this._days * 864e5 +
- (this._months % 12) * 2592e6 +
- ~~(this._months / 12) * 31536e6;
- },
-
- humanize : function (withSuffix) {
- var difference = +this,
- output = relativeTime(difference, !withSuffix, this.lang());
-
- if (withSuffix) {
- output = this.lang().pastFuture(difference, output);
- }
-
- return this.lang().postformat(output);
- },
-
- add : function (input, val) {
- // supports only 2.0-style add(1, 's') or add(moment)
- var dur = moment.duration(input, val);
-
- this._milliseconds += dur._milliseconds;
- this._days += dur._days;
- this._months += dur._months;
-
- this._bubble();
-
- return this;
- },
-
- subtract : function (input, val) {
- var dur = moment.duration(input, val);
-
- this._milliseconds -= dur._milliseconds;
- this._days -= dur._days;
- this._months -= dur._months;
-
- this._bubble();
-
- return this;
- },
-
- get : function (units) {
- units = normalizeUnits(units);
- return this[units.toLowerCase() + 's']();
- },
-
- as : function (units) {
- units = normalizeUnits(units);
- return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's']();
- },
-
- lang : moment.fn.lang
- };
-
- function makeDurationGetter(name) {
- moment.duration.fn[name] = function () {
- return this._data[name];
- };
- }
-
- function makeDurationAsGetter(name, factor) {
- moment.duration.fn['as' + name] = function () {
- return +this / factor;
- };
- }
-
- for (i in unitMillisecondFactors) {
- if (unitMillisecondFactors.hasOwnProperty(i)) {
- makeDurationAsGetter(i, unitMillisecondFactors[i]);
- makeDurationGetter(i.toLowerCase());
- }
- }
-
- makeDurationAsGetter('Weeks', 6048e5);
- moment.duration.fn.asMonths = function () {
- return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12;
- };
-
-
- /************************************
- Default Lang
- ************************************/
-
-
- // Set default language, other languages will inherit from English.
- moment.lang('en', {
- ordinal : function (number) {
- var b = number % 10,
- output = (~~ (number % 100 / 10) === 1) ? 'th' :
- (b === 1) ? 'st' :
- (b === 2) ? 'nd' :
- (b === 3) ? 'rd' : 'th';
- return number + output;
- }
- });
-
-
- /************************************
- Exposing Moment
- ************************************/
-
-
- // CommonJS module is defined
- if (hasModule) {
- module.exports = moment;
- }
- /*global ender:false */
- if (typeof ender === 'undefined') {
- // here, `this` means `window` in the browser, or `global` on the server
- // add `moment` as a global object via a string identifier,
- // for Closure Compiler "advanced" mode
- this['moment'] = moment;
- }
- /*global define:false */
- if (typeof define === "function" && define.amd) {
- define("moment", [], function () {
- return moment;
- });
- }
-}).call(this);
diff --git a/src/_h5ai/client/js/lib/moment-2.6.0.min.js b/src/_h5ai/client/js/lib/moment-2.6.0.min.js
new file mode 100644
index 00000000..3fe82adf
--- /dev/null
+++ b/src/_h5ai/client/js/lib/moment-2.6.0.min.js
@@ -0,0 +1,6 @@
+//! moment.js
+//! version : 2.6.0
+//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
+//! license : MIT
+//! momentjs.com
+(function(a){function b(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function c(a,b){function c(){ib.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+a)}var d=!0;return i(function(){return d&&(c(),d=!1),b.apply(this,arguments)},b)}function d(a,b){return function(c){return l(a.call(this,c),b)}}function e(a,b){return function(c){return this.lang().ordinal(a.call(this,c),b)}}function f(){}function g(a){y(a),i(this,a)}function h(a){var b=r(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._milliseconds=+k+1e3*j+6e4*i+36e5*h,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._bubble()}function i(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return b.hasOwnProperty("toString")&&(a.toString=b.toString),b.hasOwnProperty("valueOf")&&(a.valueOf=b.valueOf),a}function j(a){var b,c={};for(b in a)a.hasOwnProperty(b)&&wb.hasOwnProperty(b)&&(c[b]=a[b]);return c}function k(a){return 0>a?Math.ceil(a):Math.floor(a)}function l(a,b,c){for(var d=""+Math.abs(a),e=a>=0;d.lengthd;d++)(c&&a[d]!==b[d]||!c&&t(a[d])!==t(b[d]))&&g++;return g+f}function q(a){if(a){var b=a.toLowerCase().replace(/(.)s$/,"$1");a=Zb[a]||$b[b]||b}return a}function r(a){var b,c,d={};for(c in a)a.hasOwnProperty(c)&&(b=q(c),b&&(d[b]=a[c]));return d}function s(b){var c,d;if(0===b.indexOf("week"))c=7,d="day";else{if(0!==b.indexOf("month"))return;c=12,d="month"}ib[b]=function(e,f){var g,h,i=ib.fn._lang[b],j=[];if("number"==typeof e&&(f=e,e=a),h=function(a){var b=ib().utc().set(d,a);return i.call(ib.fn._lang,b,e||"")},null!=f)return h(f);for(g=0;c>g;g++)j.push(h(g));return j}}function t(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=b>=0?Math.floor(b):Math.ceil(b)),c}function u(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function v(a,b,c){return $(ib([a,11,31+b-c]),b,c).week}function w(a){return x(a)?366:365}function x(a){return a%4===0&&a%100!==0||a%400===0}function y(a){var b;a._a&&-2===a._pf.overflow&&(b=a._a[pb]<0||a._a[pb]>11?pb:a._a[qb]<1||a._a[qb]>u(a._a[ob],a._a[pb])?qb:a._a[rb]<0||a._a[rb]>23?rb:a._a[sb]<0||a._a[sb]>59?sb:a._a[tb]<0||a._a[tb]>59?tb:a._a[ub]<0||a._a[ub]>999?ub:-1,a._pf._overflowDayOfYear&&(ob>b||b>qb)&&(b=qb),a._pf.overflow=b)}function z(a){return null==a._isValid&&(a._isValid=!isNaN(a._d.getTime())&&a._pf.overflow<0&&!a._pf.empty&&!a._pf.invalidMonth&&!a._pf.nullInput&&!a._pf.invalidFormat&&!a._pf.userInvalidated,a._strict&&(a._isValid=a._isValid&&0===a._pf.charsLeftOver&&0===a._pf.unusedTokens.length)),a._isValid}function A(a){return a?a.toLowerCase().replace("_","-"):a}function B(a,b){return b._isUTC?ib(a).zone(b._offset||0):ib(a).local()}function C(a,b){return b.abbr=a,vb[a]||(vb[a]=new f),vb[a].set(b),vb[a]}function D(a){delete vb[a]}function E(a){var b,c,d,e,f=0,g=function(a){if(!vb[a]&&xb)try{require("./lang/"+a)}catch(b){}return vb[a]};if(!a)return ib.fn._lang;if(!n(a)){if(c=g(a))return c;a=[a]}for(;f0;){if(c=g(e.slice(0,b).join("-")))return c;if(d&&d.length>=b&&p(e,d,!0)>=b-1)break;b--}f++}return ib.fn._lang}function F(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function G(a){var b,c,d=a.match(Bb);for(b=0,c=d.length;c>b;b++)d[b]=cc[d[b]]?cc[d[b]]:F(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function H(a,b){return a.isValid()?(b=I(b,a.lang()),_b[b]||(_b[b]=G(b)),_b[b](a)):a.lang().invalidDate()}function I(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Cb.lastIndex=0;d>=0&&Cb.test(a);)a=a.replace(Cb,c),Cb.lastIndex=0,d-=1;return a}function J(a,b){var c,d=b._strict;switch(a){case"Q":return Nb;case"DDDD":return Pb;case"YYYY":case"GGGG":case"gggg":return d?Qb:Fb;case"Y":case"G":case"g":return Sb;case"YYYYYY":case"YYYYY":case"GGGGG":case"ggggg":return d?Rb:Gb;case"S":if(d)return Nb;case"SS":if(d)return Ob;case"SSS":if(d)return Pb;case"DDD":return Eb;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return Ib;case"a":case"A":return E(b._l)._meridiemParse;case"X":return Lb;case"Z":case"ZZ":return Jb;case"T":return Kb;case"SSSS":return Hb;case"MM":case"DD":case"YY":case"GG":case"gg":case"HH":case"hh":case"mm":case"ss":case"ww":case"WW":return d?Ob:Db;case"M":case"D":case"d":case"H":case"h":case"m":case"s":case"w":case"W":case"e":case"E":return Db;case"Do":return Mb;default:return c=new RegExp(R(Q(a.replace("\\","")),"i"))}}function K(a){a=a||"";var b=a.match(Jb)||[],c=b[b.length-1]||[],d=(c+"").match(Xb)||["-",0,0],e=+(60*d[1])+t(d[2]);return"+"===d[0]?-e:e}function L(a,b,c){var d,e=c._a;switch(a){case"Q":null!=b&&(e[pb]=3*(t(b)-1));break;case"M":case"MM":null!=b&&(e[pb]=t(b)-1);break;case"MMM":case"MMMM":d=E(c._l).monthsParse(b),null!=d?e[pb]=d:c._pf.invalidMonth=b;break;case"D":case"DD":null!=b&&(e[qb]=t(b));break;case"Do":null!=b&&(e[qb]=t(parseInt(b,10)));break;case"DDD":case"DDDD":null!=b&&(c._dayOfYear=t(b));break;case"YY":e[ob]=ib.parseTwoDigitYear(b);break;case"YYYY":case"YYYYY":case"YYYYYY":e[ob]=t(b);break;case"a":case"A":c._isPm=E(c._l).isPM(b);break;case"H":case"HH":case"h":case"hh":e[rb]=t(b);break;case"m":case"mm":e[sb]=t(b);break;case"s":case"ss":e[tb]=t(b);break;case"S":case"SS":case"SSS":case"SSSS":e[ub]=t(1e3*("0."+b));break;case"X":c._d=new Date(1e3*parseFloat(b));break;case"Z":case"ZZ":c._useUTC=!0,c._tzm=K(b);break;case"w":case"ww":case"W":case"WW":case"d":case"dd":case"ddd":case"dddd":case"e":case"E":a=a.substr(0,1);case"gg":case"gggg":case"GG":case"GGGG":case"GGGGG":a=a.substr(0,2),b&&(c._w=c._w||{},c._w[a]=b)}}function M(a){var b,c,d,e,f,g,h,i,j,k,l=[];if(!a._d){for(d=O(a),a._w&&null==a._a[qb]&&null==a._a[pb]&&(f=function(b){var c=parseInt(b,10);return b?b.length<3?c>68?1900+c:2e3+c:c:null==a._a[ob]?ib().weekYear():a._a[ob]},g=a._w,null!=g.GG||null!=g.W||null!=g.E?h=_(f(g.GG),g.W||1,g.E,4,1):(i=E(a._l),j=null!=g.d?X(g.d,i):null!=g.e?parseInt(g.e,10)+i._week.dow:0,k=parseInt(g.w,10)||1,null!=g.d&&jw(e)&&(a._pf._overflowDayOfYear=!0),c=W(e,0,a._dayOfYear),a._a[pb]=c.getUTCMonth(),a._a[qb]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=l[b]=d[b];for(;7>b;b++)a._a[b]=l[b]=null==a._a[b]?2===b?1:0:a._a[b];l[rb]+=t((a._tzm||0)/60),l[sb]+=t((a._tzm||0)%60),a._d=(a._useUTC?W:V).apply(null,l)}}function N(a){var b;a._d||(b=r(a._i),a._a=[b.year,b.month,b.day,b.hour,b.minute,b.second,b.millisecond],M(a))}function O(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function P(a){a._a=[],a._pf.empty=!0;var b,c,d,e,f,g=E(a._l),h=""+a._i,i=h.length,j=0;for(d=I(a._f,g).match(Bb)||[],b=0;b0&&a._pf.unusedInput.push(f),h=h.slice(h.indexOf(c)+c.length),j+=c.length),cc[e]?(c?a._pf.empty=!1:a._pf.unusedTokens.push(e),L(e,c,a)):a._strict&&!c&&a._pf.unusedTokens.push(e);a._pf.charsLeftOver=i-j,h.length>0&&a._pf.unusedInput.push(h),a._isPm&&a._a[rb]<12&&(a._a[rb]+=12),a._isPm===!1&&12===a._a[rb]&&(a._a[rb]=0),M(a),y(a)}function Q(a){return a.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e})}function R(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function S(a){var c,d,e,f,g;if(0===a._f.length)return a._pf.invalidFormat=!0,void(a._d=new Date(0/0));for(f=0;fg)&&(e=g,d=c));i(a,d||c)}function T(a){var b,c,d=a._i,e=Tb.exec(d);if(e){for(a._pf.iso=!0,b=0,c=Vb.length;c>b;b++)if(Vb[b][1].exec(d)){a._f=Vb[b][0]+(e[6]||" ");break}for(b=0,c=Wb.length;c>b;b++)if(Wb[b][1].exec(d)){a._f+=Wb[b][0];break}d.match(Jb)&&(a._f+="Z"),P(a)}else ib.createFromInputFallback(a)}function U(b){var c=b._i,d=yb.exec(c);c===a?b._d=new Date:d?b._d=new Date(+d[1]):"string"==typeof c?T(b):n(c)?(b._a=c.slice(0),M(b)):o(c)?b._d=new Date(+c):"object"==typeof c?N(b):"number"==typeof c?b._d=new Date(c):ib.createFromInputFallback(b)}function V(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 1970>a&&h.setFullYear(a),h}function W(a){var b=new Date(Date.UTC.apply(null,arguments));return 1970>a&&b.setUTCFullYear(a),b}function X(a,b){if("string"==typeof a)if(isNaN(a)){if(a=b.weekdaysParse(a),"number"!=typeof a)return null}else a=parseInt(a,10);return a}function Y(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function Z(a,b,c){var d=nb(Math.abs(a)/1e3),e=nb(d/60),f=nb(e/60),g=nb(f/24),h=nb(g/365),i=45>d&&["s",d]||1===e&&["m"]||45>e&&["mm",e]||1===f&&["h"]||22>f&&["hh",f]||1===g&&["d"]||25>=g&&["dd",g]||45>=g&&["M"]||345>g&&["MM",nb(g/30)]||1===h&&["y"]||["yy",h];return i[2]=b,i[3]=a>0,i[4]=c,Y.apply({},i)}function $(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=ib(a).add("d",f),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function _(a,b,c,d,e){var f,g,h=W(a,0,1).getUTCDay();return c=null!=c?c:e,f=e-h+(h>d?7:0)-(e>h?7:0),g=7*(b-1)+(c-e)+f+1,{year:g>0?a:a-1,dayOfYear:g>0?g:w(a-1)+g}}function ab(b){var c=b._i,d=b._f;return null===c||d===a&&""===c?ib.invalid({nullInput:!0}):("string"==typeof c&&(b._i=c=E().preparse(c)),ib.isMoment(c)?(b=j(c),b._d=new Date(+c._d)):d?n(d)?S(b):P(b):U(b),new g(b))}function bb(a,b){var c;return"string"==typeof b&&(b=a.lang().monthsParse(b),"number"!=typeof b)?a:(c=Math.min(a.date(),u(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a)}function cb(a,b){return a._d["get"+(a._isUTC?"UTC":"")+b]()}function db(a,b,c){return"Month"===b?bb(a,c):a._d["set"+(a._isUTC?"UTC":"")+b](c)}function eb(a,b){return function(c){return null!=c?(db(this,a,c),ib.updateOffset(this,b),this):cb(this,a)}}function fb(a){ib.duration.fn[a]=function(){return this._data[a]}}function gb(a,b){ib.duration.fn["as"+a]=function(){return+this/b}}function hb(a){"undefined"==typeof ender&&(jb=mb.moment,mb.moment=a?c("Accessing Moment through the global scope is deprecated, and will be removed in an upcoming release.",ib):ib)}for(var ib,jb,kb,lb="2.6.0",mb="undefined"!=typeof global?global:this,nb=Math.round,ob=0,pb=1,qb=2,rb=3,sb=4,tb=5,ub=6,vb={},wb={_isAMomentObject:null,_i:null,_f:null,_l:null,_strict:null,_isUTC:null,_offset:null,_pf:null,_lang:null},xb="undefined"!=typeof module&&module.exports,yb=/^\/?Date\((\-?\d+)/i,zb=/(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,Ab=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,Bb=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g,Cb=/(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,Db=/\d\d?/,Eb=/\d{1,3}/,Fb=/\d{1,4}/,Gb=/[+\-]?\d{1,6}/,Hb=/\d+/,Ib=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Jb=/Z|[\+\-]\d\d:?\d\d/gi,Kb=/T/i,Lb=/[\+\-]?\d+(\.\d{1,3})?/,Mb=/\d{1,2}/,Nb=/\d/,Ob=/\d\d/,Pb=/\d{3}/,Qb=/\d{4}/,Rb=/[+-]?\d{6}/,Sb=/[+-]?\d+/,Tb=/^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Ub="YYYY-MM-DDTHH:mm:ssZ",Vb=[["YYYYYY-MM-DD",/[+-]\d{6}-\d{2}-\d{2}/],["YYYY-MM-DD",/\d{4}-\d{2}-\d{2}/],["GGGG-[W]WW-E",/\d{4}-W\d{2}-\d/],["GGGG-[W]WW",/\d{4}-W\d{2}/],["YYYY-DDD",/\d{4}-\d{3}/]],Wb=[["HH:mm:ss.SSSS",/(T| )\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],Xb=/([\+\-]|\d\d)/gi,Yb=("Date|Hours|Minutes|Seconds|Milliseconds".split("|"),{Milliseconds:1,Seconds:1e3,Minutes:6e4,Hours:36e5,Days:864e5,Months:2592e6,Years:31536e6}),Zb={ms:"millisecond",s:"second",m:"minute",h:"hour",d:"day",D:"date",w:"week",W:"isoWeek",M:"month",Q:"quarter",y:"year",DDD:"dayOfYear",e:"weekday",E:"isoWeekday",gg:"weekYear",GG:"isoWeekYear"},$b={dayofyear:"dayOfYear",isoweekday:"isoWeekday",isoweek:"isoWeek",weekyear:"weekYear",isoweekyear:"isoWeekYear"},_b={},ac="DDD w W M D d".split(" "),bc="M D H h m s w W".split(" "),cc={M:function(){return this.month()+1},MMM:function(a){return this.lang().monthsShort(this,a)},MMMM:function(a){return this.lang().months(this,a)},D:function(){return this.date()},DDD:function(){return this.dayOfYear()},d:function(){return this.day()},dd:function(a){return this.lang().weekdaysMin(this,a)},ddd:function(a){return this.lang().weekdaysShort(this,a)},dddd:function(a){return this.lang().weekdays(this,a)},w:function(){return this.week()},W:function(){return this.isoWeek()},YY:function(){return l(this.year()%100,2)},YYYY:function(){return l(this.year(),4)},YYYYY:function(){return l(this.year(),5)},YYYYYY:function(){var a=this.year(),b=a>=0?"+":"-";return b+l(Math.abs(a),6)},gg:function(){return l(this.weekYear()%100,2)},gggg:function(){return l(this.weekYear(),4)},ggggg:function(){return l(this.weekYear(),5)},GG:function(){return l(this.isoWeekYear()%100,2)},GGGG:function(){return l(this.isoWeekYear(),4)},GGGGG:function(){return l(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.lang().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.lang().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return t(this.milliseconds()/100)},SS:function(){return l(t(this.milliseconds()/10),2)},SSS:function(){return l(this.milliseconds(),3)},SSSS:function(){return l(this.milliseconds(),3)},Z:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+l(t(a/60),2)+":"+l(t(a)%60,2)},ZZ:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+l(t(a/60),2)+l(t(a)%60,2)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},X:function(){return this.unix()},Q:function(){return this.quarter()}},dc=["months","monthsShort","weekdays","weekdaysShort","weekdaysMin"];ac.length;)kb=ac.pop(),cc[kb+"o"]=e(cc[kb],kb);for(;bc.length;)kb=bc.pop(),cc[kb+kb]=d(cc[kb],2);for(cc.DDDD=d(cc.DDD,3),i(f.prototype,{set:function(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(a){return this._months[a.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(a){return this._monthsShort[a.month()]},monthsParse:function(a){var b,c,d;for(this._monthsParse||(this._monthsParse=[]),b=0;12>b;b++)if(this._monthsParse[b]||(c=ib.utc([2e3,b]),d="^"+this.months(c,"")+"|^"+this.monthsShort(c,""),this._monthsParse[b]=new RegExp(d.replace(".",""),"i")),this._monthsParse[b].test(a))return b},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(a){return this._weekdays[a.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(a){return this._weekdaysShort[a.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(a){return this._weekdaysMin[a.day()]},weekdaysParse:function(a){var b,c,d;for(this._weekdaysParse||(this._weekdaysParse=[]),b=0;7>b;b++)if(this._weekdaysParse[b]||(c=ib([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b},_longDateFormat:{LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D YYYY",LLL:"MMMM D YYYY LT",LLLL:"dddd, MMMM D YYYY LT"},longDateFormat:function(a){var b=this._longDateFormat[a];return!b&&this._longDateFormat[a.toUpperCase()]&&(b=this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a]=b),b},isPM:function(a){return"p"===(a+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},calendar:function(a,b){var c=this._calendar[a];return"function"==typeof c?c.apply(b):c},_relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},relativeTime:function(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)},pastFuture:function(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)},ordinal:function(a){return this._ordinal.replace("%d",a)},_ordinal:"%d",preparse:function(a){return a},postformat:function(a){return a},week:function(a){return $(a,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6},_invalidDate:"Invalid date",invalidDate:function(){return this._invalidDate}}),ib=function(c,d,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._i=c,g._f=d,g._l=e,g._strict=f,g._isUTC=!1,g._pf=b(),ab(g)},ib.suppressDeprecationWarnings=!1,ib.createFromInputFallback=c("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i)}),ib.utc=function(c,d,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._useUTC=!0,g._isUTC=!0,g._l=e,g._i=c,g._f=d,g._strict=f,g._pf=b(),ab(g).utc()},ib.unix=function(a){return ib(1e3*a)},ib.duration=function(a,b){var c,d,e,f=a,g=null;return ib.isDuration(a)?f={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(f={},b?f[b]=a:f.milliseconds=a):(g=zb.exec(a))?(c="-"===g[1]?-1:1,f={y:0,d:t(g[qb])*c,h:t(g[rb])*c,m:t(g[sb])*c,s:t(g[tb])*c,ms:t(g[ub])*c}):(g=Ab.exec(a))&&(c="-"===g[1]?-1:1,e=function(a){var b=a&&parseFloat(a.replace(",","."));return(isNaN(b)?0:b)*c},f={y:e(g[2]),M:e(g[3]),d:e(g[4]),h:e(g[5]),m:e(g[6]),s:e(g[7]),w:e(g[8])}),d=new h(f),ib.isDuration(a)&&a.hasOwnProperty("_lang")&&(d._lang=a._lang),d},ib.version=lb,ib.defaultFormat=Ub,ib.momentProperties=wb,ib.updateOffset=function(){},ib.lang=function(a,b){var c;return a?(b?C(A(a),b):null===b?(D(a),a="en"):vb[a]||E(a),c=ib.duration.fn._lang=ib.fn._lang=E(a),c._abbr):ib.fn._lang._abbr},ib.langData=function(a){return a&&a._lang&&a._lang._abbr&&(a=a._lang._abbr),E(a)},ib.isMoment=function(a){return a instanceof g||null!=a&&a.hasOwnProperty("_isAMomentObject")},ib.isDuration=function(a){return a instanceof h},kb=dc.length-1;kb>=0;--kb)s(dc[kb]);ib.normalizeUnits=function(a){return q(a)},ib.invalid=function(a){var b=ib.utc(0/0);return null!=a?i(b._pf,a):b._pf.userInvalidated=!0,b},ib.parseZone=function(){return ib.apply(null,arguments).parseZone()},ib.parseTwoDigitYear=function(a){return t(a)+(t(a)>68?1900:2e3)},i(ib.fn=g.prototype,{clone:function(){return ib(this)},valueOf:function(){return+this._d+6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.clone().lang("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){var a=ib(this).utc();return 00:!1},parsingFlags:function(){return i({},this._pf)},invalidAt:function(){return this._pf.overflow},utc:function(){return this.zone(0)},local:function(){return this.zone(0),this._isUTC=!1,this},format:function(a){var b=H(this,a||ib.defaultFormat);return this.lang().postformat(b)},add:function(a,b){var c;return c="string"==typeof a?ib.duration(+b,a):ib.duration(a,b),m(this,c,1),this},subtract:function(a,b){var c;return c="string"==typeof a?ib.duration(+b,a):ib.duration(a,b),m(this,c,-1),this},diff:function(a,b,c){var d,e,f=B(a,this),g=6e4*(this.zone()-f.zone());return b=q(b),"year"===b||"month"===b?(d=432e5*(this.daysInMonth()+f.daysInMonth()),e=12*(this.year()-f.year())+(this.month()-f.month()),e+=(this-ib(this).startOf("month")-(f-ib(f).startOf("month")))/d,e-=6e4*(this.zone()-ib(this).startOf("month").zone()-(f.zone()-ib(f).startOf("month").zone()))/d,"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:k(e)},from:function(a,b){return ib.duration(this.diff(a)).lang(this.lang()._abbr).humanize(!b)},fromNow:function(a){return this.from(ib(),a)},calendar:function(){var a=B(ib(),this).startOf("day"),b=this.diff(a,"days",!0),c=-6>b?"sameElse":-1>b?"lastWeek":0>b?"lastDay":1>b?"sameDay":2>b?"nextDay":7>b?"nextWeek":"sameElse";return this.format(this.lang().calendar(c,this))},isLeapYear:function(){return x(this.year())},isDST:function(){return this.zone()+ib(a).startOf(b)},isBefore:function(a,b){return b="undefined"!=typeof b?b:"millisecond",+this.clone().startOf(b)<+ib(a).startOf(b)},isSame:function(a,b){return b=b||"ms",+this.clone().startOf(b)===+B(a,this).startOf(b)},min:function(a){return a=ib.apply(null,arguments),this>a?this:a},max:function(a){return a=ib.apply(null,arguments),a>this?this:a},zone:function(a,b){var c=this._offset||0;return null==a?this._isUTC?c:this._d.getTimezoneOffset():("string"==typeof a&&(a=K(a)),Math.abs(a)<16&&(a=60*a),this._offset=a,this._isUTC=!0,c!==a&&(!b||this._changeInProgress?m(this,ib.duration(c-a,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,ib.updateOffset(this,!0),this._changeInProgress=null)),this)},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},parseZone:function(){return this._tzm?this.zone(this._tzm):"string"==typeof this._i&&this.zone(this._i),this},hasAlignedHourOffset:function(a){return a=a?ib(a).zone():0,(this.zone()-a)%60===0},daysInMonth:function(){return u(this.year(),this.month())},dayOfYear:function(a){var b=nb((ib(this).startOf("day")-ib(this).startOf("year"))/864e5)+1;return null==a?b:this.add("d",a-b)},quarter:function(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)},weekYear:function(a){var b=$(this,this.lang()._week.dow,this.lang()._week.doy).year;return null==a?b:this.add("y",a-b)},isoWeekYear:function(a){var b=$(this,1,4).year;return null==a?b:this.add("y",a-b)},week:function(a){var b=this.lang().week(this);return null==a?b:this.add("d",7*(a-b))},isoWeek:function(a){var b=$(this,1,4).week;return null==a?b:this.add("d",7*(a-b))},weekday:function(a){var b=(this.day()+7-this.lang()._week.dow)%7;return null==a?b:this.add("d",a-b)},isoWeekday:function(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)},isoWeeksInYear:function(){return v(this.year(),1,4)},weeksInYear:function(){var a=this._lang._week;return v(this.year(),a.dow,a.doy)},get:function(a){return a=q(a),this[a]()},set:function(a,b){return a=q(a),"function"==typeof this[a]&&this[a](b),this},lang:function(b){return b===a?this._lang:(this._lang=E(b),this)}}),ib.fn.millisecond=ib.fn.milliseconds=eb("Milliseconds",!1),ib.fn.second=ib.fn.seconds=eb("Seconds",!1),ib.fn.minute=ib.fn.minutes=eb("Minutes",!1),ib.fn.hour=ib.fn.hours=eb("Hours",!0),ib.fn.date=eb("Date",!0),ib.fn.dates=c("dates accessor is deprecated. Use date instead.",eb("Date",!0)),ib.fn.year=eb("FullYear",!0),ib.fn.years=c("years accessor is deprecated. Use year instead.",eb("FullYear",!0)),ib.fn.days=ib.fn.day,ib.fn.months=ib.fn.month,ib.fn.weeks=ib.fn.week,ib.fn.isoWeeks=ib.fn.isoWeek,ib.fn.quarters=ib.fn.quarter,ib.fn.toJSON=ib.fn.toISOString,i(ib.duration.fn=h.prototype,{_bubble:function(){var a,b,c,d,e=this._milliseconds,f=this._days,g=this._months,h=this._data;h.milliseconds=e%1e3,a=k(e/1e3),h.seconds=a%60,b=k(a/60),h.minutes=b%60,c=k(b/60),h.hours=c%24,f+=k(c/24),h.days=f%30,g+=k(f/30),h.months=g%12,d=k(g/12),h.years=d},weeks:function(){return k(this.days()/7)},valueOf:function(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*t(this._months/12)},humanize:function(a){var b=+this,c=Z(b,!a,this.lang());return a&&(c=this.lang().pastFuture(b,c)),this.lang().postformat(c)},add:function(a,b){var c=ib.duration(a,b);return this._milliseconds+=c._milliseconds,this._days+=c._days,this._months+=c._months,this._bubble(),this},subtract:function(a,b){var c=ib.duration(a,b);return this._milliseconds-=c._milliseconds,this._days-=c._days,this._months-=c._months,this._bubble(),this},get:function(a){return a=q(a),this[a.toLowerCase()+"s"]()},as:function(a){return a=q(a),this["as"+a.charAt(0).toUpperCase()+a.slice(1)+"s"]()},lang:ib.fn.lang,toIsoString:function(){var a=Math.abs(this.years()),b=Math.abs(this.months()),c=Math.abs(this.days()),d=Math.abs(this.hours()),e=Math.abs(this.minutes()),f=Math.abs(this.seconds()+this.milliseconds()/1e3);return this.asSeconds()?(this.asSeconds()<0?"-":"")+"P"+(a?a+"Y":"")+(b?b+"M":"")+(c?c+"D":"")+(d||e||f?"T":"")+(d?d+"H":"")+(e?e+"M":"")+(f?f+"S":""):"P0D"}});for(kb in Yb)Yb.hasOwnProperty(kb)&&(gb(kb,Yb[kb]),fb(kb.toLowerCase()));gb("Weeks",6048e5),ib.duration.fn.asMonths=function(){return(+this-31536e6*this.years())/2592e6+12*this.years()},ib.lang("en",{ordinal:function(a){var b=a%10,c=1===t(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),xb?module.exports=ib:"function"==typeof define&&define.amd?(define("moment",function(a,b,c){return c.config&&c.config()&&c.config().noGlobal===!0&&(mb.moment=jb),ib}),hb(!0)):hb()}).call(this);
\ No newline at end of file
diff --git a/src/_h5ai/client/js/lib/underscore-1.5.1.js b/src/_h5ai/client/js/lib/underscore-1.6.0.js
similarity index 82%
rename from src/_h5ai/client/js/lib/underscore-1.5.1.js
rename to src/_h5ai/client/js/lib/underscore-1.6.0.js
index 7d4ee27c..9a4cabec 100644
--- a/src/_h5ai/client/js/lib/underscore-1.5.1.js
+++ b/src/_h5ai/client/js/lib/underscore-1.6.0.js
@@ -1,6 +1,6 @@
-// Underscore.js 1.5.1
+// Underscore.js 1.6.0
// http://underscorejs.org
-// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license.
(function() {
@@ -8,7 +8,7 @@
// Baseline setup
// --------------
- // Establish the root object, `window` in the browser, or `global` on the server.
+ // Establish the root object, `window` in the browser, or `exports` on the server.
var root = this;
// Save the previous value of the `_` variable.
@@ -65,7 +65,7 @@
}
// Current version.
- _.VERSION = '1.5.1';
+ _.VERSION = '1.6.0';
// Collection Functions
// --------------------
@@ -74,20 +74,20 @@
// Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available.
var each = _.each = _.forEach = function(obj, iterator, context) {
- if (obj == null) return;
+ if (obj == null) return obj;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
- for (var i = 0, l = obj.length; i < l; i++) {
+ for (var i = 0, length = obj.length; i < length; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker) return;
}
} else {
- for (var key in obj) {
- if (_.has(obj, key)) {
- if (iterator.call(context, obj[key], key, obj) === breaker) return;
- }
+ var keys = _.keys(obj);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
}
}
+ return obj;
};
// Return the results of applying the iterator to each element.
@@ -153,10 +153,10 @@
};
// Return the first value which passes a truth test. Aliased as `detect`.
- _.find = _.detect = function(obj, iterator, context) {
+ _.find = _.detect = function(obj, predicate, context) {
var result;
any(obj, function(value, index, list) {
- if (iterator.call(context, value, index, list)) {
+ if (predicate.call(context, value, index, list)) {
result = value;
return true;
}
@@ -167,33 +167,33 @@
// Return all the elements that pass a truth test.
// Delegates to **ECMAScript 5**'s native `filter` if available.
// Aliased as `select`.
- _.filter = _.select = function(obj, iterator, context) {
+ _.filter = _.select = function(obj, predicate, context) {
var results = [];
if (obj == null) return results;
- if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
+ if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context);
each(obj, function(value, index, list) {
- if (iterator.call(context, value, index, list)) results.push(value);
+ if (predicate.call(context, value, index, list)) results.push(value);
});
return results;
};
// Return all the elements for which a truth test fails.
- _.reject = function(obj, iterator, context) {
+ _.reject = function(obj, predicate, context) {
return _.filter(obj, function(value, index, list) {
- return !iterator.call(context, value, index, list);
+ return !predicate.call(context, value, index, list);
}, context);
};
// Determine whether all of the elements match a truth test.
// Delegates to **ECMAScript 5**'s native `every` if available.
// Aliased as `all`.
- _.every = _.all = function(obj, iterator, context) {
- iterator || (iterator = _.identity);
+ _.every = _.all = function(obj, predicate, context) {
+ predicate || (predicate = _.identity);
var result = true;
if (obj == null) return result;
- if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
+ if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context);
each(obj, function(value, index, list) {
- if (!(result = result && iterator.call(context, value, index, list))) return breaker;
+ if (!(result = result && predicate.call(context, value, index, list))) return breaker;
});
return !!result;
};
@@ -201,13 +201,13 @@
// Determine if at least one element in the object matches a truth test.
// Delegates to **ECMAScript 5**'s native `some` if available.
// Aliased as `any`.
- var any = _.some = _.any = function(obj, iterator, context) {
- iterator || (iterator = _.identity);
+ var any = _.some = _.any = function(obj, predicate, context) {
+ predicate || (predicate = _.identity);
var result = false;
if (obj == null) return result;
- if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
+ if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
each(obj, function(value, index, list) {
- if (result || (result = iterator.call(context, value, index, list))) return breaker;
+ if (result || (result = predicate.call(context, value, index, list))) return breaker;
});
return !!result;
};
@@ -233,25 +233,19 @@
// Convenience version of a common use case of `map`: fetching a property.
_.pluck = function(obj, key) {
- return _.map(obj, function(value){ return value[key]; });
+ return _.map(obj, _.property(key));
};
// Convenience version of a common use case of `filter`: selecting only objects
// containing specific `key:value` pairs.
- _.where = function(obj, attrs, first) {
- if (_.isEmpty(attrs)) return first ? void 0 : [];
- return _[first ? 'find' : 'filter'](obj, function(value) {
- for (var key in attrs) {
- if (attrs[key] !== value[key]) return false;
- }
- return true;
- });
+ _.where = function(obj, attrs) {
+ return _.filter(obj, _.matches(attrs));
};
// Convenience version of a common use case of `find`: getting the first object
// containing specific `key:value` pairs.
_.findWhere = function(obj, attrs) {
- return _.where(obj, attrs, true);
+ return _.find(obj, _.matches(attrs));
};
// Return the maximum element or (element-based computation).
@@ -261,13 +255,15 @@
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.max.apply(Math, obj);
}
- if (!iterator && _.isEmpty(obj)) return -Infinity;
- var result = {computed : -Infinity, value: -Infinity};
+ var result = -Infinity, lastComputed = -Infinity;
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
- computed > result.computed && (result = {value : value, computed : computed});
+ if (computed > lastComputed) {
+ result = value;
+ lastComputed = computed;
+ }
});
- return result.value;
+ return result;
};
// Return the minimum element (or element-based computation).
@@ -275,16 +271,19 @@
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.min.apply(Math, obj);
}
- if (!iterator && _.isEmpty(obj)) return Infinity;
- var result = {computed : Infinity, value: Infinity};
+ var result = Infinity, lastComputed = Infinity;
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
- computed < result.computed && (result = {value : value, computed : computed});
+ if (computed < lastComputed) {
+ result = value;
+ lastComputed = computed;
+ }
});
- return result.value;
+ return result;
};
- // Shuffle an array.
+ // Shuffle an array, using the modern version of the
+ // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
_.shuffle = function(obj) {
var rand;
var index = 0;
@@ -297,19 +296,32 @@
return shuffled;
};
+ // Sample **n** random values from a collection.
+ // If **n** is not specified, returns a single random element.
+ // The internal `guard` argument allows it to work with `map`.
+ _.sample = function(obj, n, guard) {
+ if (n == null || guard) {
+ if (obj.length !== +obj.length) obj = _.values(obj);
+ return obj[_.random(obj.length - 1)];
+ }
+ return _.shuffle(obj).slice(0, Math.max(0, n));
+ };
+
// An internal function to generate lookup iterators.
var lookupIterator = function(value) {
- return _.isFunction(value) ? value : function(obj){ return obj[value]; };
+ if (value == null) return _.identity;
+ if (_.isFunction(value)) return value;
+ return _.property(value);
};
// Sort the object's values by a criterion produced by an iterator.
- _.sortBy = function(obj, value, context) {
- var iterator = lookupIterator(value);
+ _.sortBy = function(obj, iterator, context) {
+ iterator = lookupIterator(iterator);
return _.pluck(_.map(obj, function(value, index, list) {
return {
- value : value,
- index : index,
- criteria : iterator.call(context, value, index, list)
+ value: value,
+ index: index,
+ criteria: iterator.call(context, value, index, list)
};
}).sort(function(left, right) {
var a = left.criteria;
@@ -318,43 +330,46 @@
if (a > b || a === void 0) return 1;
if (a < b || b === void 0) return -1;
}
- return left.index < right.index ? -1 : 1;
+ return left.index - right.index;
}), 'value');
};
// An internal function used for aggregate "group by" operations.
- var group = function(obj, value, context, behavior) {
- var result = {};
- var iterator = lookupIterator(value == null ? _.identity : value);
- each(obj, function(value, index) {
- var key = iterator.call(context, value, index, obj);
- behavior(result, key, value);
- });
- return result;
+ var group = function(behavior) {
+ return function(obj, iterator, context) {
+ var result = {};
+ iterator = lookupIterator(iterator);
+ each(obj, function(value, index) {
+ var key = iterator.call(context, value, index, obj);
+ behavior(result, key, value);
+ });
+ return result;
+ };
};
// Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion.
- _.groupBy = function(obj, value, context) {
- return group(obj, value, context, function(result, key, value) {
- (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
- });
- };
+ _.groupBy = group(function(result, key, value) {
+ _.has(result, key) ? result[key].push(value) : result[key] = [value];
+ });
+
+ // Indexes the object's values by a criterion, similar to `groupBy`, but for
+ // when you know that your index values will be unique.
+ _.indexBy = group(function(result, key, value) {
+ result[key] = value;
+ });
// Counts instances of an object that group by a certain criterion. Pass
// either a string attribute to count by, or a function that returns the
// criterion.
- _.countBy = function(obj, value, context) {
- return group(obj, value, context, function(result, key) {
- if (!_.has(result, key)) result[key] = 0;
- result[key]++;
- });
- };
+ _.countBy = group(function(result, key) {
+ _.has(result, key) ? result[key]++ : result[key] = 1;
+ });
// Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iterator, context) {
- iterator = iterator == null ? _.identity : lookupIterator(iterator);
+ iterator = lookupIterator(iterator);
var value = iterator.call(context, obj);
var low = 0, high = array.length;
while (low < high) {
@@ -386,7 +401,9 @@
// allows it to work with `_.map`.
_.first = _.head = _.take = function(array, n, guard) {
if (array == null) return void 0;
- return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
+ if ((n == null) || guard) return array[0];
+ if (n < 0) return [];
+ return slice.call(array, 0, n);
};
// Returns everything but the last entry of the array. Especially useful on
@@ -401,11 +418,8 @@
// values in the array. The **guard** check allows it to work with `_.map`.
_.last = function(array, n, guard) {
if (array == null) return void 0;
- if ((n != null) && !guard) {
- return slice.call(array, Math.max(array.length - n, 0));
- } else {
- return array[array.length - 1];
- }
+ if ((n == null) || guard) return array[array.length - 1];
+ return slice.call(array, Math.max(array.length - n, 0));
};
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
@@ -436,7 +450,7 @@
return output;
};
- // Return a completely flattened version of an array.
+ // Flatten out an array, either recursively (by default), or just one level.
_.flatten = function(array, shallow) {
return flatten(array, shallow, []);
};
@@ -446,6 +460,16 @@
return _.difference(array, slice.call(arguments, 1));
};
+ // Split an array into two arrays: one whose elements all satisfy the given
+ // predicate, and one whose elements all do not satisfy the predicate.
+ _.partition = function(array, predicate) {
+ var pass = [], fail = [];
+ each(array, function(elem) {
+ (predicate(elem) ? pass : fail).push(elem);
+ });
+ return [pass, fail];
+ };
+
// Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`.
@@ -479,7 +503,7 @@
var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) {
- return _.indexOf(other, item) >= 0;
+ return _.contains(other, item);
});
});
};
@@ -494,7 +518,7 @@
// Zip together multiple lists into a single array -- elements that share
// an index go together.
_.zip = function() {
- var length = _.max(_.pluck(arguments, "length").concat(0));
+ var length = _.max(_.pluck(arguments, 'length').concat(0));
var results = new Array(length);
for (var i = 0; i < length; i++) {
results[i] = _.pluck(arguments, '' + i);
@@ -508,7 +532,7 @@
_.object = function(list, values) {
if (list == null) return {};
var result = {};
- for (var i = 0, l = list.length; i < l; i++) {
+ for (var i = 0, length = list.length; i < length; i++) {
if (values) {
result[list[i]] = values[i];
} else {
@@ -526,17 +550,17 @@
// for **isSorted** to use binary search.
_.indexOf = function(array, item, isSorted) {
if (array == null) return -1;
- var i = 0, l = array.length;
+ var i = 0, length = array.length;
if (isSorted) {
if (typeof isSorted == 'number') {
- i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
+ i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
} else {
i = _.sortedIndex(array, item);
return array[i] === item ? i : -1;
}
}
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
- for (; i < l; i++) if (array[i] === item) return i;
+ for (; i < length; i++) if (array[i] === item) return i;
return -1;
};
@@ -562,11 +586,11 @@
}
step = arguments[2] || 1;
- var len = Math.max(Math.ceil((stop - start) / step), 0);
+ var length = Math.max(Math.ceil((stop - start) / step), 0);
var idx = 0;
- var range = new Array(len);
+ var range = new Array(length);
- while(idx < len) {
+ while(idx < length) {
range[idx++] = start;
start += step;
}
@@ -600,19 +624,27 @@
};
// Partially apply a function by creating a version that has had some of its
- // arguments pre-filled, without changing its dynamic `this` context.
+ // arguments pre-filled, without changing its dynamic `this` context. _ acts
+ // as a placeholder, allowing any combination of arguments to be pre-filled.
_.partial = function(func) {
- var args = slice.call(arguments, 1);
+ var boundArgs = slice.call(arguments, 1);
return function() {
- return func.apply(this, args.concat(slice.call(arguments)));
+ var position = 0;
+ var args = boundArgs.slice();
+ for (var i = 0, length = args.length; i < length; i++) {
+ if (args[i] === _) args[i] = arguments[position++];
+ }
+ while (position < arguments.length) args.push(arguments[position++]);
+ return func.apply(this, args);
};
};
- // Bind all of an object's methods to that object. Useful for ensuring that
- // all callbacks defined on an object belong to it.
+ // Bind a number of an object's methods to that object. Remaining arguments
+ // are the method names to be bound. Useful for ensuring that all callbacks
+ // defined on an object belong to it.
_.bindAll = function(obj) {
var funcs = slice.call(arguments, 1);
- if (funcs.length === 0) throw new Error("bindAll must be passed function names");
+ if (funcs.length === 0) throw new Error('bindAll must be passed function names');
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
return obj;
};
@@ -651,12 +683,13 @@
var previous = 0;
options || (options = {});
var later = function() {
- previous = options.leading === false ? 0 : new Date;
+ previous = options.leading === false ? 0 : _.now();
timeout = null;
result = func.apply(context, args);
+ context = args = null;
};
return function() {
- var now = new Date;
+ var now = _.now();
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
@@ -666,6 +699,7 @@
timeout = null;
previous = now;
result = func.apply(context, args);
+ context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
@@ -678,18 +712,34 @@
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
- var result;
- var timeout = null;
- return function() {
- var context = this, args = arguments;
- var later = function() {
+ var timeout, args, context, timestamp, result;
+
+ var later = function() {
+ var last = _.now() - timestamp;
+ if (last < wait) {
+ timeout = setTimeout(later, wait - last);
+ } else {
timeout = null;
- if (!immediate) result = func.apply(context, args);
- };
+ if (!immediate) {
+ result = func.apply(context, args);
+ context = args = null;
+ }
+ }
+ };
+
+ return function() {
+ context = this;
+ args = arguments;
+ timestamp = _.now();
var callNow = immediate && !timeout;
- clearTimeout(timeout);
- timeout = setTimeout(later, wait);
- if (callNow) result = func.apply(context, args);
+ if (!timeout) {
+ timeout = setTimeout(later, wait);
+ }
+ if (callNow) {
+ result = func.apply(context, args);
+ context = args = null;
+ }
+
return result;
};
};
@@ -711,11 +761,7 @@
// allowing you to adjust arguments, run code before and after, and
// conditionally execute the original function.
_.wrap = function(func, wrapper) {
- return function() {
- var args = [func];
- push.apply(args, arguments);
- return wrapper.apply(this, args);
- };
+ return _.partial(wrapper, func);
};
// Returns a function that is the composition of a list of functions, each
@@ -745,8 +791,9 @@
// Retrieve the names of an object's properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
- _.keys = nativeKeys || function(obj) {
- if (obj !== Object(obj)) throw new TypeError('Invalid object');
+ _.keys = function(obj) {
+ if (!_.isObject(obj)) return [];
+ if (nativeKeys) return nativeKeys(obj);
var keys = [];
for (var key in obj) if (_.has(obj, key)) keys.push(key);
return keys;
@@ -754,22 +801,33 @@
// Retrieve the values of an object's properties.
_.values = function(obj) {
- var values = [];
- for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var values = new Array(length);
+ for (var i = 0; i < length; i++) {
+ values[i] = obj[keys[i]];
+ }
return values;
};
// Convert an object into a list of `[key, value]` pairs.
_.pairs = function(obj) {
- var pairs = [];
- for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
+ var keys = _.keys(obj);
+ var length = keys.length;
+ var pairs = new Array(length);
+ for (var i = 0; i < length; i++) {
+ pairs[i] = [keys[i], obj[keys[i]]];
+ }
return pairs;
};
// Invert the keys and values of an object. The values must be serializable.
_.invert = function(obj) {
var result = {};
- for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
+ var keys = _.keys(obj);
+ for (var i = 0, length = keys.length; i < length; i++) {
+ result[obj[keys[i]]] = keys[i];
+ }
return result;
};
@@ -890,7 +948,8 @@
// from different frames are.
var aCtor = a.constructor, bCtor = b.constructor;
if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
- _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
+ _.isFunction(bCtor) && (bCtor instanceof bCtor))
+ && ('constructor' in a && 'constructor' in b)) {
return false;
}
// Add the first object to the stack of traversed objects.
@@ -1030,6 +1089,30 @@
return value;
};
+ _.constant = function(value) {
+ return function () {
+ return value;
+ };
+ };
+
+ _.property = function(key) {
+ return function(obj) {
+ return obj[key];
+ };
+ };
+
+ // Returns a predicate for checking whether an object has a given set of `key:value` pairs.
+ _.matches = function(attrs) {
+ return function(obj) {
+ if (obj === attrs) return true; //avoid comparing an object to itself.
+ for (var key in attrs) {
+ if (attrs[key] !== obj[key])
+ return false;
+ }
+ return true;
+ }
+ };
+
// Run a function **n** times.
_.times = function(n, iterator, context) {
var accum = Array(Math.max(0, n));
@@ -1046,6 +1129,9 @@
return min + Math.floor(Math.random() * (max - min + 1));
};
+ // A (possibly faster) way to get the current timestamp as an integer.
+ _.now = Date.now || function() { return new Date().getTime(); };
+
// List of HTML entities for escaping.
var entityMap = {
escape: {
@@ -1053,8 +1139,7 @@
'<': '<',
'>': '>',
'"': '"',
- "'": ''',
- '/': '/'
+ "'": '''
}
};
entityMap.unescape = _.invert(entityMap.escape);
@@ -1085,7 +1170,7 @@
// Add your own custom functions to the Underscore object.
_.mixin = function(obj) {
- each(_.functions(obj), function(name){
+ each(_.functions(obj), function(name) {
var func = _[name] = obj[name];
_.prototype[name] = function() {
var args = [this._wrapped];
@@ -1243,4 +1328,16 @@
});
+ // AMD registration happens at the end for compatibility with AMD loaders
+ // that may not enforce next-turn semantics on modules. Even though general
+ // practice for AMD registration is to be anonymous, underscore registers
+ // as a named module because, like jQuery, it is a base library that is
+ // popular enough to be bundled in a third party lib, but not be part of
+ // an AMD load request. Those cases could generate an error when an
+ // anonymous define() is called outside of a loader request.
+ if (typeof define === 'function' && define.amd) {
+ define('underscore', [], function() {
+ return _;
+ });
+ }
}).call(this);
diff --git a/src/_h5ai/client/js/markdown.js b/src/_h5ai/client/js/markdown.js
deleted file mode 100644
index 27be65e6..00000000
--- a/src/_h5ai/client/js/markdown.js
+++ /dev/null
@@ -1,2 +0,0 @@
-
-// @include "lib/markdown-*.js"
diff --git a/src/_h5ai/client/js/qrcode.js b/src/_h5ai/client/js/qrcode.js
deleted file mode 100644
index 1608743f..00000000
--- a/src/_h5ai/client/js/qrcode.js
+++ /dev/null
@@ -1,2 +0,0 @@
-
-// @include "lib/jquery.qrcode-*.js"
diff --git a/src/_h5ai/client/js/scripts.js b/src/_h5ai/client/js/scripts.js
index 7b454a7c..59ba01f7 100644
--- a/src/_h5ai/client/js/scripts.js
+++ b/src/_h5ai/client/js/scripts.js
@@ -3,27 +3,24 @@
// ----------
// @include "lib/modernizr-*.js"
// @include "lib/underscore-*.js"
+// @include "lib/markdown-*.js"
// @include "lib/modulejs-*.js"
// @include "lib/moment-*.js"
// @include "lib/json2-*.js"
-// @include "lib/spin-*.js"
// jQuery libs
// -----------
// @include "lib/jquery-*.js"
-// @include "lib/jquery.filedrop-*.js"
-// @include "lib/jquery.fracs-*.js"
-// @include "lib/jquery.mousewheel-*.js"
-// @include "lib/jquery.scrollpanel-*.js"
-// @include "lib/jquery.spin-*.js"
+// @include "lib/jquery.*.js"
// app
// ---
(function () {
'use strict';
- /*global jQuery, Modernizr, moment, _ */
+ /*global jQuery, markdown, Modernizr, moment, _ */
modulejs.define('$', function () { return jQuery; });
+ modulejs.define('markdown', function () { return markdown; });
modulejs.define('modernizr', function () { return Modernizr; });
modulejs.define('moment', function () { return moment; });
modulejs.define('_', function () { return _; });
@@ -31,27 +28,30 @@
// @include "inc/**/*.js"
var $ = jQuery,
- mode = $('script[src$="scripts.js"]').data('mode');
+ module = $('script[data-module]').data('module'),
+ url;
if ($('html').hasClass('no-browser')) {
-
- } else if (mode === 'info') {
-
- $(function () { modulejs.require('info'); });
-
- } else {
-
- $.ajax({
- url: '.',
- data: {action: 'get', options: true, types: true, langs: true, server: true},
- type: 'POST',
- dataType: 'json',
- success: function (config) {
-
- modulejs.define('config', config);
- $(function () { modulejs.require('main'); });
- }
- });
+ return;
}
+ if (module === 'main') {
+ url = '.';
+ } else if (module === 'info') {
+ url = 'server/php/index.php';
+ } else {
+ return;
+ }
+
+ $.ajax({
+ url: url,
+ data: {action: 'get', setup: true, options: true, types: true, theme: true, langs: true},
+ type: 'POST',
+ dataType: 'json'
+ }).done(function (config) {
+
+ modulejs.define('config', config);
+ $(function () { modulejs.require(module); });
+ });
+
}());
diff --git a/src/_h5ai/client/themes/evolvere/icons/ar-7z.svg b/src/_h5ai/client/themes/evolvere/icons/ar-7z.svg
new file mode 100755
index 00000000..defc7585
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/ar-7z.svg
@@ -0,0 +1,248 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/ar-ace.svg b/src/_h5ai/client/themes/evolvere/icons/ar-ace.svg
new file mode 100755
index 00000000..dcb46463
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/ar-ace.svg
@@ -0,0 +1,248 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/ar-apk.svg b/src/_h5ai/client/themes/evolvere/icons/ar-apk.svg
new file mode 100755
index 00000000..faa3d402
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/ar-apk.svg
@@ -0,0 +1,218 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/ar-bz.svg b/src/_h5ai/client/themes/evolvere/icons/ar-bz.svg
new file mode 100755
index 00000000..7d8a0ea0
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/ar-bz.svg
@@ -0,0 +1,293 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/ar-deb.svg b/src/_h5ai/client/themes/evolvere/icons/ar-deb.svg
new file mode 100755
index 00000000..a94d019b
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/ar-deb.svg
@@ -0,0 +1,325 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/ar-gz.svg b/src/_h5ai/client/themes/evolvere/icons/ar-gz.svg
new file mode 100755
index 00000000..8f023ea9
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/ar-gz.svg
@@ -0,0 +1,497 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/ar-jar.svg b/src/_h5ai/client/themes/evolvere/icons/ar-jar.svg
new file mode 100755
index 00000000..a47e4a96
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/ar-jar.svg
@@ -0,0 +1,250 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/ar-pkg.svg b/src/_h5ai/client/themes/evolvere/icons/ar-pkg.svg
new file mode 100755
index 00000000..d8b409f7
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/ar-pkg.svg
@@ -0,0 +1,249 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/ar-rar.svg b/src/_h5ai/client/themes/evolvere/icons/ar-rar.svg
new file mode 100755
index 00000000..8889c28f
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/ar-rar.svg
@@ -0,0 +1,93 @@
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/ar-rpm.svg b/src/_h5ai/client/themes/evolvere/icons/ar-rpm.svg
new file mode 100755
index 00000000..14b34ccc
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/ar-rpm.svg
@@ -0,0 +1,325 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/ar-tar.svg b/src/_h5ai/client/themes/evolvere/icons/ar-tar.svg
new file mode 100755
index 00000000..94685842
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/ar-tar.svg
@@ -0,0 +1,390 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/ar-tgz.svg b/src/_h5ai/client/themes/evolvere/icons/ar-tgz.svg
new file mode 100755
index 00000000..fe1cbc5a
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/ar-tgz.svg
@@ -0,0 +1,371 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/ar-zip.svg b/src/_h5ai/client/themes/evolvere/icons/ar-zip.svg
new file mode 100755
index 00000000..35fe82e7
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/ar-zip.svg
@@ -0,0 +1,247 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/ar.svg b/src/_h5ai/client/themes/evolvere/icons/ar.svg
new file mode 100755
index 00000000..d8b409f7
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/ar.svg
@@ -0,0 +1,249 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/aud.svg b/src/_h5ai/client/themes/evolvere/icons/aud.svg
new file mode 100755
index 00000000..b9090b0b
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/aud.svg
@@ -0,0 +1,435 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/bak.svg b/src/_h5ai/client/themes/evolvere/icons/bak.svg
new file mode 100755
index 00000000..e06c0768
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/bak.svg
@@ -0,0 +1,278 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/bin-exe.svg b/src/_h5ai/client/themes/evolvere/icons/bin-exe.svg
new file mode 100755
index 00000000..3bbbe8cf
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/bin-exe.svg
@@ -0,0 +1,383 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/bin.svg b/src/_h5ai/client/themes/evolvere/icons/bin.svg
new file mode 100755
index 00000000..395a5cdf
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/bin.svg
@@ -0,0 +1,212 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/disc.svg b/src/_h5ai/client/themes/evolvere/icons/disc.svg
new file mode 100755
index 00000000..e190343a
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/disc.svg
@@ -0,0 +1,1744 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/file.svg b/src/_h5ai/client/themes/evolvere/icons/file.svg
new file mode 100755
index 00000000..3522b369
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/file.svg
@@ -0,0 +1,222 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/img-bmp.svg b/src/_h5ai/client/themes/evolvere/icons/img-bmp.svg
new file mode 100755
index 00000000..4385e420
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/img-bmp.svg
@@ -0,0 +1,413 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/img-gif.svg b/src/_h5ai/client/themes/evolvere/icons/img-gif.svg
new file mode 100755
index 00000000..a5063f9f
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/img-gif.svg
@@ -0,0 +1,575 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/img-ico.svg b/src/_h5ai/client/themes/evolvere/icons/img-ico.svg
new file mode 100755
index 00000000..fd223efb
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/img-ico.svg
@@ -0,0 +1,404 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/img-jpg.svg b/src/_h5ai/client/themes/evolvere/icons/img-jpg.svg
new file mode 100755
index 00000000..f09c1370
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/img-jpg.svg
@@ -0,0 +1,432 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/img-png.svg b/src/_h5ai/client/themes/evolvere/icons/img-png.svg
new file mode 100755
index 00000000..b72b65ec
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/img-png.svg
@@ -0,0 +1,544 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/img-tiff.svg b/src/_h5ai/client/themes/evolvere/icons/img-tiff.svg
new file mode 100755
index 00000000..4fb30250
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/img-tiff.svg
@@ -0,0 +1,376 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/img.svg b/src/_h5ai/client/themes/evolvere/icons/img.svg
new file mode 100755
index 00000000..3ca66a9d
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/img.svg
@@ -0,0 +1,434 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-build.svg b/src/_h5ai/client/themes/evolvere/icons/txt-build.svg
new file mode 100755
index 00000000..8384b783
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-build.svg
@@ -0,0 +1,274 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-c.svg b/src/_h5ai/client/themes/evolvere/icons/txt-c.svg
new file mode 100755
index 00000000..dcdd791f
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-c.svg
@@ -0,0 +1,803 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-cpp.svg b/src/_h5ai/client/themes/evolvere/icons/txt-cpp.svg
new file mode 100755
index 00000000..340f9061
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-cpp.svg
@@ -0,0 +1,1079 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-csv.svg b/src/_h5ai/client/themes/evolvere/icons/txt-csv.svg
new file mode 100755
index 00000000..db3d15d0
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-csv.svg
@@ -0,0 +1,254 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-fortran.svg b/src/_h5ai/client/themes/evolvere/icons/txt-fortran.svg
new file mode 100755
index 00000000..956b1848
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-fortran.svg
@@ -0,0 +1,1115 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-h.svg b/src/_h5ai/client/themes/evolvere/icons/txt-h.svg
new file mode 100755
index 00000000..16085c3b
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-h.svg
@@ -0,0 +1,970 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-hpp.svg b/src/_h5ai/client/themes/evolvere/icons/txt-hpp.svg
new file mode 100755
index 00000000..0483d83e
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-hpp.svg
@@ -0,0 +1,904 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-html.svg b/src/_h5ai/client/themes/evolvere/icons/txt-html.svg
new file mode 100755
index 00000000..4b9f5901
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-html.svg
@@ -0,0 +1,257 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-install.svg b/src/_h5ai/client/themes/evolvere/icons/txt-install.svg
new file mode 100755
index 00000000..3684485a
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-install.svg
@@ -0,0 +1,262 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-java.svg b/src/_h5ai/client/themes/evolvere/icons/txt-java.svg
new file mode 100755
index 00000000..7be3a793
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-java.svg
@@ -0,0 +1,362 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-js.svg b/src/_h5ai/client/themes/evolvere/icons/txt-js.svg
new file mode 100755
index 00000000..a23aba1e
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-js.svg
@@ -0,0 +1,281 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-json.svg b/src/_h5ai/client/themes/evolvere/icons/txt-json.svg
new file mode 100755
index 00000000..a23aba1e
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-json.svg
@@ -0,0 +1,281 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-license.svg b/src/_h5ai/client/themes/evolvere/icons/txt-license.svg
new file mode 100755
index 00000000..bd15a1ee
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-license.svg
@@ -0,0 +1,923 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-log.svg b/src/_h5ai/client/themes/evolvere/icons/txt-log.svg
new file mode 100755
index 00000000..267bee04
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-log.svg
@@ -0,0 +1,306 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-php.svg b/src/_h5ai/client/themes/evolvere/icons/txt-php.svg
new file mode 100755
index 00000000..1a5c91a8
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-php.svg
@@ -0,0 +1,348 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-py.svg b/src/_h5ai/client/themes/evolvere/icons/txt-py.svg
new file mode 100755
index 00000000..3494c5cd
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-py.svg
@@ -0,0 +1,1092 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-readme.svg b/src/_h5ai/client/themes/evolvere/icons/txt-readme.svg
new file mode 100755
index 00000000..f90f30d5
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-readme.svg
@@ -0,0 +1,309 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-rss.svg b/src/_h5ai/client/themes/evolvere/icons/txt-rss.svg
new file mode 100755
index 00000000..b2ccc797
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-rss.svg
@@ -0,0 +1,1794 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-script.svg b/src/_h5ai/client/themes/evolvere/icons/txt-script.svg
new file mode 100755
index 00000000..c0df93ea
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-script.svg
@@ -0,0 +1,284 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-svg.svg b/src/_h5ai/client/themes/evolvere/icons/txt-svg.svg
new file mode 100755
index 00000000..fc8a3fec
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-svg.svg
@@ -0,0 +1,351 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-vcal.svg b/src/_h5ai/client/themes/evolvere/icons/txt-vcal.svg
new file mode 100755
index 00000000..90669e8e
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-vcal.svg
@@ -0,0 +1,642 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt-xml.svg b/src/_h5ai/client/themes/evolvere/icons/txt-xml.svg
new file mode 100755
index 00000000..7c2a085f
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt-xml.svg
@@ -0,0 +1,298 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/txt.svg b/src/_h5ai/client/themes/evolvere/icons/txt.svg
new file mode 100755
index 00000000..ffda30aa
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/txt.svg
@@ -0,0 +1,221 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/vid.svg b/src/_h5ai/client/themes/evolvere/icons/vid.svg
new file mode 100755
index 00000000..c3f1c38e
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/vid.svg
@@ -0,0 +1,565 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/x-calc.svg b/src/_h5ai/client/themes/evolvere/icons/x-calc.svg
new file mode 100755
index 00000000..fb1bc1bf
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/x-calc.svg
@@ -0,0 +1,373 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/x-db.svg b/src/_h5ai/client/themes/evolvere/icons/x-db.svg
new file mode 100755
index 00000000..5537f688
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/x-db.svg
@@ -0,0 +1,465 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/x-doc.svg b/src/_h5ai/client/themes/evolvere/icons/x-doc.svg
new file mode 100755
index 00000000..05544230
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/x-doc.svg
@@ -0,0 +1,275 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/x-flash.svg b/src/_h5ai/client/themes/evolvere/icons/x-flash.svg
new file mode 100755
index 00000000..bb092fc9
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/x-flash.svg
@@ -0,0 +1,374 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/x-font.svg b/src/_h5ai/client/themes/evolvere/icons/x-font.svg
new file mode 100755
index 00000000..e2988bbc
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/x-font.svg
@@ -0,0 +1,857 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/x-pdf.svg b/src/_h5ai/client/themes/evolvere/icons/x-pdf.svg
new file mode 100755
index 00000000..89ad4052
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/x-pdf.svg
@@ -0,0 +1,281 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/x-pres.svg b/src/_h5ai/client/themes/evolvere/icons/x-pres.svg
new file mode 100755
index 00000000..8dce7415
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/x-pres.svg
@@ -0,0 +1,340 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/x-torrent.svg b/src/_h5ai/client/themes/evolvere/icons/x-torrent.svg
new file mode 100755
index 00000000..538b2cbe
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/x-torrent.svg
@@ -0,0 +1,448 @@
+
+
+
+
diff --git a/src/_h5ai/client/themes/evolvere/icons/x.svg b/src/_h5ai/client/themes/evolvere/icons/x.svg
new file mode 100755
index 00000000..e3ec2e17
--- /dev/null
+++ b/src/_h5ai/client/themes/evolvere/icons/x.svg
@@ -0,0 +1,496 @@
+
+
+
+
diff --git a/src/_h5ai/client/icons/96/7zip.png b/src/_h5ai/client/themes/faenza/icons/ar-7z.png
similarity index 100%
rename from src/_h5ai/client/icons/96/7zip.png
rename to src/_h5ai/client/themes/faenza/icons/ar-7z.png
diff --git a/src/_h5ai/client/icons/96/ace.png b/src/_h5ai/client/themes/faenza/icons/ar-ace.png
similarity index 100%
rename from src/_h5ai/client/icons/96/ace.png
rename to src/_h5ai/client/themes/faenza/icons/ar-ace.png
diff --git a/src/_h5ai/client/icons/96/deb.png b/src/_h5ai/client/themes/faenza/icons/ar-deb.png
similarity index 100%
rename from src/_h5ai/client/icons/96/deb.png
rename to src/_h5ai/client/themes/faenza/icons/ar-deb.png
diff --git a/src/_h5ai/client/icons/96/gzip.png b/src/_h5ai/client/themes/faenza/icons/ar-gz.png
similarity index 100%
rename from src/_h5ai/client/icons/96/gzip.png
rename to src/_h5ai/client/themes/faenza/icons/ar-gz.png
diff --git a/src/_h5ai/client/icons/96/jar.png b/src/_h5ai/client/themes/faenza/icons/ar-jar.png
similarity index 100%
rename from src/_h5ai/client/icons/96/jar.png
rename to src/_h5ai/client/themes/faenza/icons/ar-jar.png
diff --git a/src/_h5ai/client/icons/96/rar.png b/src/_h5ai/client/themes/faenza/icons/ar-rar.png
similarity index 100%
rename from src/_h5ai/client/icons/96/rar.png
rename to src/_h5ai/client/themes/faenza/icons/ar-rar.png
diff --git a/src/_h5ai/client/icons/96/rpm.png b/src/_h5ai/client/themes/faenza/icons/ar-rpm.png
similarity index 100%
rename from src/_h5ai/client/icons/96/rpm.png
rename to src/_h5ai/client/themes/faenza/icons/ar-rpm.png
diff --git a/src/_h5ai/client/icons/96/archive.png b/src/_h5ai/client/themes/faenza/icons/ar-tar.png
similarity index 100%
rename from src/_h5ai/client/icons/96/archive.png
rename to src/_h5ai/client/themes/faenza/icons/ar-tar.png
diff --git a/src/_h5ai/client/icons/96/zip.png b/src/_h5ai/client/themes/faenza/icons/ar-zip.png
similarity index 100%
rename from src/_h5ai/client/icons/96/zip.png
rename to src/_h5ai/client/themes/faenza/icons/ar-zip.png
diff --git a/src/_h5ai/client/icons/96/tar.png b/src/_h5ai/client/themes/faenza/icons/ar.png
similarity index 100%
rename from src/_h5ai/client/icons/96/tar.png
rename to src/_h5ai/client/themes/faenza/icons/ar.png
diff --git a/src/_h5ai/client/icons/96/mp3.png b/src/_h5ai/client/themes/faenza/icons/aud-mp3.png
similarity index 100%
rename from src/_h5ai/client/icons/96/mp3.png
rename to src/_h5ai/client/themes/faenza/icons/aud-mp3.png
diff --git a/src/_h5ai/client/icons/96/ogg.png b/src/_h5ai/client/themes/faenza/icons/aud-ogg.png
similarity index 100%
rename from src/_h5ai/client/icons/96/ogg.png
rename to src/_h5ai/client/themes/faenza/icons/aud-ogg.png
diff --git a/src/_h5ai/client/icons/96/playlist.png b/src/_h5ai/client/themes/faenza/icons/aud-pls.png
similarity index 100%
rename from src/_h5ai/client/icons/96/playlist.png
rename to src/_h5ai/client/themes/faenza/icons/aud-pls.png
diff --git a/src/_h5ai/client/icons/96/wav.png b/src/_h5ai/client/themes/faenza/icons/aud-wav.png
similarity index 100%
rename from src/_h5ai/client/icons/96/wav.png
rename to src/_h5ai/client/themes/faenza/icons/aud-wav.png
diff --git a/src/_h5ai/client/icons/96/wma.png b/src/_h5ai/client/themes/faenza/icons/aud-wma.png
similarity index 100%
rename from src/_h5ai/client/icons/96/wma.png
rename to src/_h5ai/client/themes/faenza/icons/aud-wma.png
diff --git a/src/_h5ai/client/icons/96/audio.png b/src/_h5ai/client/themes/faenza/icons/aud.png
similarity index 100%
rename from src/_h5ai/client/icons/96/audio.png
rename to src/_h5ai/client/themes/faenza/icons/aud.png
diff --git a/src/_h5ai/client/icons/96/bak.png b/src/_h5ai/client/themes/faenza/icons/bak.png
similarity index 100%
rename from src/_h5ai/client/icons/96/bak.png
rename to src/_h5ai/client/themes/faenza/icons/bak.png
diff --git a/src/_h5ai/client/icons/96/exe.png b/src/_h5ai/client/themes/faenza/icons/bin-exe.png
similarity index 100%
rename from src/_h5ai/client/icons/96/exe.png
rename to src/_h5ai/client/themes/faenza/icons/bin-exe.png
diff --git a/src/_h5ai/client/icons/96/bin.png b/src/_h5ai/client/themes/faenza/icons/bin.png
similarity index 100%
rename from src/_h5ai/client/icons/96/bin.png
rename to src/_h5ai/client/themes/faenza/icons/bin.png
diff --git a/src/_h5ai/client/icons/96/cd.png b/src/_h5ai/client/themes/faenza/icons/disc.png
similarity index 100%
rename from src/_h5ai/client/icons/96/cd.png
rename to src/_h5ai/client/themes/faenza/icons/disc.png
diff --git a/src/_h5ai/client/icons/96/default.png b/src/_h5ai/client/themes/faenza/icons/file.png
similarity index 100%
rename from src/_h5ai/client/icons/96/default.png
rename to src/_h5ai/client/themes/faenza/icons/file.png
diff --git a/src/_h5ai/client/icons/96/bmp.png b/src/_h5ai/client/themes/faenza/icons/img-bmp.png
similarity index 100%
rename from src/_h5ai/client/icons/96/bmp.png
rename to src/_h5ai/client/themes/faenza/icons/img-bmp.png
diff --git a/src/_h5ai/client/icons/96/gif.png b/src/_h5ai/client/themes/faenza/icons/img-gif.png
similarity index 100%
rename from src/_h5ai/client/icons/96/gif.png
rename to src/_h5ai/client/themes/faenza/icons/img-gif.png
diff --git a/src/_h5ai/client/icons/96/ico.png b/src/_h5ai/client/themes/faenza/icons/img-ico.png
similarity index 100%
rename from src/_h5ai/client/icons/96/ico.png
rename to src/_h5ai/client/themes/faenza/icons/img-ico.png
diff --git a/src/_h5ai/client/icons/96/jpg.png b/src/_h5ai/client/themes/faenza/icons/img-jpg.png
similarity index 100%
rename from src/_h5ai/client/icons/96/jpg.png
rename to src/_h5ai/client/themes/faenza/icons/img-jpg.png
diff --git a/src/_h5ai/client/icons/96/png.png b/src/_h5ai/client/themes/faenza/icons/img-png.png
similarity index 100%
rename from src/_h5ai/client/icons/96/png.png
rename to src/_h5ai/client/themes/faenza/icons/img-png.png
diff --git a/src/_h5ai/client/icons/96/tiff.png b/src/_h5ai/client/themes/faenza/icons/img-tiff.png
similarity index 100%
rename from src/_h5ai/client/icons/96/tiff.png
rename to src/_h5ai/client/themes/faenza/icons/img-tiff.png
diff --git a/src/_h5ai/client/icons/96/xcf.png b/src/_h5ai/client/themes/faenza/icons/img-xcf.png
similarity index 100%
rename from src/_h5ai/client/icons/96/xcf.png
rename to src/_h5ai/client/themes/faenza/icons/img-xcf.png
diff --git a/src/_h5ai/client/icons/96/image.png b/src/_h5ai/client/themes/faenza/icons/img.png
similarity index 100%
rename from src/_h5ai/client/icons/96/image.png
rename to src/_h5ai/client/themes/faenza/icons/img.png
diff --git a/src/_h5ai/client/icons/96/authors.png b/src/_h5ai/client/themes/faenza/icons/txt-authors.png
similarity index 100%
rename from src/_h5ai/client/icons/96/authors.png
rename to src/_h5ai/client/themes/faenza/icons/txt-authors.png
diff --git a/src/_h5ai/client/icons/96/makefile.png b/src/_h5ai/client/themes/faenza/icons/txt-build.png
similarity index 100%
rename from src/_h5ai/client/icons/96/makefile.png
rename to src/_h5ai/client/themes/faenza/icons/txt-build.png
diff --git a/src/_h5ai/client/icons/96/c.png b/src/_h5ai/client/themes/faenza/icons/txt-c.png
similarity index 100%
rename from src/_h5ai/client/icons/96/c.png
rename to src/_h5ai/client/themes/faenza/icons/txt-c.png
diff --git a/src/_h5ai/client/icons/96/cpp.png b/src/_h5ai/client/themes/faenza/icons/txt-cpp.png
similarity index 100%
rename from src/_h5ai/client/icons/96/cpp.png
rename to src/_h5ai/client/themes/faenza/icons/txt-cpp.png
diff --git a/src/_h5ai/client/icons/96/css.png b/src/_h5ai/client/themes/faenza/icons/txt-css.png
similarity index 100%
rename from src/_h5ai/client/icons/96/css.png
rename to src/_h5ai/client/themes/faenza/icons/txt-css.png
diff --git a/src/_h5ai/client/icons/96/diff.png b/src/_h5ai/client/themes/faenza/icons/txt-diff.png
similarity index 100%
rename from src/_h5ai/client/icons/96/diff.png
rename to src/_h5ai/client/themes/faenza/icons/txt-diff.png
diff --git a/src/_h5ai/client/icons/96/h.png b/src/_h5ai/client/themes/faenza/icons/txt-h.png
similarity index 100%
rename from src/_h5ai/client/icons/96/h.png
rename to src/_h5ai/client/themes/faenza/icons/txt-h.png
diff --git a/src/_h5ai/client/icons/96/hpp.png b/src/_h5ai/client/themes/faenza/icons/txt-hpp.png
similarity index 100%
rename from src/_h5ai/client/icons/96/hpp.png
rename to src/_h5ai/client/themes/faenza/icons/txt-hpp.png
diff --git a/src/_h5ai/client/icons/96/html.png b/src/_h5ai/client/themes/faenza/icons/txt-html.png
similarity index 100%
rename from src/_h5ai/client/icons/96/html.png
rename to src/_h5ai/client/themes/faenza/icons/txt-html.png
diff --git a/src/_h5ai/client/icons/96/install.png b/src/_h5ai/client/themes/faenza/icons/txt-install.png
similarity index 100%
rename from src/_h5ai/client/icons/96/install.png
rename to src/_h5ai/client/themes/faenza/icons/txt-install.png
diff --git a/src/_h5ai/client/icons/96/java.png b/src/_h5ai/client/themes/faenza/icons/txt-java.png
similarity index 100%
rename from src/_h5ai/client/icons/96/java.png
rename to src/_h5ai/client/themes/faenza/icons/txt-java.png
diff --git a/src/_h5ai/client/icons/96/js.png b/src/_h5ai/client/themes/faenza/icons/txt-js.png
similarity index 100%
rename from src/_h5ai/client/icons/96/js.png
rename to src/_h5ai/client/themes/faenza/icons/txt-js.png
diff --git a/src/_h5ai/client/icons/96/json.png b/src/_h5ai/client/themes/faenza/icons/txt-json.png
similarity index 100%
rename from src/_h5ai/client/icons/96/json.png
rename to src/_h5ai/client/themes/faenza/icons/txt-json.png
diff --git a/src/_h5ai/client/icons/96/copying.png b/src/_h5ai/client/themes/faenza/icons/txt-license.png
similarity index 100%
rename from src/_h5ai/client/icons/96/copying.png
rename to src/_h5ai/client/themes/faenza/icons/txt-license.png
diff --git a/src/_h5ai/client/icons/96/log.png b/src/_h5ai/client/themes/faenza/icons/txt-log.png
similarity index 100%
rename from src/_h5ai/client/icons/96/log.png
rename to src/_h5ai/client/themes/faenza/icons/txt-log.png
diff --git a/src/_h5ai/client/icons/96/markdown.png b/src/_h5ai/client/themes/faenza/icons/txt-md.png
similarity index 100%
rename from src/_h5ai/client/icons/96/markdown.png
rename to src/_h5ai/client/themes/faenza/icons/txt-md.png
diff --git a/src/_h5ai/client/icons/96/php.png b/src/_h5ai/client/themes/faenza/icons/txt-php.png
similarity index 100%
rename from src/_h5ai/client/icons/96/php.png
rename to src/_h5ai/client/themes/faenza/icons/txt-php.png
diff --git a/src/_h5ai/client/icons/96/py.png b/src/_h5ai/client/themes/faenza/icons/txt-py.png
similarity index 100%
rename from src/_h5ai/client/icons/96/py.png
rename to src/_h5ai/client/themes/faenza/icons/txt-py.png
diff --git a/src/_h5ai/client/icons/96/rb.png b/src/_h5ai/client/themes/faenza/icons/txt-rb.png
similarity index 100%
rename from src/_h5ai/client/icons/96/rb.png
rename to src/_h5ai/client/themes/faenza/icons/txt-rb.png
diff --git a/src/_h5ai/client/icons/96/readme.png b/src/_h5ai/client/themes/faenza/icons/txt-readme.png
similarity index 100%
rename from src/_h5ai/client/icons/96/readme.png
rename to src/_h5ai/client/themes/faenza/icons/txt-readme.png
diff --git a/src/_h5ai/client/icons/96/rss.png b/src/_h5ai/client/themes/faenza/icons/txt-rss.png
similarity index 100%
rename from src/_h5ai/client/icons/96/rss.png
rename to src/_h5ai/client/themes/faenza/icons/txt-rss.png
diff --git a/src/_h5ai/client/icons/96/rtf.png b/src/_h5ai/client/themes/faenza/icons/txt-rtf.png
similarity index 100%
rename from src/_h5ai/client/icons/96/rtf.png
rename to src/_h5ai/client/themes/faenza/icons/txt-rtf.png
diff --git a/src/_h5ai/client/icons/96/script.png b/src/_h5ai/client/themes/faenza/icons/txt-script.png
similarity index 100%
rename from src/_h5ai/client/icons/96/script.png
rename to src/_h5ai/client/themes/faenza/icons/txt-script.png
diff --git a/src/_h5ai/client/icons/96/source.png b/src/_h5ai/client/themes/faenza/icons/txt-source.png
similarity index 100%
rename from src/_h5ai/client/icons/96/source.png
rename to src/_h5ai/client/themes/faenza/icons/txt-source.png
diff --git a/src/_h5ai/client/icons/96/draw.png b/src/_h5ai/client/themes/faenza/icons/txt-svg.png
similarity index 100%
rename from src/_h5ai/client/icons/96/draw.png
rename to src/_h5ai/client/themes/faenza/icons/txt-svg.png
diff --git a/src/_h5ai/client/icons/96/tex.png b/src/_h5ai/client/themes/faenza/icons/txt-tex.png
similarity index 100%
rename from src/_h5ai/client/icons/96/tex.png
rename to src/_h5ai/client/themes/faenza/icons/txt-tex.png
diff --git a/src/_h5ai/client/icons/96/vcal.png b/src/_h5ai/client/themes/faenza/icons/txt-vcal.png
similarity index 100%
rename from src/_h5ai/client/icons/96/vcal.png
rename to src/_h5ai/client/themes/faenza/icons/txt-vcal.png
diff --git a/src/_h5ai/client/icons/96/xml.png b/src/_h5ai/client/themes/faenza/icons/txt-xml.png
similarity index 100%
rename from src/_h5ai/client/icons/96/xml.png
rename to src/_h5ai/client/themes/faenza/icons/txt-xml.png
diff --git a/src/_h5ai/client/icons/96/text.png b/src/_h5ai/client/themes/faenza/icons/txt.png
similarity index 100%
rename from src/_h5ai/client/icons/96/text.png
rename to src/_h5ai/client/themes/faenza/icons/txt.png
diff --git a/src/_h5ai/client/icons/96/video.png b/src/_h5ai/client/themes/faenza/icons/vid.png
similarity index 100%
rename from src/_h5ai/client/icons/96/video.png
rename to src/_h5ai/client/themes/faenza/icons/vid.png
diff --git a/src/_h5ai/client/icons/96/calc.png b/src/_h5ai/client/themes/faenza/icons/x-calc.png
similarity index 100%
rename from src/_h5ai/client/icons/96/calc.png
rename to src/_h5ai/client/themes/faenza/icons/x-calc.png
diff --git a/src/_h5ai/client/icons/96/doc.png b/src/_h5ai/client/themes/faenza/icons/x-doc.png
similarity index 100%
rename from src/_h5ai/client/icons/96/doc.png
rename to src/_h5ai/client/themes/faenza/icons/x-doc.png
diff --git a/src/_h5ai/client/icons/96/svg.png b/src/_h5ai/client/themes/faenza/icons/x-draw.png
similarity index 100%
rename from src/_h5ai/client/icons/96/svg.png
rename to src/_h5ai/client/themes/faenza/icons/x-draw.png
diff --git a/src/_h5ai/client/icons/96/eps.png b/src/_h5ai/client/themes/faenza/icons/x-eps.png
similarity index 100%
rename from src/_h5ai/client/icons/96/eps.png
rename to src/_h5ai/client/themes/faenza/icons/x-eps.png
diff --git a/src/_h5ai/client/icons/96/flash.png b/src/_h5ai/client/themes/faenza/icons/x-flash.png
similarity index 100%
rename from src/_h5ai/client/icons/96/flash.png
rename to src/_h5ai/client/themes/faenza/icons/x-flash.png
diff --git a/src/_h5ai/client/icons/96/font.png b/src/_h5ai/client/themes/faenza/icons/x-font.png
similarity index 100%
rename from src/_h5ai/client/icons/96/font.png
rename to src/_h5ai/client/themes/faenza/icons/x-font.png
diff --git a/src/_h5ai/client/icons/96/pdf.png b/src/_h5ai/client/themes/faenza/icons/x-pdf.png
similarity index 100%
rename from src/_h5ai/client/icons/96/pdf.png
rename to src/_h5ai/client/themes/faenza/icons/x-pdf.png
diff --git a/src/_h5ai/client/icons/96/pgp.png b/src/_h5ai/client/themes/faenza/icons/x-pgp.png
similarity index 100%
rename from src/_h5ai/client/icons/96/pgp.png
rename to src/_h5ai/client/themes/faenza/icons/x-pgp.png
diff --git a/src/_h5ai/client/icons/96/pres.png b/src/_h5ai/client/themes/faenza/icons/x-pres.png
similarity index 100%
rename from src/_h5ai/client/icons/96/pres.png
rename to src/_h5ai/client/themes/faenza/icons/x-pres.png
diff --git a/src/_h5ai/client/icons/96/ps.png b/src/_h5ai/client/themes/faenza/icons/x-ps.png
similarity index 100%
rename from src/_h5ai/client/icons/96/ps.png
rename to src/_h5ai/client/themes/faenza/icons/x-ps.png
diff --git a/src/_h5ai/client/icons/96/psd.png b/src/_h5ai/client/themes/faenza/icons/x-psd.png
similarity index 100%
rename from src/_h5ai/client/icons/96/psd.png
rename to src/_h5ai/client/themes/faenza/icons/x-psd.png
diff --git a/src/_h5ai/client/icons/96/torrent.png b/src/_h5ai/client/themes/faenza/icons/x-torrent.png
similarity index 100%
rename from src/_h5ai/client/icons/96/torrent.png
rename to src/_h5ai/client/themes/faenza/icons/x-torrent.png
diff --git a/src/_h5ai/client/icons/96/unknown.png b/src/_h5ai/client/themes/faenza/icons/x.png
similarity index 100%
rename from src/_h5ai/client/icons/96/unknown.png
rename to src/_h5ai/client/themes/faenza/icons/x.png
diff --git a/src/_h5ai/conf/l10n/bg.json b/src/_h5ai/conf/l10n/bg.json
index 58cf98ae..38324c12 100644
--- a/src/_h5ai/conf/l10n/bg.json
+++ b/src/_h5ai/conf/l10n/bg.json
@@ -1,12 +1,19 @@
{
"lang": "български",
"details": "детайли",
+ "list": "списък",
+ "grid": "мрежа",
"icons": "икони",
"name": "Име",
"lastModified": "Последна промяна",
"size": "Размер",
"parentDirectory": "Предходна директория",
- "empty": "празно",
- "folders": "папки",
- "files": "файлове"
+ "empty": "празна",
+ "folders": "директории",
+ "files": "файлове",
+ "download": "изтегляне",
+ "noMatch": "няма съвпадение",
+ "dateFormat": "DD-MM-YYYY HH:mm",
+ "filter": "филтър",
+ "delete": "изтрий"
}
\ No newline at end of file
diff --git a/src/_h5ai/conf/l10n/fi.json b/src/_h5ai/conf/l10n/fi.json
index c6715bf0..52c6fcc4 100644
--- a/src/_h5ai/conf/l10n/fi.json
+++ b/src/_h5ai/conf/l10n/fi.json
@@ -16,4 +16,4 @@
"dateFormat": "DD.MM.YYYY HH:mm",
"filter": "suodata",
"delete": "poista"
-}
+}
\ No newline at end of file
diff --git a/src/_h5ai/conf/l10n/fr.json b/src/_h5ai/conf/l10n/fr.json
index e2431cd1..dc800d0d 100644
--- a/src/_h5ai/conf/l10n/fr.json
+++ b/src/_h5ai/conf/l10n/fr.json
@@ -16,4 +16,4 @@
"dateFormat": "DD/MM/YYYY HH:mm",
"filter": "filtre",
"delete": "supprimer"
-}
+}
\ No newline at end of file
diff --git a/src/_h5ai/conf/l10n/hi.json b/src/_h5ai/conf/l10n/hi.json
index a6b4f619..c183f911 100644
--- a/src/_h5ai/conf/l10n/hi.json
+++ b/src/_h5ai/conf/l10n/hi.json
@@ -16,4 +16,4 @@
"dateFormat": "DD.MM.YYYY HH:mm",
"filter": "फ़िल्टर",
"delete": "हटाओ"
-}
+}
\ No newline at end of file
diff --git a/src/_h5ai/conf/l10n/ko.json b/src/_h5ai/conf/l10n/ko.json
new file mode 100644
index 00000000..bb9597cf
--- /dev/null
+++ b/src/_h5ai/conf/l10n/ko.json
@@ -0,0 +1,19 @@
+{
+ "lang": "한국어",
+ "details": "자세히",
+ "list": "목록",
+ "grid": "그리드",
+ "icons": "아이콘",
+ "name": "파일명",
+ "lastModified": "최근수정일",
+ "size": "크기",
+ "parentDirectory": "상위폴더",
+ "empty": "빈폴더",
+ "folders": "폴더",
+ "files": "파일",
+ "download": "다운로드",
+ "noMatch": "해당파일이 없습니다.",
+ "dateFormat": "YYYY-MM-DD HH:mm",
+ "filter": "필터",
+ "delete": "삭제"
+}
\ No newline at end of file
diff --git a/src/_h5ai/conf/l10n/pt.json b/src/_h5ai/conf/l10n/pt.json
index 5e238ce0..debe6b63 100644
--- a/src/_h5ai/conf/l10n/pt.json
+++ b/src/_h5ai/conf/l10n/pt.json
@@ -1,12 +1,19 @@
{
"lang": "português",
"details": "detalhes",
+ "list": "lista",
+ "grid": "grelha",
"icons": "ícones",
"name": "Nome",
- "lastModified": "Última modificação",
+ "lastModified": "última modificação",
"size": "Tamanho",
- "parentDirectory": "Diretório superior",
+ "parentDirectory": "diretório acima",
"empty": "vazio",
"folders": "pastas",
- "files": "arquivos"
+ "files": "arquivos",
+ "download": "descarregar",
+ "noMatch": "sem resultados",
+ "dateFormat": "DD-MM-YYYY HH:mm",
+ "filter": "filtro",
+ "delete": "eliminar"
}
\ No newline at end of file
diff --git a/src/_h5ai/conf/l10n/sl.json b/src/_h5ai/conf/l10n/sl.json
new file mode 100644
index 00000000..147041ce
--- /dev/null
+++ b/src/_h5ai/conf/l10n/sl.json
@@ -0,0 +1,19 @@
+{
+ "lang": "slovenščina",
+ "details": "podrobnosti",
+ "list": "seznam",
+ "grid": "mreža",
+ "icons": "ikone",
+ "name": "Ime",
+ "lastModified": "Zadnja sprememba",
+ "size": "Velikost",
+ "parentDirectory": "Nadrejena mapa",
+ "empty": "prazno",
+ "folders": "mape",
+ "files": "datoteke",
+ "download": "prenesi",
+ "noMatch": "ni zadetkov",
+ "dateFormat": "DD. MM. YYYY HH:mm",
+ "filter": "filter",
+ "delete": "izbriši"
+}
\ No newline at end of file
diff --git a/src/_h5ai/conf/l10n/sv.json b/src/_h5ai/conf/l10n/sv.json
index a39589bf..5babca34 100644
--- a/src/_h5ai/conf/l10n/sv.json
+++ b/src/_h5ai/conf/l10n/sv.json
@@ -1,10 +1,17 @@
{
"lang": "svenska",
"details": "detaljerad",
+ "list": "lista",
+ "grid": "rutnät",
"icons": "ikoner",
"name": "Filnamn",
"lastModified": "Senast ändrad",
"size": "Filstorlek",
"parentDirectory": "Till överordnad mapp",
- "empty": "tom"
+ "empty": "tom",
+ "folders": "kataloger",
+ "files": "filer",
+ "download": "ladda ner",
+ "noMatch": "ingen matchning",
+ "delete": "radera"
}
\ No newline at end of file
diff --git a/src/_h5ai/conf/l10n/zh-cn.json b/src/_h5ai/conf/l10n/zh-cn.json
index 1f8e0c23..249a220f 100644
--- a/src/_h5ai/conf/l10n/zh-cn.json
+++ b/src/_h5ai/conf/l10n/zh-cn.json
@@ -1,13 +1,19 @@
{
"lang": "简体中文",
"details": "详情",
+ "list": "列表",
+ "grid": "网格",
"icons": "图标",
"name": "文件名",
- "lastModified": "上次修改",
+ "lastModified": "修改时间",
"size": "大小",
"parentDirectory": "上层文件夹",
"empty": "空文件夹",
"folders": "文件夹",
"files": "文件",
- "download": "下载"
+ "download": "下载",
+ "noMatch": "没有匹配",
+ "dateFormat": "YYYY-MM-DD HH:mm",
+ "filter": "过滤",
+ "delete": "删除"
}
\ No newline at end of file
diff --git a/src/_h5ai/conf/l10n/zh-tw.json b/src/_h5ai/conf/l10n/zh-tw.json
index 1170f347..1e3251f1 100644
--- a/src/_h5ai/conf/l10n/zh-tw.json
+++ b/src/_h5ai/conf/l10n/zh-tw.json
@@ -13,7 +13,7 @@
"files": "檔案",
"download": "下載",
"noMatch": "沒有符合的檔案",
- "dateFormat": "YYYY-MM-DD HH:mm", /* syntax as specified on http://momentjs.com */
+ "dateFormat": "YYYY-MM-DD HH:mm",
"filter": "過濾",
"delete": "刪除"
-}
+}
\ No newline at end of file
diff --git a/src/_h5ai/conf/options.json b/src/_h5ai/conf/options.json
index eb8671c6..be3dea5b 100644
--- a/src/_h5ai/conf/options.json
+++ b/src/_h5ai/conf/options.json
@@ -10,49 +10,53 @@ Options
Spacing of the main content.
Left and right will be added to a minimum of 30px. Top and bottom
- are calculated relative to the top and bottom bar heights.
+ are added to the top and bottom bar heights.
*/
"spacing": {
- "maxWidth": 960,
"top": 50,
- "right": "auto",
"bottom": 50,
- "left": "auto"
+ "left": "auto",
+ "right": "auto",
+ "maxWidth": 1024
},
/*
General view options.
+ - binaryPrefix: set to true uses 1024B=1KiB when formatting file sizes (see http://en.wikipedia.org/wiki/Binary_prefix)
+ - hidden: don't list items matching these regular expressions
+ - hideFolders: hide all folders in the main view
+ - hideIf403: hide files and folders that are not readable by the server
+ - hideParentFolder: hide parent folder links in the main view
- modes: array, subset of ["details", "grid", "icons"]
the first value indicates the default view mode. If only one value
is given the view mode is fixed and the selector buttons are hidden.
The user selected view mode is also stored local in modern browsers
so that it will be persistent.
- - sizes: array, subset of [16, 24, 32, 48, 64, 96]
+ - setParentFolderLabels: set parent folder labels to real folder names
+ - sizes: array, subset of [16, 24, 32, 48, 64, 96, 128, 192, 256, 384]
the first value indicates the default view mode. If only one value
is given the view mode is fixed and the selector buttons are hidden.
The user selected view mode is also stored local in modern browsers
so that it will be persistent.
- - setParentFolderLabels: set parent folder labels to real folder names
- - hideParentFolderLinks: hide parent folder links in the main view
- - hideFolders: hide all folders in the main view
- - binaryPrefix: set to true uses 1024B=1KiB when formatting file sizes (see http://en.wikipedia.org/wiki/Binary_prefix)
- - indexFiles: consider folder with those files as non {{pkg.name}} folders
- - ignore: don't list items matching these regular expressions
- smartBrowsing: use History API if available (no need to reload the whole page)
- - extInNewWindow: open non-h5ai links in new window/tab
+ - theme: name of one of the folders in "_{{pkg.name}}/client/themes", defaults to builtin fallback
+ - unmanaged: don't manage folders containing one of those files
+ - unmanagedInNewWindow: open unmanaged links in new window/tab
*/
"view": {
- "modes": ["details", "grid", "icons"],
- "sizes": [48, 24, 96],
- "setParentFolderLabels": true,
- "hideParentFolderLinks": false,
- "hideFolders": false,
"binaryPrefix": false,
- "indexFiles": ["index.html", "index.htm", "index.php"],
- "ignore": ["^\\.", "^_{{pkg.name}}"],
+ "hidden": ["^\\.", "^_{{pkg.name}}"],
+ "hideFolders": false,
+ "hideIf403": true,
+ "hideParentFolder": false,
+ "modes": ["details", "grid", "icons"],
+ "setParentFolderLabels": true,
+ "sizes": [24, 32, 48, 64, 96],
"smartBrowsing": true,
- "extInNewWindow": false
+ "theme": "",
+ "unmanaged": ["index.html", "index.htm", "index.php"],
+ "unmanagedInNewWindow": false
},
@@ -78,46 +82,30 @@ Options
/*
Allow customized header and footer files.
- First looks for files "_h5ai.header.html" and "_h5ai.footer.html" in the current directory.
- If not found it looks in all parent directories (starting in the current directory) for
- files "_h5ai.headers.html" and "_h5ai.footers.html" until it finds one. Note the different
- filenames: "header" (only current) - "headers" (current and sub directories)!
+ First checks for files "_h5ai.header.html" and "_h5ai.footer.html" in the current directory.
+ If not successful it checks all parent directories (starting in the current directory) for
+ files "_h5ai.headers.html" and "_h5ai.footers.html".
+ Note the different filenames: "header" (only current) - "headers" (current and sub directories)!
The file's content will be placed inside a tag above/below the main content.
+ If a file's extension is ".md" instead of ".html" its content will be interpreted as markdown.
*/
"custom": {
"enabled": true
},
- /* [EXPERIMENTAL]
- Allow file deletion.
- */
- "delete": {
- "enabled": false
- },
-
- /* [EXPERIMENTAL]
- File upload via drag'n'drop. Folders are not supported.
- The working file size seems to be very browser dependent.
-
- - maxfiles: number, max number of files per upload
- - maxfilesize: number, file size is in MB
- */
- "dropbox": {
- "enabled": false,
- "maxfiles": 10,
- "maxfilesize": 1000
- },
-
/*
Enable packaged download of selected entries.
+ To select files the "select"-extension needs to be enabled.
- type: "php-tar", "shell-tar" or "shell-zip"
- packageName: basename of the download package, null for current foldername
+ - alwaysVisible: always show download button (defaults to download the current folder)
*/
"download": {
- "enabled": false,
+ "enabled": true,
"type": "php-tar",
- "packageName": null
+ "packageName": null,
+ "alwaysVisible": false
},
/*
@@ -135,9 +123,15 @@ Options
/*
Calc the size of folders.
+ This operation is real slow. The calculated sizes differ slightly for both
+ calculation types since "php" only adds the file size, while "shell-du"
+ also adds the sizes for the actual folder files.
+
+ - type: "php" (sloooow) or "shell-du" (sloow)
*/
"foldersize": {
- "enabled": false
+ "enabled": false,
+ "type": "php"
},
/*
@@ -151,13 +145,29 @@ Options
["_trackPageLoadTime"]
]
- see: http://support.google.com/googleanalytics/bin/topic.py?hl=en&topic=27612
+ see: https://developers.google.com/analytics/devguides/collection/gajs/
*/
- "google-analytics": {
+ "google-analytics-ga": {
"enabled": false,
"gaq": []
},
+ /*
+ Adds Google Universial Analytics asynchronous tracking code.
+
+ for example:
+ "calls": [
+ ['create', 'UA-XXXX-Y', 'auto'],
+ ['send', 'pageview']
+ ]
+
+ see: https://developers.google.com/analytics/devguides/collection/analyticsjs/
+ */
+ "google-analytics-ua": {
+ "enabled": false,
+ "calls": []
+ },
+
/*
Localization, for example "en", "de" etc. - see "_h5ai/conf/l10n" folder for
possible values. Adjust it to your needs. If lang is not found
@@ -179,19 +189,6 @@ Options
"enabled": true
},
- /*
- Shows the server mode in the bottom left corner.
-
- - display:
- 0: only show mode
- 1: mode and servername
- 2: mode, servername and -version
- */
- "mode": {
- "enabled": true,
- "display": 2
- },
-
/*
Adds Piwik tracker javascript code.
@@ -204,6 +201,16 @@ Options
"idSite": 1
},
+ /*
+ Play a audio preview on click.
+
+ - types: array of types
+ */
+ "preview-aud": {
+ "enabled": true,
+ "types": ["aud"]
+ },
+
/*
Show an image preview on click.
@@ -211,7 +218,7 @@ Options
*/
"preview-img": {
"enabled": true,
- "types": ["bmp", "gif", "ico", "image", "jpg", "png"]
+ "types": ["img", "img-bmp", "img-gif", "img-ico", "img-jpg", "img-png"]
},
/*
@@ -229,32 +236,42 @@ Options
"preview-txt": {
"enabled": true,
"types": {
- "authors": "fixed",
- "copying": "fixed",
- "c": "c",
- "cpp": "cpp",
- "css": "css",
- "diff": "diff",
- "h": "c",
- "hpp": "cpp",
- "install": "fixed",
- "log": "fixed",
- "java": "java",
- "js": "js",
- "json": "js",
- "makefile": "xml",
- "markdown": "markdown",
- // "php": "php",
- "python": "python",
- "readme": "fixed",
- "rb": "ruby",
- "rtf": "fixed",
- "script": "shell",
- "text": "fixed",
- "xml": "xml"
+ "txt": "fixed",
+ "txt-authors": "fixed",
+ "txt-license": "fixed",
+ "txt-c": "c",
+ "txt-cpp": "cpp",
+ "txt-css": "css",
+ "txt-diff": "diff",
+ "txt-h": "c",
+ "txt-hpp": "cpp",
+ "txt-install": "fixed",
+ "txt-log": "fixed",
+ "txt-java": "java",
+ "txt-js": "js",
+ "txt-json": "js",
+ "txt-makefile": "xml",
+ "txt-md": "markdown",
+ // "txt-php": "php",
+ "txt-py": "python",
+ "txt-readme": "fixed",
+ "txt-rb": "ruby",
+ "txt-rtf": "fixed",
+ "txt-script": "shell",
+ "txt-xml": "xml"
}
},
+ /*
+ Play a video preview on click.
+
+ - types: array of types
+ */
+ "preview-vid": {
+ "enabled": true,
+ "types": ["vid"]
+ },
+
/*
Show QRCodes on hovering files.
@@ -265,17 +282,9 @@ Options
"size": 150
},
- /* [EXPERIMENTAL]
- Allow to rename files.
- No GUI yet.
- */
- "rename": {
- "enabled": false
- },
-
/*
Make entries selectable (first mouse button + drag).
- At the moment only needed for packaged download and delete.
+ At the moment only needed for packaged download.
- checkboxes: boolean, show a checkbox on mouse over item
*/
@@ -292,13 +301,15 @@ Options
- reverse: boolean, false for ascending, true for descending
- ignorecase: boolean, compare ignorecase
- natural: boolean, use natural sort order
+ - folders: where to place folders, 0 for "top", 1 for "in place", 2 for "bottom"
*/
"sort": {
"enabled": true,
"column": 0,
"reverse": false,
"ignorecase": true,
- "natural": false
+ "natural": false,
+ "folders": 0
},
/*
@@ -321,9 +332,9 @@ Options
*/
"thumbnails": {
"enabled": true,
- "img": ["bmp", "gif", "ico", "image", "jpg", "png"],
- "mov": ["video"],
- "doc": ["pdf", "ps"],
+ "img": ["img", "img-bmp", "img-gif", "img-ico", "img-jpg", "img-png"],
+ "mov": ["vid"],
+ "doc": ["x-pdf", "x-ps"],
"delay": 1,
"size": 96,
"exif": true
diff --git a/src/_h5ai/conf/types.json b/src/_h5ai/conf/types.json
index 3fa61997..2dc198a7 100644
--- a/src/_h5ai/conf/types.json
+++ b/src/_h5ai/conf/types.json
@@ -6,68 +6,65 @@ File types mapped to file extensions
*/
{
- "archive": [".tar.bz2", ".tar.gz", ".tgz"],
- "audio": [".aif", ".aiff", ".flac", ".m4a", ".mid", ".mp3", ".mpa", ".ra", ".ogg", ".wav", ".wma"],
- "authors": ["authors"],
- "bin": [".class", ".o", ".so"],
- "blank": [],
- "bmp": [".bmp"],
- "c": [".c"],
- "calc": [".ods", ".ots", ".xlr", ".xls", ".xlsx"],
- "cd": [".cue", ".iso"],
- "copying": ["copying", "license"],
- "cpp": [".cpp"],
- "css": [".css", ".less"],
- "deb": [".deb"],
- "default": [],
- "diff": [".diff", ".patch"],
- "doc": [".doc", ".docx", ".odm", ".odt", ".ott"],
- "draw": [".drw"],
- "eps": [".eps"],
- "exe": [".bat", ".cmd", ".exe"],
- "folder": [],
- "folder-page": [],
- "folder-parent": [],
- "gif": [".gif"],
- "gzip": [".gz"],
- "h": [".h"],
- "hpp": [".hpp"],
- "html": [".htm", ".html", ".shtml"],
- "ico": [".ico"],
- "image": [".svg", ".xpm"],
- "install": ["install"],
- "java": [".java"],
- "jpg": [".jpg", ".jpeg"],
- "js": [".js"],
- "json": [".json"],
- "log": [".log", "changelog"],
- "makefile": [".pom", "build.xml", "pom.xml"],
- "markdown": [".markdown", ".md"],
- "package": [],
- "pdf": [".pdf"],
- "php": [".php"],
- "playlist": [".m3u", ".m3u8", ".pls"],
- "png": [".png"],
- "pres": [".odp", ".otp", ".pps", ".ppt", ".pptx"],
- "ps": [".ps"],
- "psd": [".psd"],
- "py": [".py"],
- "rar": [".rar"],
- "rb": [".rb"],
- "readme": ["readme"],
- "rpm": [".rpm"],
- "rss": [".rss"],
- "rtf": [".rtf"],
- "script": [".conf", ".csh", ".ini", ".ksh", ".sh", ".shar", ".tcl"],
- "source": [],
- "sql": [],
- "tar": [".tar"],
- "tex": [".tex"],
- "text": [".text", ".txt"],
- "tiff": [".tiff"],
- "unknown": [],
- "vcal": [".vcal"],
- "video": [".avi", ".flv", ".mkv", ".mov", ".m4v", ".mp4", ".mpg", ".rm", ".swf", ".ts", ".vob", ".wmv"],
- "xml": [".xml"],
- "zip": [".7z", ".bz2", ".jar", ".lzma", ".war", ".z", ".Z", ".zip"]
+ // "txt-authors": ["author*"],
+ // "txt-install": ["install*"],
+ // "txt-license": ["copying*", "license*"],
+ // "txt-readme": ["readme*"],
+
+ "ar": ["*.tar.bz2", "*.tar.gz", "*.tgz"],
+ "ar-apk": ["*.apk"],
+ "ar-deb": ["*.deb"],
+ "ar-gz": ["*.gz"],
+ "ar-rar": ["*.rar"],
+ "ar-rpm": ["*.rpm"],
+ "ar-tar": ["*.tar"],
+ "ar-zip": ["*.7z", "*.bz2", "*.jar", "*.lzma", "*.war", "*.z", "*.Z", "*.zip"],
+ "aud": ["*.aif", "*.aiff", "*.flac", "*.m4a", "*.mid", "*.mp3", "*.mpa", "*.ra", "*.ogg", "*.wav", "*.wma"],
+ "aud-pls": ["*.m3u", "*.m3u8", "*.pls"],
+ "bak": ["*.bak", "*~"],
+ "bin": ["*.class", "*.o", "*.so"],
+ "bin-exe": ["*.bat", "*.cmd", "*.exe"],
+ "disc": ["*.cue", "*.iso"],
+ "img": ["*.xpm"],
+ "img-bmp": ["*.bmp"],
+ "img-gif": ["*.gif"],
+ "img-ico": ["*.ico"],
+ "img-jpg": ["*.jpg", "*.jpeg"],
+ "img-png": ["*.png"],
+ "img-tiff": ["*.tiff"],
+ "txt": ["*.text", "*.txt"],
+ "txt-build": ["*.pom", "build.xml", "pom.xml"],
+ "txt-c": ["*.c"],
+ "txt-cpp": ["*.cpp"],
+ "txt-css": ["*.css", "*.less"],
+ "txt-diff": ["*.diff", "*.patch"],
+ "txt-h": ["*.h"],
+ "txt-html": ["*.htm", "*.html", "*.shtml", "*.xhtml"],
+ "txt-hpp": ["*.hpp"],
+ "txt-java": ["*.java"],
+ "txt-js": ["*.js"],
+ "txt-json": ["*.json"],
+ "txt-log": ["*.log", "changelog*"],
+ "txt-md": ["*.markdown", "*.md"],
+ "txt-php": ["*.php"],
+ "txt-py": ["*.py"],
+ "txt-rb": ["*.rb"],
+ "txt-rss": ["*.rss"],
+ "txt-rtf": ["*.rtf"],
+ "txt-script": ["*.conf", "*.bsh", "*.csh", "*.ini", "*.ksh", "*.sh", "*.shar", "*.tcl", "*.zsh"],
+ "txt-source": [],
+ "txt-svg": ["*.svg"],
+ "txt-tex": ["*.tex"],
+ "txt-vcal": ["*.vcal"],
+ "txt-xml": ["*.xml"],
+ "vid": ["*.avi", "*.flv", "*.mkv", "*.mov", "*.m4v", "*.mp4", "*.mpg", "*.rm", "*.swf", "*.ts", "*.vob", "*.webm", "*.wmv"],
+ "x": [],
+ "x-calc": ["*.ods", "*.ots", "*.xlr", "*.xls", "*.xlsx"],
+ "x-doc": ["*.doc", "*.docx", "*.odm", "*.odt", "*.ott"],
+ "x-draw": ["*.drw"],
+ "x-eps": ["*.eps"],
+ "x-pdf": ["*.pdf"],
+ "x-pres": ["*.odp", "*.otp", "*.pps", "*.ppt", "*.pptx"],
+ "x-ps": ["*.ps"],
+ "x-psd": ["*.psd"]
}
diff --git a/src/_h5ai/index.html.jade b/src/_h5ai/index.html.jade
index e09cbed6..b6204a1a 100644
--- a/src/_h5ai/index.html.jade
+++ b/src/_h5ai/index.html.jade
@@ -1,98 +1,42 @@
doctype 5
-//if lt IE 9
+//if lt IE 10
-//[if gt IE 8]>app = $app;
- }
-
-
- public function apply() {
-
- $options = $this->app->get_options();
-
- list($action) = use_request_params(array("action"));
-
- if ($action === "get") {
-
- $response = array();
-
- if (array_key_exists("options", $_REQUEST)) {
-
- use_request_params("options");
- $response["options"] = $this->app->get_options();
- }
-
- if (array_key_exists("types", $_REQUEST)) {
-
- use_request_params("types");
- $response["types"] = $this->app->get_types();
- }
-
- if (array_key_exists("langs", $_REQUEST)) {
-
- use_request_params("langs");
- $response["langs"] = $this->app->get_l10n_list();
- }
-
- if (array_key_exists("l10n", $_REQUEST)) {
-
- list($iso_codes) = use_request_params("l10nCodes", "l10n");
- $iso_codes = explode(":", $iso_codes);
- $response["l10n"] = $this->app->get_l10n($iso_codes);
- }
-
- if (array_key_exists("checks", $_REQUEST)) {
-
- use_request_params("checks");
- $response["checks"] = $this->app->get_server_checks();
- }
-
- if (array_key_exists("server", $_REQUEST)) {
-
- use_request_params("server");
- $response["server"] = $this->app->get_server_details();
- }
-
- if (array_key_exists("custom", $_REQUEST)) {
-
- list($abs_href) = use_optional_request_params("customHref", "custom");
- $response["custom"] = $this->app->get_customizations($abs_href);
- }
-
- if (array_key_exists("items", $_REQUEST)) {
-
- list($abs_href, $what) = use_optional_request_params("itemsHref", "itemsWhat", "items");
- $what = is_numeric($what) ? intval($what, 10) : 1;
- $response["items"] = $this->app->get_items($abs_href, $what);
- }
-
- if (count($_REQUEST)) {
- $response["unused"] = $_REQUEST;
- }
-
- json_exit($response);
- }
-
-
- else if ($action === "getThumbHref") {
-
- if (!$options["thumbnails"]["enabled"]) {
- json_fail(1, "thumbnails disabled");
- }
-
- normalized_require_once("/server/php/inc/Thumb.php");
- if (!Thumb::is_supported()) {
- json_fail(2, "thumbnails not supported");
- }
-
- list($type, $src_abs_href, $mode, $width, $height) = use_request_params(array("type", "href", "mode", "width", "height"));
-
- $thumb = new Thumb($this->app);
- $thumb_href = $thumb->thumb($type, $src_abs_href, $mode, $width, $height);
- if ($thumb_href === null) {
- json_fail(3, "thumbnail creation failed");
- }
-
- json_exit(array("absHref" => $thumb_href));
- }
-
-
- else if ($action === "download") {
-
- json_fail(1, "downloads disabled", !$options["download"]["enabled"]);
-
- list($as, $type, $hrefs) = use_request_params(array("as", "type", "hrefs"));
-
- normalized_require_once("/server/php/inc/Archive.php");
- $archive = new Archive($this->app);
-
- $hrefs = explode("|:|", trim($hrefs));
-
- set_time_limit(0);
- header("Content-Type: application/octet-stream");
- header("Content-Disposition: attachment; filename=\"$as\"");
- header("Connection: close");
- $rc = $archive->output($type, $hrefs);
-
- if ($rc !== 0) {
- json_fail("packaging failed");
- }
- exit;
- }
-
-
- else if ($action === "upload") {
-
- list($href) = use_request_params(array("href"));
-
- json_fail(1, "wrong HTTP method", strtolower($_SERVER["REQUEST_METHOD"]) !== "post");
- json_fail(2, "something went wrong", !array_key_exists("userfile", $_FILES));
-
- $userfile = $_FILES["userfile"];
-
- json_fail(3, "something went wrong [" . $userfile["error"] . "]", $userfile["error"] !== 0);
- json_fail(4, "folders not supported", file_get_contents($userfile["tmp_name"]) === "null");
-
- $upload_dir = $this->app->get_abs_path($href);
- $code = $this->app->get_http_code($href);
-
- json_fail(5, "upload dir no h5ai folder or ignored", $code !== App::$MAGIC_SEQUENCE || $this->app->is_ignored($upload_dir));
-
- $dest = $upload_dir . "/" . utf8_encode($userfile["name"]);
-
- json_fail(6, "already exists", file_exists($dest));
- json_fail(7, "can't move uploaded file", !move_uploaded_file($userfile["tmp_name"], $dest));
-
- json_exit();
- }
-
-
- else if ($action === "delete") {
-
- json_fail(1, "deletion disabled", !$options["delete"]["enabled"]);
-
- list($hrefs) = use_request_params(array("hrefs"));
-
- $hrefs = explode("|:|", trim($hrefs));
- $errors = array();
-
- foreach ($hrefs as $href) {
-
- $d = normalize_path(dirname($href), true);
- $n = basename($href);
-
- $code = $this->app->get_http_code($d);
-
- if ($code == App::$MAGIC_SEQUENCE && !$this->app->is_ignored($n)) {
-
- $abs_path = $this->app->get_abs_path($href);
-
- if (!unlink($abs_path)) {
- $errors[] = $href;
- }
- }
- }
-
- if (count($errors)) {
- json_fail(2, "deletion failed for some");
- } else {
- json_exit();
- }
- }
-
-
- else if ($action === "rename") {
-
- json_fail(1, "renaming disabled", !$options["rename"]["enabled"]);
-
- list($href, $name) = use_request_params(array("href", "name"));
-
- $d = normalize_path(dirname($href), true);
- $n = basename($href);
-
- $code = $this->app->get_http_code($d);
-
- if ($code == App::$MAGIC_SEQUENCE && !$this->app->is_ignored($n)) {
-
- $abs_path = $this->app->get_abs_path($href);
- $folder = normalize_path(dirname($abs_path));
-
- if (!rename($abs_path, $folder . "/" . $name)) {
- json_fail(2, "renaming failed");
- }
- }
-
- json_exit();
- }
-
- json_fail(100, "unsupported request");
- }
-}
-
-?>
\ No newline at end of file
diff --git a/src/_h5ai/server/php/inc/App.php b/src/_h5ai/server/php/inc/App.php
deleted file mode 100644
index a292d71d..00000000
--- a/src/_h5ai/server/php/inc/App.php
+++ /dev/null
@@ -1,389 +0,0 @@
-app_abs_path = normalize_path($app_abs_path);
- $this->root_abs_path = normalize_path(dirname($this->app_abs_path));
-
- $this->app_abs_href = normalize_path($app_abs_href, true);
- $this->root_abs_href = normalize_path(dirname($this->app_abs_href), true);
-
- $this->abs_href = normalize_path($abs_href, true);
- $this->abs_path = $this->get_abs_path($this->abs_href);
-
- $this->options = load_commented_json($this->app_abs_path . "/conf/options.json");
- }
-
-
- public function get_root_abs_path() {
-
- return $this->root_abs_path;
- }
-
-
- public function get_root_abs_href() {
-
- return $this->root_abs_href;
- }
-
-
- public function get_app_abs_href() {
-
- return $this->app_abs_href;
- }
-
-
- public function get_cache_abs_path() {
-
- return $this->app_abs_path . '/' . App::$CACHE_DIR;
- }
-
-
- public function get_cache_abs_href() {
-
- return $this->app_abs_href . App::$CACHE_DIR . '/';
- }
-
-
- public function get_abs_href($abs_path = null, $trailing_slash = true) {
-
- if ($abs_path === null) {
- return $this->abs_href;
- }
-
- $abs_path = substr($abs_path, strlen($this->root_abs_path));
-
- $parts = explode("/", $abs_path);
- $encoded_parts = array();
- foreach ($parts as $part) {
- if ($part) {
- $encoded_parts[] = rawurlencode($part);
- }
- }
-
- return normalize_path($this->root_abs_href . implode("/", $encoded_parts), $trailing_slash);
- }
-
-
- public function get_abs_path($abs_href = null) {
-
- if ($abs_href === null) {
- return $this->abs_path;
- }
-
- $abs_href = substr($abs_href, strlen($this->root_abs_href));
-
- return normalize_path($this->root_abs_path . "/" . rawurldecode($abs_href));
- }
-
-
- public function is_ignored($name) {
-
- // always ignore
- if ($name === "." || $name === "..") {
- return true;
- }
-
- foreach ($this->options["view"]["ignore"] as $re) {
- $re = App::$RE_DELIMITER . str_replace(App::$RE_DELIMITER, '\\' . App::$RE_DELIMITER, $re) . App::$RE_DELIMITER;
- if (preg_match($re, $name)) {
- return true;
- }
- }
-
- return false;
- }
-
-
- public function read_dir($path) {
-
- $content = array();
- if (is_dir($path)) {
- if ($dir = opendir($path)) {
- while (($file = readdir($dir)) !== false) {
- if (!$this->is_ignored($file) && !$this->is_ignored($this->get_abs_href($path) . $file)) {
- $content[] = $file;
- }
- }
- closedir($dir);
- }
- }
- return $content;
- }
-
-
- public function get_options() {
-
- return $this->options;
- }
-
-
- public function get_http_code($abs_href) {
-
- $abs_path = $this->get_abs_path($abs_href);
-
- if (!is_dir($abs_path) || strpos($abs_path, '../') || strpos($abs_path, '/..') || $abs_path == '..') {
- return 500;
- }
-
- foreach ($this->options["view"]["indexFiles"] as $if) {
- if (file_exists($abs_path . "/" . $if)) {
- return 200;
- }
- }
-
- $p = $abs_path;
- while ($p !== $this->root_abs_path) {
- if (@is_dir($p . "/_h5ai/server")) {
- return 200;
- }
- $pp = normalize_path(dirname($p));
- if ($pp === $p) {
- return 200;
- }
- $p = $pp;
- }
- return App::$MAGIC_SEQUENCE;
- }
-
-
- public function get_generic_json() {
-
- return json_encode(array("items" => $this->get_items($this->abs_href, 1))) . "\n";
- }
-
-
- public function get_items($abs_href, $what) {
-
- $code = $this->get_http_code($abs_href);
- if ($code != App::$MAGIC_SEQUENCE) {
- return array();
- }
-
- $cache = array();
- $folder = Item::get($this, $this->get_abs_path($abs_href), $cache);
-
- // add content of subfolders
- if ($what >= 2 && $folder !== null) {
- foreach ($folder->get_content($cache) as $item) {
- $item->get_content($cache);
- }
- $folder = $folder->get_parent($cache);
- }
-
- // add content of this folder and all parent folders
- while ($what >= 1 && $folder !== null) {
- $folder->get_content($cache);
- $folder = $folder->get_parent($cache);
- }
-
- uasort($cache, array("Item", "cmp"));
- $result = array();
- foreach ($cache as $p => $item) {
- $result[] = $item->to_json_object();
- }
-
- return $result;
- }
-
-
- public function get_fallback() {
-
- date_default_timezone_set("UTC");
-
- $cache = array();
- $folder = Item::get($this, $this->abs_path, $cache);
- $items = $folder->get_content($cache);
- uasort($items, array("Item", "cmp"));
-
- $html = "";
-
- $html .= "";
- $html .= " | ";
- $html .= "Name | ";
- $html .= "Last modified | ";
- $html .= "Size | ";
- $html .= "
";
-
- if ($folder->get_parent($cache)) {
- $html .= "";
- $html .= " | ";
- $html .= "Parent Directory | ";
- $html .= " | ";
- $html .= " | ";
- $html .= "
";
- }
-
- foreach ($items as $item) {
- $type = $item->is_folder ? "folder" : "default";
-
- $html .= "";
- $html .= " | ";
- $html .= "" . basename($item->abs_path) . " | ";
- $html .= "" . date("Y-m-d H:i", $item->date) . " | ";
- $html .= "" . ($item->size !== null ? intval($item->size / 1000) . " KB" : "" ) . " | ";
- $html .= "
";
- }
-
- $html .= "
";
-
- return $html;
- }
-
-
- public function get_types() {
-
- return load_commented_json($this->app_abs_path . "/conf/types.json");
- }
-
-
- public function get_l10n_list() {
-
- $langs = array();
- $l10nDir = $this->app_abs_path . "/conf/l10n";
- if (is_dir($l10nDir)) {
- if ($dir = opendir($l10nDir)) {
- while (($file = readdir($dir)) !== false) {
- if (ends_with($file, ".json")) {
- $translations = load_commented_json($l10nDir . "/" . $file);
- $langs[basename($file, ".json")] = $translations["lang"];
- }
- }
- closedir($dir);
- }
- }
- ksort($langs);
- return $langs;
- }
-
-
- public function get_l10n($iso_codes) {
-
- if (!is_array($iso_codes)) {
- $iso_codes = func_get_args();
- }
-
- $result = array();
- foreach ($iso_codes as $iso_code) {
- if ($iso_code !== "") {
- $file = $this->app_abs_path . "/conf/l10n/" . $iso_code . ".json";
- $result[$iso_code] = load_commented_json($file);
- $result[$iso_code]["isoCode"] = $iso_code;
- }
- }
-
- return $result;
- }
-
-
- public function get_server_checks() {
-
- $php = version_compare(PHP_VERSION, "5.2.1") >= 0;
- $gd = false;
- if (function_exists("gd_info")) {
- $gdinfo = gd_info();
- $gd = array_key_exists("JPG Support", $gdinfo) && $gdinfo["JPG Support"] || array_key_exists("JPEG Support", $gdinfo) && $gdinfo["JPEG Support"];
- }
- $exif = function_exists("exif_thumbnail");
- $cache = @is_writable($this->get_cache_abs_path());
- if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
- $tar = @preg_match("/tar(.exe)?$/i", `which tar`) > 0;
- $zip = @preg_match("/zip(.exe)?$/i", `which zip`) > 0;
- $convert = @preg_match("/convert(.exe)?$/i", `which convert`) > 0;
- $ffmpeg = @preg_match("/ffmpeg(.exe)?$/i", `which ffmpeg`) > 0;
- $du = @preg_match("/du(.exe)?$/i", `which du`) > 0;
- } else {
- $tar = @preg_match("/tar(.exe)?$/i", `command -v tar`) > 0;
- $zip = @preg_match("/zip(.exe)?$/i", `command -v zip`) > 0;
- $convert = @preg_match("/convert(.exe)?$/i", `command -v convert`) > 0;
- $ffmpeg = @preg_match("/ffmpeg(.exe)?$/i", `command -v ffmpeg`) > 0;
- $du = @preg_match("/du(.exe)?$/i", `command -v du`) > 0;
- }
-
- return array(
- "idx" => $this->app_abs_href . "server/php/index.php",
- "phpversion" => PHP_VERSION,
- "php" => $php,
- "cache" => $cache,
- "thumbs" => $gd,
- "exif" => $exif,
- "tar" => $tar,
- "zip" => $zip,
- "convert" => $convert,
- "ffmpeg" => $ffmpeg,
- "du" => $du
- );
- }
-
-
- public function get_server_details() {
-
- return array(
- "backend" => "php",
- "api" => true,
- "name" => strtolower(preg_replace("/\\/.*$/", "", getenv("SERVER_SOFTWARE"))),
- "version" => strtolower(preg_replace("/^.*\\//", "", preg_replace("/\\s.*$/", "", getenv("SERVER_SOFTWARE"))))
- );
- }
-
-
- public function get_customizations($abs_href) {
-
- if (!$this->options["custom"]["enabled"]) {
- return array(
- "header" => null,
- "footer" => null
- );
- }
-
- $abs_path = $this->get_abs_path($abs_href);
- $file = $abs_path . "/" . App::$FILE_PREFIX . ".header.html";
- $header = is_readable($file) ? file_get_contents($file) : null;
- $file = $abs_path . "/" . App::$FILE_PREFIX . ".footer.html";
- $footer = is_readable($file) ? file_get_contents($file) : null;
-
- $p = $abs_path;
- while ($header === null || $footer === null) {
-
- if ($header === null) {
- $file = $p . "/" . App::$FILE_PREFIX . ".headers.html";
- $header = is_readable($file) ? file_get_contents($file) : null;
- }
- if ($footer === null) {
- $file = $p . "/" . App::$FILE_PREFIX . ".footers.html";
- $footer = is_readable($file) ? file_get_contents($file) : null;
- }
-
- if ($p === $this->root_abs_path) {
- break;
- }
- $pp = normalize_path(dirname($p));
- if ($pp === $p) {
- break;
- }
- $p = $pp;
- }
-
- return array(
- "header" => $header,
- "footer" => $footer
- );
- }
-}
-
-?>
\ No newline at end of file
diff --git a/src/_h5ai/server/php/inc/Item.php b/src/_h5ai/server/php/inc/Item.php
deleted file mode 100644
index 2da5bffa..00000000
--- a/src/_h5ai/server/php/inc/Item.php
+++ /dev/null
@@ -1,118 +0,0 @@
-is_folder && !$item2->is_folder) {
- return -1;
- }
- if (!$item1->is_folder && $item2->is_folder) {
- return 1;
- }
-
- return strcasecmp($item1->abs_path, $item2->abs_path);
- }
-
- public static function get($app, $abs_path, &$cache) {
-
- if (!starts_with($abs_path, $app->get_root_abs_path())) {
- error_log("ILLEGAL REQUEST: " . $abs_path . ", " . $app->get_root_abs_path());
- return null;
- }
-
- if (is_array($cache) && array_key_exists($abs_path, $cache)) {
- return $cache[$abs_path];
- }
-
- $item = new Item($app, $abs_path);
-
- if (is_array($cache)) {
- $cache[$abs_path] = $item;
- }
- return $item;
- }
-
-
- public $app,
- $abs_path, $abs_href,
- $date, $size,
- $is_folder,
- $is_content_fetched;
-
-
- private function __construct($app, $abs_path) {
-
- $this->app = $app;
-
- $this->abs_path = normalize_path($abs_path);
- $this->is_folder = is_dir($this->abs_path);
- $this->abs_href = $this->app->get_abs_href($abs_path, $this->is_folder);
-
- $this->date = @filemtime($this->abs_path);
-
- if ($this->is_folder) {
- $this->size = null;
- $options = $app->get_options();
- if ($options["foldersize"]["enabled"]) {
- $cmd = str_replace("[DIR]", escapeshellarg($this->abs_path), Item::$FOLDER_SIZE_CMD);
- $this->size = intval(preg_replace("/\s.*$/", "", `$cmd`), 10) * 1024;
- }
- } else {
- $this->size = @filesize($this->abs_path);
- }
-
- $this->is_content_fetched = false;
- }
-
-
- public function to_json_object() {
-
- $obj = array(
- "absHref" => $this->abs_href,
- "time" => $this->date * 1000, // seconds (PHP) to milliseconds (JavaScript)
- "size" => $this->size
- );
-
- if ($this->is_folder) {
- $obj["status"] = $this->app->get_http_code($this->abs_href);
- $obj["content"] = $this->is_content_fetched;
- }
-
- return $obj;
- }
-
-
- public function get_parent(&$cache) {
-
- $parent_abs_path = normalize_path(dirname($this->abs_path));
- if ($parent_abs_path !== $this->abs_path && starts_with($parent_abs_path, $this->app->get_root_abs_path())) {
- return Item::get($this->app, $parent_abs_path, $cache);
- }
- return null;
- }
-
-
- public function get_content(&$cache) {
-
- $content = array();
-
- if ($this->app->get_http_code($this->abs_href) !== App::$MAGIC_SEQUENCE) {
- return $content;
- }
-
- $files = $this->app->read_dir($this->abs_path);
- foreach ($files as $file) {
- $item = Item::get($this->app, $this->abs_path . "/" . $file, $cache);
- $content[$item->abs_path] = $item;
- }
-
- $this->is_content_fetched = true;
-
- return $content;
- }
-}
-
-?>
\ No newline at end of file
diff --git a/src/_h5ai/server/php/inc/class-api.php b/src/_h5ai/server/php/inc/class-api.php
new file mode 100644
index 00000000..445ccbd3
--- /dev/null
+++ b/src/_h5ai/server/php/inc/class-api.php
@@ -0,0 +1,139 @@
+actions = array("get", "getThumbHref", "download", "upload", "delete", "rename");
+ $this->app = $app;
+ $this->options = $app->get_options();
+ }
+
+
+ public function apply() {
+
+ $action = use_request_param("action");
+ json_fail(100, "unsupported request", !in_array($action, $this->actions));
+
+ $methodname = "on_$action";
+ $this->$methodname();
+ }
+
+
+ private function on_get() {
+
+ $response = array();
+
+ if (has_request_param("setup")) {
+
+ use_request_param("setup");
+ $response["setup"] = $this->app->get_setup();
+ }
+
+ if (has_request_param("options")) {
+
+ use_request_param("options");
+ $response["options"] = $this->app->get_options();
+ }
+
+ if (has_request_param("types")) {
+
+ use_request_param("types");
+ $response["types"] = $this->app->get_types();
+ }
+
+ if (has_request_param("theme")) {
+
+ use_request_param("theme");
+ $response["theme"] = $this->app->get_theme();
+ }
+
+ if (has_request_param("langs")) {
+
+ use_request_param("langs");
+ $response["langs"] = $this->app->get_l10n_list();
+ }
+
+ if (has_request_param("l10n")) {
+
+ use_request_param("l10n");
+ $iso_codes = use_request_param("l10nCodes");
+ $iso_codes = explode(":", $iso_codes);
+ $response["l10n"] = $this->app->get_l10n($iso_codes);
+ }
+
+ if (has_request_param("custom")) {
+
+ use_request_param("custom");
+ $url = use_request_param("customHref");
+ $response["custom"] = $this->app->get_customizations($url);
+ }
+
+ if (has_request_param("items")) {
+
+ use_request_param("items");
+ $url = use_request_param("itemsHref");
+ $what = use_request_param("itemsWhat");
+ $what = is_numeric($what) ? intval($what, 10) : 1;
+ $response["items"] = $this->app->get_items($url, $what);
+ }
+
+ if (has_request_param("all_items")) {
+
+ use_request_param("all_items");
+ $response["all_items"] = $this->app->get_all_items();
+ }
+
+ if (count($_REQUEST)) {
+ $response["unused"] = $_REQUEST;
+ }
+
+ json_exit($response);
+ }
+
+
+ private function on_getThumbHref() {
+
+ json_fail(1, "thumbnails disabled", !$this->options["thumbnails"]["enabled"]);
+ json_fail(2, "thumbnails not supported", !HAS_PHP_JPG);
+
+ $type = use_request_param("type");
+ $src_url = use_request_param("href");
+ $mode = use_request_param("mode");
+ $width = use_request_param("width");
+ $height = use_request_param("height");
+
+ $thumb = new Thumb($this->app);
+ $thumb_url = $thumb->thumb($type, $src_url, $mode, $width, $height);
+ json_fail(3, "thumbnail creation failed", $thumb_url === null);
+
+ json_exit(array("absHref" => $thumb_url));
+ }
+
+
+ private function on_download() {
+
+ json_fail(1, "downloads disabled", !$this->options["download"]["enabled"]);
+
+ $as = use_request_param("as");
+ $type = use_request_param("type");
+ $hrefs = use_request_param("hrefs");
+
+ $archive = new Archive($this->app);
+
+ $hrefs = explode("|:|", trim($hrefs));
+
+ set_time_limit(0);
+ header("Content-Type: application/octet-stream");
+ header("Content-Disposition: attachment; filename=\"$as\"");
+ header("Connection: close");
+ $rc = $archive->output($type, $hrefs);
+
+ json_fail(2, "packaging failed", $rc !== 0);
+ exit;
+ }
+}
diff --git a/src/_h5ai/server/php/inc/class-app.php b/src/_h5ai/server/php/inc/class-app.php
new file mode 100644
index 00000000..fd16ede9
--- /dev/null
+++ b/src/_h5ai/server/php/inc/class-app.php
@@ -0,0 +1,388 @@
+options = load_commented_json(APP_PATH . "/conf/options.json");
+ }
+
+
+ public function get_options() {
+
+ return $this->options;
+ }
+
+
+ public function get_setup() {
+
+ $consts = get_defined_constants(true);
+ $setup = $consts["user"];
+ $setup["PHP_VERSION"] = PHP_VERSION;
+ unset($setup["APP_PATH"]);
+ unset($setup["ROOT_PATH"]);
+ unset($setup["CURRENT_PATH"]);
+ unset($setup["CACHE_PATH"]);
+ return $setup;
+ }
+
+
+ public function get_types() {
+
+ return load_commented_json(APP_PATH . "/conf/types.json");
+ }
+
+
+ public function get_theme() {
+
+ $theme = $this->options["view"]["theme"];
+ $theme_path = APP_PATH . "/client/themes/${theme}/icons";
+
+ $icons = array();
+
+ if (is_dir($theme_path)) {
+ if ($dir = opendir($theme_path)) {
+ while (($name = readdir($dir)) !== false) {
+ $path_parts = pathinfo($name);
+ if (in_array($path_parts["extension"], App::$ICON_EXTS)) {
+ $icons[$path_parts["filename"]] = "${theme}/icons/${name}";
+ }
+ }
+ closedir($dir);
+ }
+ }
+
+ return $icons;
+ }
+
+
+ public function to_url($path, $trailing_slash = true) {
+
+ $rel_path = substr($path, strlen(ROOT_PATH));
+ $parts = explode("/", $rel_path);
+ $encoded_parts = array();
+ foreach ($parts as $part) {
+ if ($part) {
+ $encoded_parts[] = rawurlencode($part);
+ }
+ }
+
+ return normalize_path(ROOT_HREF . implode("/", $encoded_parts), $trailing_slash);
+ }
+
+
+ public function to_path($url) {
+
+ $rel_url = substr($url, strlen(ROOT_HREF));
+ return normalize_path(ROOT_PATH . "/" . rawurldecode($rel_url));
+ }
+
+
+ public function is_hidden($name) {
+
+ // always hide
+ if ($name === "." || $name === "..") {
+ return true;
+ }
+
+ foreach ($this->options["view"]["hidden"] as $re) {
+ $re = App::$RE_DELIMITER . str_replace(App::$RE_DELIMITER, '\\' . App::$RE_DELIMITER, $re) . App::$RE_DELIMITER;
+ if (preg_match($re, $name)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ public function read_dir($path) {
+
+ $names = array();
+ if (is_dir($path)) {
+ if ($dir = opendir($path)) {
+ while (($name = readdir($dir)) !== false) {
+ if (
+ $this->is_hidden($name)
+ || $this->is_hidden($this->to_url($path) . $name)
+ || (!is_readable($path .'/'. $name) && $this->options["view"]["hideIf403"])
+ ) {
+ continue;
+ }
+ $names[] = $name;
+ }
+ closedir($dir);
+ }
+ }
+ return $names;
+ }
+
+
+ public function is_managed_url($url) {
+
+ return $this->is_managed_path($this->to_path($url));
+ }
+
+
+ public function is_managed_path($path) {
+
+ if (!is_dir($path) || strpos($path, '../') || strpos($path, '/..') || $path == '..') {
+ return false;
+ }
+
+ foreach ($this->options["view"]["unmanaged"] as $name) {
+ if (file_exists($path . "/" . $name)) {
+ return false;
+ }
+ }
+
+ while ($path !== ROOT_PATH) {
+ if (@is_dir($path . "/_h5ai/server")) {
+ return false;
+ }
+ $parent_path = normalize_path(dirname($path));
+ if ($parent_path === $path) {
+ return false;
+ }
+ $path = $parent_path;
+ }
+ return true;
+ }
+
+
+ public function get_items($url, $what) {
+
+ if (!$this->is_managed_url($url)) {
+ return array();
+ }
+
+ // return $this->get_all_items();
+ // return json_decode(file_get_contents(CACHE_PATH . "/item.json"));
+
+ $cache = array();
+ $folder = Item::get($this, $this->to_path($url), $cache);
+
+ // add content of subfolders
+ if ($what >= 2 && $folder !== null) {
+ foreach ($folder->get_content($cache) as $item) {
+ $item->get_content($cache);
+ }
+ $folder = $folder->get_parent($cache);
+ }
+
+ // add content of this folder and all parent folders
+ while ($what >= 1 && $folder !== null) {
+ $folder->get_content($cache);
+ $folder = $folder->get_parent($cache);
+ }
+
+ uasort($cache, array("Item", "cmp"));
+ $result = array();
+ foreach ($cache as $p => $item) {
+ $result[] = $item->to_json_object();
+ }
+
+ return $result;
+ }
+
+
+ private function get_all_item_content($item, &$cache) {
+
+ foreach ($item->get_content($cache) as $child) {
+ if ($child->is_folder) {
+ $this->get_all_item_content($child, $cache);
+ }
+ }
+ }
+
+
+ public function cummulate_folders($item, &$cache) {
+
+ if (!$item->is_folder) {
+ return;
+ }
+
+ $max_date = $item->date;
+ $sum_size = 0;
+ foreach ($item->get_content($cache) as $child) {
+ $this->cummulate_folders($child, $cache);
+ if ($child->date > $max_date) {
+ $max_date = $child->date;
+ }
+ $sum_size += $child->size;
+ }
+
+ $item->date = $max_date;
+ $item->size = $sum_size;
+ }
+
+
+ public function get_all_items() {
+
+ $cache = array();
+ $root = Item::get($this, ROOT_PATH, $cache);
+
+ $this->get_all_item_content($root, $cache);
+ $this->cummulate_folders($root, $cache);
+
+ uasort($cache, array("Item", "cmp"));
+ $result = array();
+ foreach ($cache as $p => $item) {
+ $result[] = $item->to_json_object();
+ }
+
+ @file_put_contents(CACHE_PATH . "/item.json", json_encode($result));
+ return $result;
+ }
+
+
+ public function get_fallback() {
+
+ $cache = array();
+ $folder = Item::get($this, CURRENT_PATH, $cache);
+ $items = $folder->get_content($cache);
+ uasort($items, array("Item", "cmp"));
+
+ $html = "";
+
+ $html .= "";
+ $html .= " | ";
+ $html .= "Name | ";
+ $html .= "Last modified | ";
+ $html .= "Size | ";
+ $html .= "
";
+
+ if ($folder->get_parent($cache)) {
+ $html .= "";
+ $html .= " | ";
+ $html .= "Parent Directory | ";
+ $html .= " | ";
+ $html .= " | ";
+ $html .= "
";
+ }
+
+ foreach ($items as $item) {
+ $type = $item->is_folder ? "folder" : "file";
+
+ $html .= "";
+ $html .= " | ";
+ $html .= "" . basename($item->path) . " | ";
+ $html .= "" . date("Y-m-d H:i", $item->date) . " | ";
+ $html .= "" . ($item->size !== null ? intval($item->size / 1000) . " KB" : "" ) . " | ";
+ $html .= "
";
+ }
+
+ $html .= "
";
+
+ return $html;
+ }
+
+
+ public function get_l10n_list() {
+
+ $langs = array();
+ $l10n_path = APP_PATH . "/conf/l10n";
+ if (is_dir($l10n_path)) {
+ if ($dir = opendir($l10n_path)) {
+ while (($file = readdir($dir)) !== false) {
+ if (ends_with($file, ".json")) {
+ $translations = load_commented_json($l10n_path . "/" . $file);
+ $langs[basename($file, ".json")] = $translations["lang"];
+ }
+ }
+ closedir($dir);
+ }
+ }
+ ksort($langs);
+ return $langs;
+ }
+
+
+ public function get_l10n($iso_codes) {
+
+ if (!is_array($iso_codes)) {
+ $iso_codes = func_get_args();
+ }
+
+ $results = array();
+ foreach ($iso_codes as $iso_code) {
+ if ($iso_code !== "") {
+ $file = APP_PATH . "/conf/l10n/" . $iso_code . ".json";
+ $results[$iso_code] = load_commented_json($file);
+ $results[$iso_code]["isoCode"] = $iso_code;
+ }
+ }
+
+ return $results;
+ }
+
+
+ private function read_custom_file($path, $name, &$content, &$type) {
+
+ foreach (APP::$CUSTOM_EXTS as $ext) {
+ $file = "$path/" . FILE_PREFIX . ".$name.$ext";
+ if (is_readable($file)) {
+ $content = file_get_contents($file);
+ $type = $ext;
+ return;
+ }
+ }
+ }
+
+
+ public function get_customizations($url) {
+
+ if (!$this->options["custom"]["enabled"]) {
+ return array(
+ "header" => null,
+ "header_type" => null,
+ "footer" => null,
+ "footer_type" => null
+ );
+ }
+
+ $path = $this->to_path($url);
+
+ $header = null;
+ $header_type = null;
+ $footer = null;
+ $footer_type = null;
+
+ $this->read_custom_file($path, "header", $header, $header_type);
+ $this->read_custom_file($path, "footer", $footer, $footer_type);
+
+ while ($header === null || $footer === null) {
+
+ if ($header === null) {
+ $this->read_custom_file($path, "headers", $header, $header_type);
+ }
+ if ($footer === null) {
+ $this->read_custom_file($path, "footers", $footer, $footer_type);
+ }
+
+ if ($path === ROOT_PATH) {
+ break;
+ }
+ $parent_path = normalize_path(dirname($path));
+ if ($parent_path === $path) {
+ break;
+ }
+ $path = $parent_path;
+ }
+
+ return array(
+ "header" => $header,
+ "header_type" => $header_type,
+ "footer" => $footer,
+ "footer_type" => $footer_type
+ );
+ }
+}
diff --git a/src/_h5ai/server/php/inc/Archive.php b/src/_h5ai/server/php/inc/class-archive.php
similarity index 87%
rename from src/_h5ai/server/php/inc/Archive.php
rename to src/_h5ai/server/php/inc/class-archive.php
index 92fd30f0..a78a107a 100644
--- a/src/_h5ai/server/php/inc/Archive.php
+++ b/src/_h5ai/server/php/inc/class-archive.php
@@ -15,15 +15,15 @@ class Archive {
}
- public function output($type, $hrefs) {
+ public function output($type, $urls) {
$this->dirs = array();
$this->files = array();
- $this->add_hrefs($hrefs);
+ $this->add_hrefs($urls);
if (count($this->dirs) === 0 && count($this->files) === 0) {
- return 500;
+ $this->add_dir(CURRENT_PATH, "/");
}
if ($type === "php-tar") {
@@ -44,11 +44,11 @@ class Archive {
private function shell_cmd($cmd) {
- $cmd = str_replace("[ROOTDIR]", escapeshellarg($this->app->get_abs_path()), $cmd);
+ $cmd = str_replace("[ROOTDIR]", escapeshellarg(CURRENT_PATH), $cmd);
$cmd = str_replace("[DIRS]", count($this->dirs) ? implode(" ", array_map("escapeshellarg", $this->dirs)) : "", $cmd);
$cmd = str_replace("[FILES]", count($this->files) ? implode(" ", array_map("escapeshellarg", $this->files)) : "", $cmd);
try {
- passthru($cmd);
+ passthru_cmd($cmd);
} catch (Exeption $err) {
return 500;
}
@@ -133,27 +133,29 @@ class Archive {
if ($fd = fopen($file, 'rb')) {
while (!feof($fd)) {
print fread($fd, Archive::$SEGMENT_SIZE);
- ob_flush();
- flush();
+ @ob_flush();
+ @flush();
}
fclose($fd);
}
}
- private function add_hrefs($hrefs) {
+ private function add_hrefs($urls) {
- foreach ($hrefs as $href) {
+ foreach ($urls as $href) {
+
+ if (trim($href) === "") {
+ continue;
+ }
$d = normalize_path(dirname($href), true);
$n = basename($href);
- $code = $this->app->get_http_code($d);
+ if ($this->app->is_managed_url($d) && !$this->app->is_hidden($n)) {
- if ($code == App::$MAGIC_SEQUENCE && !$this->app->is_ignored($n)) {
-
- $real_file = $this->app->get_abs_path($href);
- $archived_file = preg_replace("!^" . preg_quote(normalize_path($this->app->get_abs_path(), true)) . "!", "", $real_file);
+ $real_file = $this->app->to_path($href);
+ $archived_file = preg_replace("!^" . preg_quote(normalize_path(CURRENT_PATH, true)) . "!", "", $real_file);
if (is_dir($real_file)) {
$this->add_dir($real_file, $archived_file);
@@ -175,9 +177,7 @@ class Archive {
private function add_dir($real_dir, $archived_dir) {
- $code = $this->app->get_http_code($this->app->get_abs_href($real_dir));
-
- if ($code == App::$MAGIC_SEQUENCE) {
+ if ($this->app->is_managed_path($real_dir)) {
$this->dirs[] = $archived_dir;
$files = $this->app->read_dir($real_dir);
@@ -195,5 +195,3 @@ class Archive {
}
}
}
-
-?>
\ No newline at end of file
diff --git a/src/_h5ai/server/php/inc/class-item.php b/src/_h5ai/server/php/inc/class-item.php
new file mode 100644
index 00000000..33643b57
--- /dev/null
+++ b/src/_h5ai/server/php/inc/class-item.php
@@ -0,0 +1,154 @@
+is_folder && !$item2->is_folder) {
+ return -1;
+ }
+ if (!$item1->is_folder && $item2->is_folder) {
+ return 1;
+ }
+
+ return strcasecmp($item1->path, $item2->path);
+ }
+
+
+ private static $size_cache = array();
+
+
+ private static function filesize($app, $path) {
+
+ if (array_key_exists($path, Item::$size_cache)) {
+ return Item::$size_cache[$path];
+ }
+
+ $size = null;
+
+ if (is_file($path)) {
+
+ $size = @filesize($path);
+
+ } else if (is_dir($path)) {
+
+ $options = $app->get_options();
+ if ($options["foldersize"]["enabled"]) {
+ if (HAS_CMD_DU && $options["foldersize"]["type"] === "shell-du") {
+ $cmdv = array("du", "-sk", $path);
+ $size = intval(preg_replace("#\s.*$#", "", exec_cmdv($cmdv)), 10) * 1024;
+ } else {
+ $size = 0;
+ foreach ($app->read_dir($path) as $name) {
+ $size += Item::filesize($app, $path . "/" . $name);
+ }
+ }
+ }
+ }
+
+ Item::$size_cache[$path] = $size;
+ return $size;
+ }
+
+
+ public static function get($app, $path, &$cache) {
+
+ if (!starts_with($path, ROOT_PATH)) {
+ err_log("ILLEGAL REQUEST: " . $path . ", " . ROOT_PATH);
+ return null;
+ }
+
+ if (is_array($cache) && array_key_exists($path, $cache)) {
+ return $cache[$path];
+ }
+
+ $item = new Item($app, $path);
+
+ if (is_array($cache)) {
+ $cache[$path] = $item;
+ }
+ return $item;
+ }
+
+
+ public $app,
+ $path, $url,
+ $date, $size,
+ $is_folder,
+ $is_content_fetched;
+
+
+ private function __construct($app, $path) {
+
+ $this->app = $app;
+
+ $this->path = normalize_path($path, false);
+ $this->is_folder = is_dir($this->path);
+ $this->url = $app->to_url($this->path, $this->is_folder);
+ $this->date = @filemtime($this->path);
+ $this->size = Item::filesize($app, $this->path);
+ $this->is_content_fetched = false;
+
+ // $options = $app->get_options();
+ // if (!$this->is_folder && $options["hashes"]["enabled"]) {
+ if (!$this->is_folder) {
+ // $this->md5 = md5_file($this->path);
+ // $this->sha1 = sha1_file($this->path);
+ $this->md5 = null;
+ $this->sha1 = null;
+ } else {
+ $this->md5 = null;
+ $this->sha1 = null;
+ }
+ }
+
+
+ public function to_json_object() {
+
+ $obj = array(
+ "absHref" => $this->url,
+ "time" => $this->date * 1000, // seconds (PHP) to milliseconds (JavaScript)
+ "size" => $this->size
+ );
+
+ if ($this->is_folder) {
+ $obj["is_managed"] = $this->app->is_managed_url($this->url);
+ $obj["content"] = $this->is_content_fetched;
+ } else {
+ $obj["md5"] = $this->md5;
+ $obj["sha1"] = $this->sha1;
+ }
+
+ return $obj;
+ }
+
+
+ public function get_parent(&$cache) {
+
+ $parent_path = normalize_path(dirname($this->path), false);
+ if ($parent_path !== $this->path && starts_with($parent_path, ROOT_PATH)) {
+ return Item::get($this->app, $parent_path, $cache);
+ }
+ return null;
+ }
+
+
+ public function get_content(&$cache) {
+
+ $items = array();
+
+ if (!$this->app->is_managed_url($this->url)) {
+ return $items;
+ }
+
+ $files = $this->app->read_dir($this->path);
+ foreach ($files as $file) {
+ $item = Item::get($this->app, $this->path . "/" . $file, $cache);
+ $items[$item->path] = $item;
+ }
+
+ $this->is_content_fetched = true;
+
+ return $items;
+ }
+}
diff --git a/src/_h5ai/server/php/inc/Thumb.php b/src/_h5ai/server/php/inc/class-thumb.php
similarity index 67%
rename from src/_h5ai/server/php/inc/Thumb.php
rename to src/_h5ai/server/php/inc/class-thumb.php
index c4a878f3..17ce4412 100644
--- a/src/_h5ai/server/php/inc/Thumb.php
+++ b/src/_h5ai/server/php/inc/class-thumb.php
@@ -2,102 +2,104 @@
class Thumb {
- private static $FFMPEG_CMD = "ffmpeg -ss 0:01:00 -i [SOURCE] -an -vframes 1 [TARGET]";
- private static $CONVERT_CMD = "convert -strip [SOURCE][0] [TARGET]";
+ private static $FFMPEG_CMDV = array("ffmpeg", "-ss", "0:01:00", "-i", "[SRC]", "-an", "-vframes", "1", "[DEST]");
+ private static $AVCONV_CMDV = array("avconv", "-ss", "0:01:00", "-i", "[SRC]", "-an", "-vframes", "1", "[DEST]");
+ private static $CONVERT_CMDV = array("convert", "-strip", "[SRC][0]", "[DEST]");
private static $THUMB_CACHE = "thumbs";
- public static final function is_supported() {
- if (!function_exists("gd_info")) {
- return false;
- }
-
- $gdinfo = gd_info();
- return array_key_exists("JPG Support", $gdinfo) && $gdinfo["JPG Support"] || array_key_exists("JPEG Support", $gdinfo) && $gdinfo["JPEG Support"];
- }
-
-
- private $app;
+ private $app, $thumbs_path, $thumbs_href;
public function __construct($app) {
$this->app = $app;
- $this->thumbs_path = $this->app->get_cache_abs_path() . "/" . Thumb::$THUMB_CACHE;
- $this->thumbs_href = $this->app->get_cache_abs_href() . Thumb::$THUMB_CACHE;
- }
-
-
- public function thumb($type, $source_abs_href, $mode, $width, $height) {
-
- $source_abs_path = $this->app->get_abs_path($source_abs_href);
-
- if ($type === "img") {
- $capture_abs_path = $source_abs_path;
- } else if ($type === "mov") {
- $capture_abs_path = $this->capture(Thumb::$FFMPEG_CMD, $source_abs_path);
- } else if ($type === "doc") {
- $capture_abs_path = $this->capture(Thumb::$CONVERT_CMD, $source_abs_path);
- }
-
- return $this->thumb_href($capture_abs_path, $mode, $width, $height);
- }
-
-
- private function thumb_href($source_abs_path, $mode, $width, $height) {
-
- if (!file_exists($source_abs_path)) {
- return null;
- }
+ $this->thumbs_path = CACHE_PATH . "/" . Thumb::$THUMB_CACHE;
+ $this->thumbs_href = CACHE_HREF . Thumb::$THUMB_CACHE;
if (!is_dir($this->thumbs_path)) {
@mkdir($this->thumbs_path, 0755, true);
}
+ }
- $name = "thumb-" . sha1("$source_abs_path-$width-$height-$mode") . ".jpg";
- $thumb_abs_path = $this->thumbs_path . "/" . $name;
- $thumb_abs_href = $this->thumbs_href . "/" . $name;
- if (!file_exists($thumb_abs_path) || filemtime($source_abs_path) >= filemtime($thumb_abs_path)) {
+ public function thumb($type, $source_url, $mode, $width, $height) {
+
+ $source_path = $this->app->to_path($source_url);
+ if (!file_exists($source_path) || starts_with($source_path, CACHE_PATH)) {
+ return null;
+ }
+
+ if ($type === "img") {
+ $capture_path = $source_path;
+ } else if ($type === "mov") {
+ if (HAS_CMD_AVCONV) {
+ $capture_path = $this->capture(Thumb::$AVCONV_CMDV, $source_path);
+ } else if (HAS_CMD_FFMPEG) {
+ $capture_path = $this->capture(Thumb::$FFMPEG_CMDV, $source_path);
+ }
+ } else if ($type === "doc" && HAS_CMD_CONVERT) {
+ $capture_path = $this->capture(Thumb::$CONVERT_CMDV, $source_path);
+ }
+
+ return $this->thumb_href($capture_path, $mode, $width, $height);
+ }
+
+
+ private function thumb_href($source_path, $mode, $width, $height) {
+
+ if (!file_exists($source_path)) {
+ return null;
+ }
+
+ $name = "thumb-" . sha1("$source_path-$width-$height-$mode") . ".jpg";
+ $thumb_path = $this->thumbs_path . "/" . $name;
+ $thumb_url = $this->thumbs_href . "/" . $name;
+
+ if (!file_exists($thumb_path) || filemtime($source_path) >= filemtime($thumb_path)) {
$image = new Image();
$et = false;
$opts = $this->app->get_options();
- if ($opts["thumbnails"]["exif"] === true && function_exists("exif_thumbnail")) {
- $et = @exif_thumbnail($source_abs_path);
+ if (HAS_PHP_EXIF && $opts["thumbnails"]["exif"] === true) {
+ $et = @exif_thumbnail($source_path);
}
if($et !== false) {
- file_put_contents($thumb_abs_path, $et);
- $image->set_source($thumb_abs_path);
- $image->normalize_exif_orientation($source_abs_path);
+ file_put_contents($thumb_path, $et);
+ $image->set_source($thumb_path);
+ $image->normalize_exif_orientation($source_path);
} else {
- $image->set_source($source_abs_path);
+ $image->set_source($source_path);
}
$image->thumb($mode, $width, $height);
- $image->save_dest_jpeg($thumb_abs_path, 80);
+ $image->save_dest_jpeg($thumb_path, 80);
}
- return file_exists($thumb_abs_path) ? $thumb_abs_href : null;
+ return file_exists($thumb_path) ? $thumb_url : null;
}
- private function capture($cmd, $source_abs_path) {
+ private function capture($cmdv, $source_path) {
- if (!file_exists($source_abs_path)) {
+ if (!file_exists($source_path)) {
return null;
}
- $capture_abs_path = $this->app->get_cache_abs_path() . "/capture-" . sha1($source_abs_path) . ".jpg";
+ $capture_path = $this->thumbs_path . "/capture-" . sha1($source_path) . ".jpg";
- if (!file_exists($capture_abs_path) || filemtime($source_abs_path) >= filemtime($capture_abs_path)) {
- $cmd = str_replace("[SOURCE]", escapeshellarg($source_abs_path), $cmd);
- $cmd = str_replace("[TARGET]", escapeshellarg($capture_abs_path), $cmd);
- `$cmd`;
+ if (!file_exists($capture_path) || filemtime($source_path) >= filemtime($capture_path)) {
+
+ foreach ($cmdv as &$arg) {
+ $arg = str_replace("[SRC]", $source_path, $arg);
+ $arg = str_replace("[DEST]", $capture_path, $arg);
+ }
+
+ exec_cmdv($cmdv);
}
- return file_exists($capture_abs_path) ? $capture_abs_path : null;
+ return file_exists($capture_path) ? $capture_path : null;
}
}
@@ -107,17 +109,6 @@ class Image {
private $source_file, $source, $width, $height, $type, $dest;
- public static final function is_supported() {
-
- if (!function_exists("gd_info")) {
- return false;
- }
-
- $gdinfo = gd_info();
- return array_key_exists("JPG Support", $gdinfo) && $gdinfo["JPG Support"] || array_key_exists("JPEG Support", $gdinfo) && $gdinfo["JPEG Support"];
- }
-
-
public function __construct($filename = null) {
$this->source_file = null;
@@ -371,5 +362,3 @@ class Image {
}
}
}
-
-?>
\ No newline at end of file
diff --git a/src/_h5ai/server/php/inc/page.php.jade b/src/_h5ai/server/php/inc/page.php.jade
index f49aec7e..c5bc1b24 100644
--- a/src/_h5ai/server/php/inc/page.php.jade
+++ b/src/_h5ai/server/php/inc/page.php.jade
@@ -1,29 +1,24 @@
-- var href = ""
-- var fallback = ""
+- var app_href = "= APP_HREF ?>"
+- var fallback = "= FALLBACK ?>"
doctype 5
-//if lt IE 9
+//if lt IE 10
-//[if gt IE 8]>= 0);
+ define("HAS_PHP_EXIF", function_exists("exif_thumbnail"));
+ $has_php_jpg = false;
+ if (function_exists("gd_info")) {
+ $infos = gd_info();
+ $has_php_jpg = array_key_exists("JPG Support", $infos) && $infos["JPG Support"] || array_key_exists("JPEG Support", $infos) && $infos["JPEG Support"];
+ }
+ define("HAS_PHP_JPG", $has_php_jpg);
+
+
+ // SERVER
+ $server_name = null;
+ $server_version = null;
+ $server_software = getenv("SERVER_SOFTWARE");
+ if ($server_software && preg_match("#^(.*?)/(.*?)(?: |$)#", strtolower($server_software), $matches)) {
+ $server_name = $matches[1];
+ $server_version = $matches[2];
+ }
+ define("SERVER_NAME", $server_name);
+ define("SERVER_VERSION", $server_version);
+ define("HAS_WIN_OS", strtolower(substr(PHP_OS, 0, 3)) === "win");
+
+
+ // PATHS
+ $script_name = getenv("SCRIPT_NAME");
+ if (SERVER_NAME === "lighttpd") {
+ $script_name = preg_replace("#^.*?//#", "/", $script_name);
+ }
+ define("APP_HREF", normalize_path(dirname(dirname(dirname($script_name))), true));
+ define("APP_PATH", normalize_path(dirname(dirname(dirname(dirname(__FILE__)))), false));
+
+ define("ROOT_HREF", normalize_path(dirname(APP_HREF), true));
+ define("ROOT_PATH", normalize_path(dirname(APP_PATH), false));
+
+ $uri_parts = parse_url(getenv("REQUEST_URI"));
+ $current_href = normalize_path($uri_parts["path"], true);
+ $rel_href = substr($current_href, strlen(ROOT_HREF));
+ $current_path = normalize_path(ROOT_PATH . "/" . rawurldecode($rel_href));
+ if (!is_dir($current_path)) {
+ $current_href = normalize_path(dirname($current_href), true);
+ $current_path = normalize_path(dirname($current_path), false);
+ }
+ define("CURRENT_HREF", $current_href);
+ define("CURRENT_PATH", $current_path);
+
+ define("INDEX_HREF", normalize_path(APP_HREF . "server/php/index.php", false));
+
+ define("CACHE_HREF", normalize_path(APP_HREF . "cache", true));
+ define("CACHE_PATH", normalize_path(APP_PATH . "/cache", false));
+ define("HAS_WRITABLE_CACHE", @is_writable(CACHE_PATH));
+
+
+ // EXTERNAL COMMANDS
+ foreach (array("tar", "zip", "convert", "ffmpeg", "avconv", "du") as $cmd) {
+ $cmdv = HAS_WIN_OS ? array("which", $cmd) : array("command", "-v", $cmd);
+ define("HAS_CMD_" . strtoupper($cmd), @preg_match("#" . $cmd . "(.exe)?$#i", exec_cmdv($cmdv)) > 0);
+ }
+}
diff --git a/src/_h5ai/server/php/inc/util.php b/src/_h5ai/server/php/inc/util.php
index db5294dc..f3e040d4 100644
--- a/src/_h5ai/server/php/inc/util.php
+++ b/src/_h5ai/server/php/inc/util.php
@@ -1,5 +1,6 @@
\ No newline at end of file
+
+function passthru_cmd($cmd) {
+
+ $rc = null;
+ passthru($cmd, $rc);
+ return $rc;
+}
+
+
+function exec_cmdv($cmdv) {
+
+ if (!is_array($cmdv)) {
+ $cmdv = func_get_args();
+ }
+ $cmd = implode(" ", array_map("escapeshellarg", $cmdv));
+
+ $lines = array();
+ $rc = null;
+ exec($cmd, $lines, $rc);
+ return implode("\n", $lines);
+}
+
+
+function delete_path($path, $recursive = false) {
+
+ if (is_file($path)) {
+ return @unlink($path);
+ }
+
+ if (is_dir($path)) {
+ if ($recursive === true && $dir = opendir($path)) {
+ while (($name = readdir($dir)) !== false) {
+ delete_path($path . "/" . $name);
+ }
+ closedir($dir);
+ }
+
+ return @rmdir($path);
+ }
+
+ return false;
+}
+
+
+// debug tools
+
+function err_log($message, $obj = null) {
+
+ error_log($message . ": " . var_export($obj, true));
+}
+
+
+function scr_log($message, $obj = null) {
+
+ echo("" . $message . ": " . var_export($obj, true) . "
\n");
+}
+
+
+global $__TIMER_START, $__TIMER_PREV;
+$__TIMER_START = microtime(true);
+$__TIMER_PREV = $__TIMER_START;
+
+function time_log($message) {
+
+ global $__TIMER_START, $__TIMER_PREV;
+
+ $now = microtime(true);
+
+ if ($__TIMER_START === $__TIMER_PREV) {
+ error_log("------------------------------");
+ register_shutdown_function(function () { time_log('ex'); });
+ }
+
+ error_log($message . " DT " . number_format($now - $__TIMER_PREV, 5) . " TT " . number_format($now - $__TIMER_START, 5));
+
+ $__TIMER_PREV = $now;
+}
diff --git a/src/_h5ai/server/php/index.php b/src/_h5ai/server/php/index.php
index 967d49b1..3b4dcace 100644
--- a/src/_h5ai/server/php/index.php
+++ b/src/_h5ai/server/php/index.php
@@ -1,66 +1,36 @@
0, "version" => "{{pkg.version}}", "href" => APP_ABS_HREF));
- exit;
-}
-
-
-/* Load Libs */
-
-normalized_require_once("/server/php/inc/util.php");
-normalized_require_once("/server/php/inc/App.php");
-normalized_require_once("/server/php/inc/Item.php");
-
-
-/* Init */
-
-$app = new App(APP_ABS_PATH, APP_ABS_HREF, ABS_HREF);
-
-
-/* Run */
-
-if (array_key_exists("action", $_REQUEST)) {
+if (has_request_param("action")) {
header("Content-type: application/json;charset=utf-8");
-
- normalized_require_once("/server/php/inc/Api.php");
$api = new Api($app);
$api->apply();
} else {
header("Content-type: text/html;charset=utf-8");
-
- $HREF = $app->get_app_abs_href();
- $FALLBACK = $app->get_fallback();
-
- normalized_require_once("/server/php/inc/page.php");
+ define("FALLBACK", $app->get_fallback());
+ normalized_require_once("page");
}
-
-?>
\ No newline at end of file