+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure , options , originalOptions , dataType , tested ) {
+
+ dataType = dataType || options.dataTypes[0];
+ tested = tested || {};
+
+ if ( ! tested[ dataType ] ) {
+
+ tested[ dataType ] = true;
+
+ var list = structure[ dataType ],
+ i = 0,
+ length = list ? list.length : 0,
+ executeOnly = structure === prefilters,
+ selected;
+
+ for( ; ( executeOnly || ! selected ) && i < length ; i++ ) {
+ selected = list[ i ]( options , originalOptions );
+ // If we got redirected to a different dataType,
+ // we add it and switch to the corresponding list
+ if ( typeof( selected ) === "string" && selected !== dataType ) {
+ options.dataTypes.unshift( selected );
+ selected = inspectPrefiltersOrTransports(
+ structure , options , originalOptions , selected , tested );
+ // We always break in order not to continue
+ // to iterate in previous list
+ break;
+ }
+ }
+ // If we're only executing or nothing was selected
+ // we try the catchall dataType
+ if ( ! tested[ "*" ] && ( executeOnly || ! selected ) ) {
+ selected = inspectPrefiltersOrTransports(
+ structure , options , originalOptions , "*" , tested );
+ }
+ // This will be ignored by ajaxPrefilter
+ // so it's safe to return no matter what
+ return selected;
+ }
+}
+
+function addToPrefiltersOrTransports( structure , dataTypeExpression , functor ) {
+
+ var dataTypes = dataTypeExpression.split( rspacesAjax ),
+ i = 0,
+ length = dataTypes.length,
+ dataType,
+ list,
+ placeBefore;
+
+ // For each dataType in the dataTypeExpression
+ for( ; i < length ; i++ ) {
+ dataType = dataTypes[ i ];
+ // We control if we're asked to add before
+ // any existing element
+ placeBefore = /^\+/.test( dataType );
+ if ( placeBefore ) {
+ dataType = dataType.substr( 1 );
+ }
+ list = structure[ dataType ] = structure[ dataType ] || [];
+ // then we add to the structure accordingly
+ list[ placeBefore ? "unshift" : "push" ]( functor );
+ }
+}
+
+// Base function for both ajaxPrefilter and ajaxTransport
+function prefiltersOrTransports( structure , arg1 , arg2 , type /* internal */ ) {
+
+ type = jQuery.type( arg1 );
+
+ if ( type === "object" ) {
+ // We have an options map so we have to inspect the structure
+ return inspectPrefiltersOrTransports( structure , arg1 , arg2 );
+ } else {
+ // We're requested to add to the structure
+ // Signature is ( dataTypeExpression , function )
+ // with dataTypeExpression being optional and
+ // defaulting to auto ("*")
+ type = ( type === "function" );
+ if ( type ) {
+ arg2 = arg1;
+ arg1 = undefined;
+ }
+ // We control that the second argument is really a function
+ if ( type || jQuery.isFunction( arg2 ) ) {
+ addToPrefiltersOrTransports( structure , arg1 || "*" , arg2 );
+ }
+ }
+}
+
+// Handles responses to an ajax request:
+// - sets all responseXXX fields accordingly
+// - finds the right dataType (mediating between content-type and expecting dataType)
+// - returns the corresponding response
+function ajaxHandleResponses( s , jXHR , responses ) {
+
+ var contents = s.contents,
+ dataTypes = s.dataTypes,
+ responseFields = s.responseFields,
+ ct,
+ type,
+ finalDataType,
+ firstDataType;
+
+ // Fill responseXXX fields
+ for( type in responseFields ) {
+ if ( type in responses ) {
+ jXHR[ responseFields[ type ] ] = responses[ type ];
+ }
+ }
+
+ // Remove auto dataType and get content-type in the process
+ while( dataTypes[0] === "*" ) {
+ dataTypes.shift();
+ if ( ct === undefined ) {
+ ct = jXHR.getResponseHeader( "content-type" );
+ }
+ }
+
+ // 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;
+ }
+ }
+ }
+
+ // Check to see if we have a response for the expected dataType
+ if ( dataTypes[0] in responses ) {
+ finalDataType = dataTypes[0];
+ } 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 ];