analytics.js
function multiple (fn) {
  return function (obj, path, val, options) {
    var normalize = options && isFunction(options.normalizer) ? options.normalizer : defaultNormalize;
    path = normalize(path);

    var key;
    var finished = false;

    while (!finished) loop();

    function loop() {
      for (key in obj) {
        var normalizedKey = normalize(key);
        if (0 === path.indexOf(normalizedKey)) {
          var temp = path.substr(normalizedKey.length);
          if (temp.charAt(0) === '.' || temp.length === 0) {
            path = temp.substr(1);
            var child = obj[key];

            // we're at the end and there is nothing.
            if (null == child) {
              finished = true;
              return;
            }

            // we're at the end and there is something.
            if (!path.length) {
              finished = true;
              return;
            }

            // step into child
            obj = child;

            // but we're done here
            return;
          }
        }
      }

      key = undefined;
      // if we found no matching properties
      // on the current object, there's no match.
      finished = true;
    }

    if (!key) return;
    if (null == obj) return obj;

    // the `obj` and `key` is one above the leaf object and key, so
    // start object: { a: { 'b.c': 10 } }
    // end object: { 'b.c': 10 }
    // end key: 'b.c'
    // this way, you can do `obj[key]` and get `10`.
    return fn(obj, key, val);
  };
}
function multiple (fn) {
  return function (obj, path, val, options) {
    var normalize = options && isFunction(options.normalizer) ? options.normalizer : defaultNormalize;
    path = normalize(path);

    var key;
    var finished = false;

    while (!finished) loop();

    function loop() {
      for (key in obj) {
        var normalizedKey = normalize(key);
        if (0 === path.indexOf(normalizedKey)) {
          var temp = path.substr(normalizedKey.length);
          if (temp.charAt(0) === '.' || temp.length === 0) {
            path = temp.substr(1);
            var child = obj[key];

            // we're at the end and there is nothing.
            if (null == child) {
              finished = true;
              return;
            }

            // we're at the end and there is something.
            if (!path.length) {
              finished = true;
              return;
            }

            // step into child
            obj = child;

            // but we're done here
            return;
          }
        }
      }

      key = undefined;
      // if we found no matching properties
      // on the current object, there's no match.
      finished = true;
    }

    if (!key) return;
    if (null == obj) return obj;

    // the `obj` and `key` is one above the leaf object and key, so
    // start object: { a: { 'b.c': 10 } }
    // end object: { 'b.c': 10 }
    // end key: 'b.c'
    // this way, you can do `obj[key]` and get `10`.
    return fn(obj, key, val);
  };
}
function multiple ( fn ) { return function ( obj , path , val , options ) { var normalize = options && isFunction ( options . normalizer ) ? options . normalizer : defaultNormalize ; path = normalize ( path ) ; var key ; var finished = false ; while ( ! finished ) loop ( ) ; function loop ( ) { for ( key in obj ) { var normalizedKey = normalize ( key ) ; if ( 0 === path . indexOf ( normalizedKey ) ) { var temp = path . substr ( normalizedKey . length ) ; if ( temp . charAt ( 0 ) === '.' || temp . length === 0 ) { path = temp . substr ( 1 ) ; var child = obj [ key ] ; // we're at the end and there is nothing. if ( null == child ) { finished = true ; return ; } // we're at the end and there is something. if ( ! path . length ) { finished = true ; return ; } // step into child obj = child ; // but we're done here return ; } } } key = undefined ; // if we found no matching properties // on the current object, there's no match. finished = true ; } if ( ! key ) return ; if ( null == obj ) return obj ; // the `obj` and `key` is one above the leaf object and key, so // start object: { a: { 'b.c': 10 } } // end object: { 'b.c': 10 } // end key: 'b.c' // this way, you can do `obj[key]` and get `10`. return fn ( obj , key , val ) ; } ; }
Compose applying the function to a nested key
Compose applying the function to a nested key