| 'use strict'; | 
|   | 
| var has = Object.prototype.hasOwnProperty | 
|   , undef; | 
|   | 
| /** | 
|  * Decode a URI encoded string. | 
|  * | 
|  * @param {String} input The URI encoded string. | 
|  * @returns {String|Null} The decoded string. | 
|  * @api private | 
|  */ | 
| function decode(input) { | 
|   try { | 
|     return decodeURIComponent(input.replace(/\+/g, ' ')); | 
|   } catch (e) { | 
|     return null; | 
|   } | 
| } | 
|   | 
| /** | 
|  * Attempts to encode a given input. | 
|  * | 
|  * @param {String} input The string that needs to be encoded. | 
|  * @returns {String|Null} The encoded string. | 
|  * @api private | 
|  */ | 
| function encode(input) { | 
|   try { | 
|     return encodeURIComponent(input); | 
|   } catch (e) { | 
|     return null; | 
|   } | 
| } | 
|   | 
| /** | 
|  * Simple query string parser. | 
|  * | 
|  * @param {String} query The query string that needs to be parsed. | 
|  * @returns {Object} | 
|  * @api public | 
|  */ | 
| function querystring(query) { | 
|   var parser = /([^=?#&]+)=?([^&]*)/g | 
|     , result = {} | 
|     , part; | 
|   | 
|   while (part = parser.exec(query)) { | 
|     var key = decode(part[1]) | 
|       , value = decode(part[2]); | 
|   | 
|     // | 
|     // Prevent overriding of existing properties. This ensures that build-in | 
|     // methods like `toString` or __proto__ are not overriden by malicious | 
|     // querystrings. | 
|     // | 
|     // In the case if failed decoding, we want to omit the key/value pairs | 
|     // from the result. | 
|     // | 
|     if (key === null || value === null || key in result) continue; | 
|     result[key] = value; | 
|   } | 
|   | 
|   return result; | 
| } | 
|   | 
| /** | 
|  * Transform a query string to an object. | 
|  * | 
|  * @param {Object} obj Object that should be transformed. | 
|  * @param {String} prefix Optional prefix. | 
|  * @returns {String} | 
|  * @api public | 
|  */ | 
| function querystringify(obj, prefix) { | 
|   prefix = prefix || ''; | 
|   | 
|   var pairs = [] | 
|     , value | 
|     , key; | 
|   | 
|   // | 
|   // Optionally prefix with a '?' if needed | 
|   // | 
|   if ('string' !== typeof prefix) prefix = '?'; | 
|   | 
|   for (key in obj) { | 
|     if (has.call(obj, key)) { | 
|       value = obj[key]; | 
|   | 
|       // | 
|       // Edge cases where we actually want to encode the value to an empty | 
|       // string instead of the stringified value. | 
|       // | 
|       if (!value && (value === null || value === undef || isNaN(value))) { | 
|         value = ''; | 
|       } | 
|   | 
|       key = encode(key); | 
|       value = encode(value); | 
|   | 
|       // | 
|       // If we failed to encode the strings, we should bail out as we don't | 
|       // want to add invalid strings to the query. | 
|       // | 
|       if (key === null || value === null) continue; | 
|       pairs.push(key +'='+ value); | 
|     } | 
|   } | 
|   | 
|   return pairs.length ? prefix + pairs.join('&') : ''; | 
| } | 
|   | 
| // | 
| // Expose the module. | 
| // | 
| exports.stringify = querystringify; | 
| exports.parse = querystring; |