- return String(str)
- .split('&')
- .reduce(function(ret, pair){
- try{
- pair = decodeURIComponent(pair.replace(/\+/g, ' '));
- } catch(e) {
- // ignore
- }
-
- var eql = pair.indexOf('=')
- , brace = lastBraceInKey(pair)
- , key = pair.substr(0, brace || eql)
- , val = pair.substr(brace || eql, pair.length)
- , val = val.substr(val.indexOf('=') + 1, val.length)
- , parent = ret;
-
- // ?foo
- if ('' == key) key = pair, val = '';
-
- // nested
- if (~key.indexOf(']')) {
- var parts = key.split('[')
- , len = parts.length
- , last = len - 1;
-
- function parse(parts, parent, key) {
- var part = parts.shift();
-
- // end
- if (!part) {
- if (isArray(parent[key])) {
- parent[key].push(val);
- } else if ('object' == typeof parent[key]) {
- parent[key] = val;
- } else if ('undefined' == typeof parent[key]) {
- parent[key] = val;
- } else {
- parent[key] = [parent[key], val];
- }
- // array
- } else {
- obj = parent[key] = parent[key] || [];
- if (']' == part) {
- if (isArray(obj)) {
- if ('' != val) obj.push(val);
- } else if ('object' == typeof obj) {
- obj[objectKeys(obj).length] = val;
- } else {
- obj = parent[key] = [parent[key], val];
- }
- // prop
- } else if (~part.indexOf(']')) {
- part = part.substr(0, part.length - 1);
- if(notint.test(part) && isArray(obj)) obj = promote(parent, key);
- parse(parts, obj, part);
- // key
- } else {
- if(notint.test(part) && isArray(obj)) obj = promote(parent, key);
- parse(parts, obj, part);
- }
- }
- }
-
- parse(parts, parent, 'base');
- // optimize
- } else {
- if (notint.test(key) && isArray(parent.base)) {
- var t = {};
- for(var k in parent.base) t[k] = parent.base[k];
- parent.base = t;
- }
- set(parent.base, key, val);
- }
-
- return ret;
- }, {base: {}}).base;