pakmanaged.js
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;
              // 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.