function(s, o, g) {
        var i, k, x, reIgnoreStr, reIgnore;
        var optionKeys;
        var newOptionObj = {};
        var newIgnoredObj = {};
    
        o = _.clone(o);
        state.reset();
    
        if (o && o.scope) {
          JSHINT.scope = o.scope;
        } else {
          JSHINT.errors = [];
          JSHINT.undefs = [];
          JSHINT.internals = [];
          JSHINT.blacklist = {};
          JSHINT.scope = "(main)";
        }
    
        predefined = Object.create(null);
        combine(predefined, vars.ecmaIdentifiers[3]);
        combine(predefined, vars.reservedVars);
    
        combine(predefined, g || {});
    
        declared = Object.create(null);
        exported = Object.create(null);
    
        function each(obj, cb) {
          if (!obj)
            return;
    
          if (!Array.isArray(obj) && typeof obj === "object")
            obj = Object.keys(obj);
    
          obj.forEach(cb);
        }
    
        if (o) {
          each(o.predef || null, function(item) {
            var slice, prop;
    
            if (item[0] === "-") {
              slice = item.slice(1);
              JSHINT.blacklist[slice] = slice;
              // remove from predefined if there
              delete predefined[slice];
            } else {
              prop = Object.getOwnPropertyDescriptor(o.predef, item);
              predefined[item] = prop ? prop.value : false;
            }
          });
    
          each(o.exported || null, function(item) {
            exported[item] = true;
          });
    
          delete o.predef;
          delete o.exported;
    
          optionKeys = Object.keys(o);
          for (x = 0; x < optionKeys.length; x++) {
            if (/^-W\d{3}$/g.test(optionKeys[x])) {
              newIgnoredObj[optionKeys[x].slice(1)] = true;
            } else {
              var optionKey = optionKeys[x];
              newOptionObj[optionKey] = o[optionKey];
              if (optionKey === "es5") {
                if (o[optionKey]) {
                  warning("I003");
                }
              }
    
              if (optionKeys[x] === "newcap" && o[optionKey] === false)
                newOptionObj["(explicitNewcap)"] = true;
            }
          }
        }
    
        state.option = newOptionObj;
        state.ignored = newIgnoredObj;
    
        state.option.indent = state.option.indent || 4;
        state.option.maxerr = state.option.maxerr || 50;
    
        indent = 1;
        global = Object.create(predefined);
        scope = global;
    
        funct = functor("(global)", null, scope, {
          "(global)"    : true,
          "(blockscope)": blockScope(),
          "(comparray)" : arrayComprehension(),
          "(metrics)"   : createMetrics(state.tokens.next)
        });
    
        functions = [funct];
        urls = [];
        stack = null;
        member = {};
        membersOnly = null;
        implied = {};
        inblock = false;
        lookahead = [];
        unuseds = [];
    
        if (!isString(s) && !Array.isArray(s)) {
          errorAt("E004", 0);
          return false;
        }
    
        api = {
          get isJSON() {
            return state.jsonMode;
          },
    
          getOption: function(name) {
            return state.option[name] || null;
          },
    
          getCache: function(name) {
            return state.cache[name];
          },
    
          setCache: function(name, value) {
            state.cache[name] = value;
          },
    
          warn: function(code, data) {
            warningAt.apply(null, [ code, data.line, data.char ].concat(data.data));
          },
    
          on: function(names, listener) {
            names.split(" ").forEach(function(name) {
              emitter.on(name, listener);
            }.bind(this));
          }
        };
    
        emitter.removeAllListeners();
        (extraModules || []).forEach(function(func) {
          func(api);
        });
    
        state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"];
    
        if (o && o.ignoreDelimiters) {
    
          if (!Array.isArray(o.ignoreDelimiters)) {
            o.ignoreDelimiters = [o.ignoreDelimiters];
          }
    
          o.ignoreDelimiters.forEach(function(delimiterPair) {
            if (!delimiterPair.start || !delimiterPair.end)
                return;
    
            reIgnoreStr = escapeRegex(delimiterPair.start) +
                          "[\\s\\S]*?" +
                          escapeRegex(delimiterPair.end);
    
            reIgnore = new RegExp(reIgnoreStr, "ig");
    
            s = s.replace(reIgnore, function(match) {
              return match.replace(/./g, " ");
            });
          });
        }
    
        lex = new Lexer(s);
    
        lex.on("warning", function(ev) {
          warningAt.apply(null, [ ev.code, ev.line, ev.character].concat(ev.data));
        });
    
        lex.on("error", function(ev) {
          errorAt.apply(null, [ ev.code, ev.line, ev.character ].concat(ev.data));
        });
    
        lex.on("fatal", function(ev) {
          quit("E041", ev.line, ev.from);
        });
    
        lex.on("Identifier", function(ev) {
          emitter.emit("Identifier", ev);
        });
    
        lex.on("String", function(ev) {
          emitter.emit("String", ev);
        });
    
        lex.on("Number", function(ev) {
          emitter.emit("Number", ev);
        });
    
        lex.start();
    
        // Check options
        for (var name in o) {
          if (_.has(o, name)) {
            checkOption(name, state.tokens.curr);
          }
        }
    
        assume();
    
        // combine the passed globals after we've assumed all our options
        combine(predefined, g || {});
    
        //reset values
        comma.first = true;
    
        try {
          advance();
          switch (state.tokens.next.id) {
          case "{":
          case "[":
            destructuringAssignOrJsonValue();
            break;
          default:
            directives();
    
            if (state.isStrict()) {
              if (!state.option.globalstrict) {
                if (!(state.option.module || state.option.node || state.option.phantom ||
                  state.option.browserify)) {
                  warning("W097", state.tokens.prev);
                }
              }
            }
    
            statements();
          }
    
          if (state.tokens.next.id !== "(end)") {
            quit("E041", state.tokens.curr.line);
          }
    
          funct["(blockscope)"].unstack();
    
          var markDefined = function(name, context) {
            do {
              if (typeof context[name] === "string") {
                // JSHINT marks unused variables as 'unused' and
                // unused function declaration as 'unction'. This
                // code changes such instances back 'var' and
                // 'closure' so that the code in JSHINT.data()
                // doesn't think they're unused.
    
                if (context[name] === "unused")
                  context[name] = "var";
                else if (context[name] === "unction")
                  context[name] = "closure";
    
                return true;
              }
    
              context = context["(context)"];
            } while (context);
    
            return false;
          };
    
          var clearImplied = function(name, line) {
            if (!implied[name])
              return;
    
            var newImplied = [];
            for (var i = 0; i < implied[name].length; i += 1) {
              if (implied[name][i] !== line)
                newImplied.push(implied[name][i]);
            }
    
            if (newImplied.length === 0)
              delete implied[name];
            else
              implied[name] = newImplied;
          };
    
          var checkUnused = function(func, key) {
            var type = func[key];
            var tkn = func["(tokens)"][key];
    
            if (key.charAt(0) === "(")
              return;
    
            if (type !== "unused" && type !== "unction")
              return;
    
            // Params are checked separately from other variables.
            if (func["(params)"] && func["(params)"].indexOf(key) !== -1)
              return;
    
            // Variable is in global scope and defined as exported.
            if (func["(global)"] && _.has(exported, key))
              return;
    
            warnUnused(key, tkn, "var");
          };
    
          // Check queued 'x is not defined' instances to see if they're still undefined.
          for (i = 0; i < JSHINT.undefs.length; i += 1) {
            k = JSHINT.undefs[i].slice(0);
    
            if (markDefined(k[2].value, k[0]) || k[2].forgiveUndef) {
              clearImplied(k[2].value, k[2].line);
            } else if (state.option.undef) {
              warning.apply(warning, k.slice(1));
            }
          }
    
          functions.forEach(function(func) {
            if (func["(unusedOption)"] === false) {
              return;
            }
    
            for (var key in func) {
              if (_.has(func, key)) {
                checkUnused(func, key);
              }
            }
    
            if (!func["(params)"])
              return;
    
            var params = func["(params)"].slice();
            var param  = params.pop();
            var type, unused_opt;
    
            while (param) {
              type = func[param];
              unused_opt = func["(unusedOption)"] || state.option.unused;
              unused_opt = unused_opt === true ? "last-param" : unused_opt;
    
              // 'undefined' is a special case for (function(window, undefined) { ... })();
              // patterns.
    
              if (param === "undefined")
                return;
    
              if (type === "unused" || type === "unction") {
                warnUnused(param, func["(tokens)"][param], "param", func["(unusedOption)"]);
              } else if (unused_opt === "last-param") {
                return;
              }
    
              param = params.pop();
            }
          });
    
          for (var key in declared) {
            if (_.has(declared, key) && !_.has(global, key) && !_.has(exported, key)) {
              warnUnused(key, declared[key], "var");
            }
          }
    
        } catch (err) {
          if (err && err.name === "JSHintError") {
            var nt = state.tokens.next || {};
            JSHINT.errors.push({
              scope     : "(main)",
              raw       : err.raw,
              code      : err.code,
              reason    : err.message,
              line      : err.line || nt.line,
              character : err.character || nt.from
            }, null);
          } else {
            throw err;
          }
        }
    
        // Loop over the listed "internals", and check them as well.
    
        if (JSHINT.scope === "(main)") {
          o = o || {};
    
          for (i = 0; i < JSHINT.internals.length; i += 1) {
            k = JSHINT.internals[i];
            o.scope = k.elem;
            itself(k.value, o, g);
          }
        }
    
        return JSHINT.errors.length === 0;
      }
function(s, o, g) {
        var i, k, x, reIgnoreStr, reIgnore;
        var optionKeys;
        var newOptionObj = {};
        var newIgnoredObj = {};
    
        o = _.clone(o);
        state.reset();
    
        if (o && o.scope) {
          JSHINT.scope = o.scope;
        } else {
          JSHINT.errors = [];
          JSHINT.undefs = [];
          JSHINT.internals = [];
          JSHINT.blacklist = {};
          JSHINT.scope = "(main)";
        }
    
        predefined = Object.create(null);
        combine(predefined, vars.ecmaIdentifiers[3]);
        combine(predefined, vars.reservedVars);
    
        combine(predefined, g || {});
    
        declared = Object.create(null);
        exported = Object.create(null);
    
        function each(obj, cb) {
          if (!obj)
            return;
    
          if (!Array.isArray(obj) && typeof obj === "object")
            obj = Object.keys(obj);
    
          obj.forEach(cb);
        }
    
        if (o) {
          each(o.predef || null, function(item) {
            var slice, prop;
    
            if (item[0] === "-") {
              slice = item.slice(1);
              JSHINT.blacklist[slice] = slice;
              
              delete predefined[slice];
            } else {
              prop = Object.getOwnPropertyDescriptor(o.predef, item);
              predefined[item] = prop ? prop.value : false;
            }
          });
    
          each(o.exported || null, function(item) {
            exported[item] = true;
          });
    
          delete o.predef;
          delete o.exported;
    
          optionKeys = Object.keys(o);
          for (x = 0; x < optionKeys.length; x++) {
            if (/^-W\d{3}$/g.test(optionKeys[x])) {
              newIgnoredObj[optionKeys[x].slice(1)] = true;
            } else {
              var optionKey = optionKeys[x];
              newOptionObj[optionKey] = o[optionKey];
              if (optionKey === "es5") {
                if (o[optionKey]) {
                  warning("I003");
                }
              }
    
              if (optionKeys[x] === "newcap" && o[optionKey] === false)
                newOptionObj["(explicitNewcap)"] = true;
            }
          }
        }
    
        state.option = newOptionObj;
        state.ignored = newIgnoredObj;
    
        state.option.indent = state.option.indent || 4;
        state.option.maxerr = state.option.maxerr || 50;
    
        indent = 1;
        global = Object.create(predefined);
        scope = global;
    
        funct = functor("(global)", null, scope, {
          "(global)"    : true,
          "(blockscope)": blockScope(),
          "(comparray)" : arrayComprehension(),
          "(metrics)"   : createMetrics(state.tokens.next)
        });
    
        functions = [funct];
        urls = [];
        stack = null;
        member = {};
        membersOnly = null;
        implied = {};
        inblock = false;
        lookahead = [];
        unuseds = [];
    
        if (!isString(s) && !Array.isArray(s)) {
          errorAt("E004", 0);
          return false;
        }
    
        api = {
          get isJSON() {
            return state.jsonMode;
          },
    
          getOption: function(name) {
            return state.option[name] || null;
          },
    
          getCache: function(name) {
            return state.cache[name];
          },
    
          setCache: function(name, value) {
            state.cache[name] = value;
          },
    
          warn: function(code, data) {
            warningAt.apply(null, [ code, data.line, data.char ].concat(data.data));
          },
    
          on: function(names, listener) {
            names.split(" ").forEach(function(name) {
              emitter.on(name, listener);
            }.bind(this));
          }
        };
    
        emitter.removeAllListeners();
        (extraModules || []).forEach(function(func) {
          func(api);
        });
    
        state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"];
    
        if (o && o.ignoreDelimiters) {
    
          if (!Array.isArray(o.ignoreDelimiters)) {
            o.ignoreDelimiters = [o.ignoreDelimiters];
          }
    
          o.ignoreDelimiters.forEach(function(delimiterPair) {
            if (!delimiterPair.start || !delimiterPair.end)
                return;
    
            reIgnoreStr = escapeRegex(delimiterPair.start) +
                          "[\\s\\S]*?" +
                          escapeRegex(delimiterPair.end);
    
            reIgnore = new RegExp(reIgnoreStr, "ig");
    
            s = s.replace(reIgnore, function(match) {
              return match.replace(/./g, " ");
            });
          });
        }
    
        lex = new Lexer(s);
    
        lex.on("warning", function(ev) {
          warningAt.apply(null, [ ev.code, ev.line, ev.character].concat(ev.data));
        });
    
        lex.on("error", function(ev) {
          errorAt.apply(null, [ ev.code, ev.line, ev.character ].concat(ev.data));
        });
    
        lex.on("fatal", function(ev) {
          quit("E041", ev.line, ev.from);
        });
    
        lex.on("Identifier", function(ev) {
          emitter.emit("Identifier", ev);
        });
    
        lex.on("String", function(ev) {
          emitter.emit("String", ev);
        });
    
        lex.on("Number", function(ev) {
          emitter.emit("Number", ev);
        });
    
        lex.start();
    
        
        for (var name in o) {
          if (_.has(o, name)) {
            checkOption(name, state.tokens.curr);
          }
        }
    
        assume();
    
        
        combine(predefined, g || {});
    
        
        comma.first = true;
    
        try {
          advance();
          switch (state.tokens.next.id) {
          case "{":
          case "[":
            destructuringAssignOrJsonValue();
            break;
          default:
            directives();
    
            if (state.isStrict()) {
              if (!state.option.globalstrict) {
                if (!(state.option.module || state.option.node || state.option.phantom ||
                  state.option.browserify)) {
                  warning("W097", state.tokens.prev);
                }
              }
            }
    
            statements();
          }
    
          if (state.tokens.next.id !== "(end)") {
            quit("E041", state.tokens.curr.line);
          }
    
          funct["(blockscope)"].unstack();
    
          var markDefined = function(name, context) {
            do {
              if (typeof context[name] === "string") {
                
                
                
                
                
    
                if (context[name] === "unused")
                  context[name] = "var";
                else if (context[name] === "unction")
                  context[name] = "closure";
    
                return true;
              }
    
              context = context["(context)"];
            } while (context);
    
            return false;
          };
    
          var clearImplied = function(name, line) {
            if (!implied[name])
              return;
    
            var newImplied = [];
            for (var i = 0; i < implied[name].length; i += 1) {
              if (implied[name][i] !== line)
                newImplied.push(implied[name][i]);
            }
    
            if (newImplied.length === 0)
              delete implied[name];
            else
              implied[name] = newImplied;
          };
    
          var checkUnused = function(func, key) {
            var type = func[key];
            var tkn = func["(tokens)"][key];
    
            if (key.charAt(0) === "(")
              return;
    
            if (type !== "unused" && type !== "unction")
              return;
    
            
            if (func["(params)"] && func["(params)"].indexOf(key) !== -1)
              return;
    
            
            if (func["(global)"] && _.has(exported, key))
              return;
    
            warnUnused(key, tkn, "var");
          };
    
          
          for (i = 0; i < JSHINT.undefs.length; i += 1) {
            k = JSHINT.undefs[i].slice(0);
    
            if (markDefined(k[2].value, k[0]) || k[2].forgiveUndef) {
              clearImplied(k[2].value, k[2].line);
            } else if (state.option.undef) {
              warning.apply(warning, k.slice(1));
            }
          }
    
          functions.forEach(function(func) {
            if (func["(unusedOption)"] === false) {
              return;
            }
    
            for (var key in func) {
              if (_.has(func, key)) {
                checkUnused(func, key);
              }
            }
    
            if (!func["(params)"])
              return;
    
            var params = func["(params)"].slice();
            var param  = params.pop();
            var type, unused_opt;
    
            while (param) {
              type = func[param];
              unused_opt = func["(unusedOption)"] || state.option.unused;
              unused_opt = unused_opt === true ? "last-param" : unused_opt;
    
              
              
    
              if (param === "undefined")
                return;
    
              if (type === "unused" || type === "unction") {
                warnUnused(param, func["(tokens)"][param], "param", func["(unusedOption)"]);
              } else if (unused_opt === "last-param") {
                return;
              }
    
              param = params.pop();
            }
          });
    
          for (var key in declared) {
            if (_.has(declared, key) && !_.has(global, key) && !_.has(exported, key)) {
              warnUnused(key, declared[key], "var");
            }
          }
    
        } catch (err) {
          if (err && err.name === "JSHintError") {
            var nt = state.tokens.next || {};
            JSHINT.errors.push({
              scope     : "(main)",
              raw       : err.raw,
              code      : err.code,
              reason    : err.message,
              line      : err.line || nt.line,
              character : err.character || nt.from
            }, null);
          } else {
            throw err;
          }
        }
    
        
    
        if (JSHINT.scope === "(main)") {
          o = o || {};
    
          for (i = 0; i < JSHINT.internals.length; i += 1) {
            k = JSHINT.internals[i];
            o.scope = k.elem;
            itself(k.value, o, g);
          }
        }
    
        return JSHINT.errors.length === 0;
      }
function ( s , o , g ) { var i , k , x , reIgnoreStr , reIgnore ; var optionKeys ; var newOptionObj = { } ; var newIgnoredObj = { } ; o = _ . clone ( o ) ; state . reset ( ) ; if ( o && o . scope ) { JSHINT . scope = o . scope ; } else { JSHINT . errors = [ ] ; JSHINT . undefs = [ ] ; JSHINT . internals = [ ] ; JSHINT . blacklist = { } ; JSHINT . scope = "(main)" ; } predefined = Object . create ( null ) ; combine ( predefined , vars . ecmaIdentifiers [ 3 ] ) ; combine ( predefined , vars . reservedVars ) ; combine ( predefined , g || { } ) ; declared = Object . create ( null ) ; exported = Object . create ( null ) ; function each ( obj , cb ) { if ( ! obj ) return ; if ( ! Array . isArray ( obj ) && typeof obj === "object" ) obj = Object . keys ( obj ) ; obj . forEach ( cb ) ; } if ( o ) { each ( o . predef || null , function ( item ) { var slice , prop ; if ( item [ 0 ] === "-" ) { slice = item . slice ( 1 ) ; JSHINT . blacklist [ slice ] = slice ; // remove from predefined if there delete predefined [ slice ] ; } else { prop = Object . getOwnPropertyDescriptor ( o . predef , item ) ; predefined [ item ] = prop ? prop . value : false ; } } ) ; each ( o . exported || null , function ( item ) { exported [ item ] = true ; } ) ; delete o . predef ; delete o . exported ; optionKeys = Object . keys ( o ) ; for ( x = 0 ; x < optionKeys . length ; x ++ ) { if ( / ^-W\d{3}$ / g . test ( optionKeys [ x ] ) ) { newIgnoredObj [ optionKeys [ x ] . slice ( 1 ) ] = true ; } else { var optionKey = optionKeys [ x ] ; newOptionObj [ optionKey ] = o [ optionKey ] ; if ( optionKey === "es5" ) { if ( o [ optionKey ] ) { warning ( "I003" ) ; } } if ( optionKeys [ x ] === "newcap" && o [ optionKey ] === false ) newOptionObj [ "(explicitNewcap)" ] = true ; } } } state . option = newOptionObj ; state . ignored = newIgnoredObj ; state . option . indent = state . option . indent || 4 ; state . option . maxerr = state . option . maxerr || 50 ; indent = 1 ; global = Object . create ( predefined ) ; scope = global ; funct = functor ( "(global)" , null , scope , { "(global)" : true , "(blockscope)" : blockScope ( ) , "(comparray)" : arrayComprehension ( ) , "(metrics)" : createMetrics ( state . tokens . next ) } ) ; functions = [ funct ] ; urls = [ ] ; stack = null ; member = { } ; membersOnly = null ; implied = { } ; inblock = false ; lookahead = [ ] ; unuseds = [ ] ; if ( ! isString ( s ) && ! Array . isArray ( s ) ) { errorAt ( "E004" , 0 ) ; return false ; } api = { get isJSON ( ) { return state . jsonMode ; } , getOption : function ( name ) { return state . option [ name ] || null ; } , getCache : function ( name ) { return state . cache [ name ] ; } , setCache : function ( name , value ) { state . cache [ name ] = value ; } , warn : function ( code , data ) { warningAt . apply ( null , [ code , data . line , data . char ] . concat ( data . data ) ) ; } , on : function ( names , listener ) { names . split ( " " ) . forEach ( function ( name ) { emitter . on ( name , listener ) ; } . bind ( this ) ) ; } } ; emitter . removeAllListeners ( ) ; ( extraModules || [ ] ) . forEach ( function ( func ) { func ( api ) ; } ) ; state . tokens . prev = state . tokens . curr = state . tokens . next = state . syntax [ "(begin)" ] ; if ( o && o . ignoreDelimiters ) { if ( ! Array . isArray ( o . ignoreDelimiters ) ) { o . ignoreDelimiters = [ o . ignoreDelimiters ] ; } o . ignoreDelimiters . forEach ( function ( delimiterPair ) { if ( ! delimiterPair . start || ! delimiterPair . end ) return ; reIgnoreStr = escapeRegex ( delimiterPair . start ) + "[\\s\\S]*?" + escapeRegex ( delimiterPair . end ) ; reIgnore = new RegExp ( reIgnoreStr , "ig" ) ; s = s . replace ( reIgnore , function ( match ) { return match . replace ( / . / g , " " ) ; } ) ; } ) ; } lex = new Lexer ( s ) ; lex . on ( "warning" , function ( ev ) { warningAt . apply ( null , [ ev . code , ev . line , ev . character ] . concat ( ev . data ) ) ; } ) ; lex . on ( "error" , function ( ev ) { errorAt . apply ( null , [ ev . code , ev . line , ev . character ] . concat ( ev . data ) ) ; } ) ; lex . on ( "fatal" , function ( ev ) { quit ( "E041" , ev . line , ev . from ) ; } ) ; lex . on ( "Identifier" , function ( ev ) { emitter . emit ( "Identifier" , ev ) ; } ) ; lex . on ( "String" , function ( ev ) { emitter . emit ( "String" , ev ) ; } ) ; lex . on ( "Number" , function ( ev ) { emitter . emit ( "Number" , ev ) ; } ) ; lex . start ( ) ; // Check options for ( var name in o ) { if ( _ . has ( o , name ) ) { checkOption ( name , state . tokens . curr ) ; } } assume ( ) ; // combine the passed globals after we've assumed all our options combine ( predefined , g || { } ) ; //reset values comma . first = true ; try { advance ( ) ; switch ( state . tokens . next . id ) { case "{" : case "[" : destructuringAssignOrJsonValue ( ) ; break ; default : directives ( ) ; if ( state . isStrict ( ) ) { if ( ! state . option . globalstrict ) { if ( ! ( state . option . module || state . option . node || state . option . phantom || state . option . browserify ) ) { warning ( "W097" , state . tokens . prev ) ; } } } statements ( ) ; } if ( state . tokens . next . id !== "(end)" ) { quit ( "E041" , state . tokens . curr . line ) ; } funct [ "(blockscope)" ] . unstack ( ) ; var markDefined = function ( name , context ) { do { if ( typeof context [ name ] === "string" ) { // JSHINT marks unused variables as 'unused' and // unused function declaration as 'unction'. This // code changes such instances back 'var' and // 'closure' so that the code in JSHINT.data() // doesn't think they're unused. if ( context [ name ] === "unused" ) context [ name ] = "var" ; else if ( context [ name ] === "unction" ) context [ name ] = "closure" ; return true ; } context = context [ "(context)" ] ; } while ( context ) ; return false ; } ; var clearImplied = function ( name , line ) { if ( ! implied [ name ] ) return ; var newImplied = [ ] ; for ( var i = 0 ; i < implied [ name ] . length ; i += 1 ) { if ( implied [ name ] [ i ] !== line ) newImplied . push ( implied [ name ] [ i ] ) ; } if ( newImplied . length === 0 ) delete implied [ name ] ; else implied [ name ] = newImplied ; } ; var checkUnused = function ( func , key ) { var type = func [ key ] ; var tkn = func [ "(tokens)" ] [ key ] ; if ( key . charAt ( 0 ) === "(" ) return ; if ( type !== "unused" && type !== "unction" ) return ; // Params are checked separately from other variables. if ( func [ "(params)" ] && func [ "(params)" ] . indexOf ( key ) !== - 1 ) return ; // Variable is in global scope and defined as exported. if ( func [ "(global)" ] && _ . has ( exported , key ) ) return ; warnUnused ( key , tkn , "var" ) ; } ; // Check queued 'x is not defined' instances to see if they're still undefined. for ( i = 0 ; i < JSHINT . undefs . length ; i += 1 ) { k = JSHINT . undefs [ i ] . slice ( 0 ) ; if ( markDefined ( k [ 2 ] . value , k [ 0 ] ) || k [ 2 ] . forgiveUndef ) { clearImplied ( k [ 2 ] . value , k [ 2 ] . line ) ; } else if ( state . option . undef ) { warning . apply ( warning , k . slice ( 1 ) ) ; } } functions . forEach ( function ( func ) { if ( func [ "(unusedOption)" ] === false ) { return ; } for ( var key in func ) { if ( _ . has ( func , key ) ) { checkUnused ( func , key ) ; } } if ( ! func [ "(params)" ] ) return ; var params = func [ "(params)" ] . slice ( ) ; var param = params . pop ( ) ; var type , unused_opt ; while ( param ) { type = func [ param ] ; unused_opt = func [ "(unusedOption)" ] || state . option . unused ; unused_opt = unused_opt === true ? "last-param" : unused_opt ; // 'undefined' is a special case for (function(window, undefined) { ... })(); // patterns. if ( param === "undefined" ) return ; if ( type === "unused" || type === "unction" ) { warnUnused ( param , func [ "(tokens)" ] [ param ] , "param" , func [ "(unusedOption)" ] ) ; } else if ( unused_opt === "last-param" ) { return ; } param = params . pop ( ) ; } } ) ; for ( var key in declared ) { if ( _ . has ( declared , key ) && ! _ . has ( global , key ) && ! _ . has ( exported , key ) ) { warnUnused ( key , declared [ key ] , "var" ) ; } } } catch ( err ) { if ( err && err . name === "JSHintError" ) { var nt = state . tokens . next || { } ; JSHINT . errors . push ( { scope : "(main)" , raw : err . raw , code : err . code , reason : err . message , line : err . line || nt . line , character : err . character || nt . from } , null ) ; } else { throw err ; } } // Loop over the listed "internals", and check them as well. if ( JSHINT . scope === "(main)" ) { o = o || { } ; for ( i = 0 ; i < JSHINT . internals . length ; i += 1 ) { k = JSHINT . internals [ i ] ; o . scope = k . elem ; itself ( k . value , o , g ) ; } } return JSHINT . errors . length === 0 ; }
The actual JSHINT function itself.
The actual JSHINT function itself .