7257 lines
730 KiB
JavaScript
7257 lines
730 KiB
JavaScript
|
(function (f) {
|
|||
|
if (typeof exports === "object" && typeof module !== "undefined") {
|
|||
|
module.exports = f();
|
|||
|
} else if (typeof define === "function" && define.amd) {
|
|||
|
define([], f);
|
|||
|
} else {
|
|||
|
var g;
|
|||
|
if (typeof window !== "undefined") {
|
|||
|
g = window;
|
|||
|
} else if (typeof global !== "undefined") {
|
|||
|
g = global;
|
|||
|
} else if (typeof self !== "undefined") {
|
|||
|
g = self;
|
|||
|
} else {
|
|||
|
g = this;
|
|||
|
}
|
|||
|
(g.lunr || (g.lunr = {})).wordcut = f();
|
|||
|
}
|
|||
|
})(function () {
|
|||
|
var define, module, exports;
|
|||
|
return (function e(t, n, r) {
|
|||
|
function s(o, u) {
|
|||
|
if (!n[o]) {
|
|||
|
if (!t[o]) {
|
|||
|
var a = typeof require == "function" && require;
|
|||
|
if (!u && a) return a(o, !0);
|
|||
|
if (i) return i(o, !0);
|
|||
|
var f = new Error("Cannot find module '" + o + "'");
|
|||
|
throw ((f.code = "MODULE_NOT_FOUND"), f);
|
|||
|
}
|
|||
|
var l = (n[o] = { exports: {} });
|
|||
|
t[o][0].call(
|
|||
|
l.exports,
|
|||
|
function (e) {
|
|||
|
var n = t[o][1][e];
|
|||
|
return s(n ? n : e);
|
|||
|
},
|
|||
|
l,
|
|||
|
l.exports,
|
|||
|
e,
|
|||
|
t,
|
|||
|
n,
|
|||
|
r
|
|||
|
);
|
|||
|
}
|
|||
|
return n[o].exports;
|
|||
|
}
|
|||
|
var i = typeof require == "function" && require;
|
|||
|
for (var o = 0; o < r.length; o++) s(r[o]);
|
|||
|
return s;
|
|||
|
})(
|
|||
|
{
|
|||
|
1: [
|
|||
|
function (require, module, exports) {
|
|||
|
var _ = require("underscore");
|
|||
|
|
|||
|
var Acceptors = {
|
|||
|
creators: null,
|
|||
|
current: null,
|
|||
|
tag: null,
|
|||
|
|
|||
|
init: function () {
|
|||
|
this.creators = [];
|
|||
|
this.current = [];
|
|||
|
this.tag = {};
|
|||
|
},
|
|||
|
|
|||
|
reset: function () {
|
|||
|
this.current = [];
|
|||
|
this.tag = {};
|
|||
|
},
|
|||
|
|
|||
|
transit: function (ch) {
|
|||
|
var self = this;
|
|||
|
|
|||
|
self.creators.forEach(function (creator) {
|
|||
|
var acceptor = creator.createAcceptor(self.tag);
|
|||
|
if (acceptor) self.current.push(acceptor);
|
|||
|
});
|
|||
|
|
|||
|
var _current = [];
|
|||
|
self.tag = {};
|
|||
|
|
|||
|
for (var i = 0; i < self.current.length; i++) {
|
|||
|
var _acceptor = self.current[i],
|
|||
|
acceptor = _acceptor.transit(ch);
|
|||
|
|
|||
|
if (!acceptor.isError) {
|
|||
|
_current.push(acceptor);
|
|||
|
self.tag[acceptor.tag] = acceptor;
|
|||
|
}
|
|||
|
}
|
|||
|
self.current = _current;
|
|||
|
},
|
|||
|
|
|||
|
getFinalAcceptors: function () {
|
|||
|
return this.current.filter(function (acceptor) {
|
|||
|
return acceptor.isFinal;
|
|||
|
});
|
|||
|
},
|
|||
|
};
|
|||
|
|
|||
|
module.exports = function () {
|
|||
|
var acceptors = _.clone(Acceptors);
|
|||
|
acceptors.init();
|
|||
|
return acceptors;
|
|||
|
};
|
|||
|
},
|
|||
|
{ underscore: 25 },
|
|||
|
],
|
|||
|
2: [
|
|||
|
function (require, module, exports) {
|
|||
|
(function (__dirname) {
|
|||
|
var LEFT = 0;
|
|||
|
var RIGHT = 1;
|
|||
|
var path = require("path");
|
|||
|
var glob = require("glob");
|
|||
|
|
|||
|
var WordcutDict = {
|
|||
|
init: function (dictPathFile, withDefault, words) {
|
|||
|
withDefault = withDefault || false;
|
|||
|
defaultDict =
|
|||
|
path.normalize(__dirname + "/..") + "/data/tdict-*.txt";
|
|||
|
this.dict = [];
|
|||
|
var dictPathIsDefined = dictPathFile !== undefined;
|
|||
|
var dictPath =
|
|||
|
withDefault || !dictPathIsDefined ? [defaultDict] : [];
|
|||
|
var dictPathFile = dictPathFile || defaultDict;
|
|||
|
|
|||
|
if (dictPathIsDefined) {
|
|||
|
if (Array.isArray(dictPathFile)) {
|
|||
|
dictPath.concat.apply(dictPath, dictPathFile);
|
|||
|
} else {
|
|||
|
dictPath.push(dictPathFile);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
this.addFiles(dictPath, false);
|
|||
|
|
|||
|
if (words !== undefined) {
|
|||
|
this.addWords(words, false);
|
|||
|
}
|
|||
|
this.finalizeDict();
|
|||
|
},
|
|||
|
|
|||
|
addWords: function (words, finalize) {
|
|||
|
finalize = finalize === undefined || finalize;
|
|||
|
this.dict.push.apply(this.dict, words);
|
|||
|
if (finalize) {
|
|||
|
this.finalizeDict();
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
finalizeDict: function () {
|
|||
|
this.dict = this.sortuniq(this.dict);
|
|||
|
},
|
|||
|
|
|||
|
addFiles: function (files, finalize) {
|
|||
|
finalize = finalize === undefined || finalize;
|
|||
|
|
|||
|
for (var i = 0; i < 1; i++) {
|
|||
|
words = "ก.ก.\nก.ก.น.\nก.ข.ค.\nก.ค.\nก.จ.\nก.ช.น.\nก.ฌ.\nก.ต.\nก.ต.ง.\nก.ต.ช.\nก.ตร.\nก.ท.\nก.น.ช.\nก.บช.\nก.บถ.\nก.ป.ส.\nก.พ.\nก.ม.\nก.ย.\nก.ร.\nก.ล.ต.\nก.ว.\nก.ศ.ว.\nก.ส.ท.\nก.ส.ธ.\nก.ส.อ.\nก.อ.\nกก.ตชด.\nกก.ตร.น.\nกก.ภ.จว.\nกก.รสช.\nกกบ.ขส.ทบ.\nกกล.รพน.\nกง.กห.\nกง.ทบ.\nกง.ทร.\nกซข.ป.\nกซม.ป.\nกทม.กรุงเทพมหานคร\nกบ.ทบ.\nกป.สป.\nกพ.ทบ.\nกพ.ทร.\nกพ.ทหาร\nกร.ทบ.\nกรป.กลาง\nกรอ.พอ.\nกศ.ด.\nกศ.บ.\nกศ.บป.\nกศ.ม.\nกษ.ด.\nกษ.บ.\nกษ.ม.\nกส.ด.\nกส.ทบ.\nกส.บ.\nกส.ม.\nกอ.ปค.\nกอ.รพน.\nกอ.รมน.\nกอ.รสต.\nข.ต.ว.\nขว.ทบ.\nขว.ทร.\nขว.ทหาร\nขส.ทบ.\nขส.ทร.\nขส.ทอ.\nค.ด.\nค.บ.\nค.พ.ศ.\nค.ม.\nค.ร.น.\nค.ร.ฟ.\nค.ร.ม.\nค.ศ.\nค.อ.ด.\nค.อ.บ.\nค.อ.ม.\nคศ.ด.\nคศ.บ.\nคศ.ม.\nง.ด.\nจ.จ.\nจ.จ.จ.\nจ.ช.\nจ.ต.\nจ.ท.\nจ.ป.ร.\nจ.ม.\nจ.ศ.\nจ.ส.ต.\nจ.ส.ท.\nจ.ส.อ.\nจ.อ.\nจ.อ.ร.\nจ.๑๘\nจก.ธน.\nจก.สน.\nช.ค.\nช.ค.บ.\nช.พ.ค.\nช.ส.\nช.ส.ค.\nฌ.ป.ค.\nฌ.ศ.ร.\nฌ.ส.อ.\nฐท.สห.\nด.ช.\nด.ญ.\nด.ต.\nด.ศ.ค.\nด.ศ.ร.\nดย.ทร.\nต.ก.\nต.ค.\nต.จ.\nต.จ.ว.\nต.ช.\nต.ต.\nต.บ.\nต.ม.\nต.ร.\nต.ศ.ร.\nต.ห.\nต.อ.\nต.อ.จ.\nตร.กม.\nตร.ซม.\nตร.ต.\nตร.ทล.\nตร.น.\nตร.ปม.\nตร.ภ.\nตร.ม.\nตร.รฟ.\nตร.ว.\nตร.ส.\nตร.สข.\nท.จ.\nท.จ.ว.\nท.ช.\nท.ญ.\nท.ด.\nท.ท.ท.\nท.ทบ.\nท.บ.\nท.พ.\nท.ม.\nท.ศ.\nทก.ด.\nทก.บ.\nทก.ม.\nทส.ปช.\nทส.รมว.กห.\nทุ.ส.นิ.ม.\nธ.ก.ส.\nธ.ค.\nธ.ญ\nธ.บ.\nน.ช.\nน.ญ.\nน.ด.\nน.ต.\nน.ท.\nน.น.\nน.บ.\nน.บ.ท.\nน.ป.ท.\nน.พ.\nน.ม.\nน.ร.\nน.ว.\nน.ศ.\nน.ส.\nน.ส.พ.\nน.ส.๓\nน.สพ.\nน.อ.\nนปพ.ภ.\nนศ.ด.\nนศ.บ.\nนศ.ม.\nบ.ก.\nบ.ข.ส.\nบ.ช.\nบ.ด.ท.\nบ.ตร.\nบ.ภ.\nบ.ม.\nบก.จร.\nบก.ตชด.\nบก.ตม.\nบก.ทล.\nบก.น.\nบก.ป.\nบก.ปค.\nบก.ปม.\nบก.ภ.เขต\nบก.รน.\nบก.รฟ.\nบก.ร้อย.ตชด.\nบก.ส.\nบกข.ป.\nบจพ.ป.\nบช.ก.\nบช.ด.\nบช.ตชด.\nบช.น.\nบช.บ.\nบช.ปส.\nบช.ภ.\nบช.ม.\nบชท.ป.\nบชน.ป.\nบชส.ป.\nบธ.ด.\nบธ.บ.\nบธ.ม.\nบนท.ป.\nบนอ.ป.\nบปช.ป.\nป.กท.\nป.กศ.\nป.กศ.สูง\nป.จ.\nป.จ.ว.\nป.ช.\nป.ธ.\nป.ป.\nป.ป.ก.\nป.ป.ช.\nป.ป.ป.\nป.ป.ร.\nป.ป.ส.\nป.พ.\nป.พ.พ.\nป.พย.\nป.ม.\nป.ม.ก.\nป.ม.ช.\nป.ม.ธ.\nป.ม.ศ.\nป.ม.อ.\nป.ร.ร.๔\nป.ร.ร.๕\nป.ร.ร.๖\nป.ล.\nป.ว.พ.\nป.วิ.อ.\nป.ส.ส.\nป.อ.\nป.อ.ร.ส.\nป.๑\nปม.วส.\nปอ.พ.\nผกก.ภ.\nผช.ผอ.\nผต.มท.\nผบ.ตร.\nผบ.ทบ.\nผบ.ทร.\nผบ.ทสส.\nผบ.ทอ.\nผบก.น.\nผบก.ป.\nผบก.ปค.\nผบก.ปม.\nผบก.ภ.\nผบช.ก.\nผบช.ตชด.\nผบช.น.\nผบช.ภ.\nผว.กทม.\nผอ.ปจ.\nพ.ก.ง.\nพ.กศ.\nพ.ข.ต.\nพ.ค.\nพ.ค.ช.\nพ.ค.ว.\nพ.ค.ศ.\nพ.จ.ต.\nพ.จ.ท.\nพ.จ.อ.\nพ.ช.\nพ.ช.ค.\nพ.ด.\nพ.ต.\nพ.ต.ต.\nพ.ต.ท.\n<EFBFBD>
|
|||
|
.split(/[\r\n]+/)
|
|||
|
.filter(function (w) {
|
|||
|
return w.length > 1;
|
|||
|
});
|
|||
|
this.addWords(words, false);
|
|||
|
}
|
|||
|
if (finalize) {
|
|||
|
this.finalizeDict();
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
dictSeek: function (l, r, ch, strOffset, pos) {
|
|||
|
var ans = null;
|
|||
|
while (l <= r) {
|
|||
|
var m = Math.floor((l + r) / 2),
|
|||
|
dict_item = this.dict[m],
|
|||
|
len = dict_item.length;
|
|||
|
if (len <= strOffset) {
|
|||
|
l = m + 1;
|
|||
|
} else {
|
|||
|
var ch_ = dict_item[strOffset];
|
|||
|
if (ch_ < ch) {
|
|||
|
l = m + 1;
|
|||
|
} else if (ch_ > ch) {
|
|||
|
r = m - 1;
|
|||
|
} else {
|
|||
|
ans = m;
|
|||
|
if (pos == LEFT) {
|
|||
|
r = m - 1;
|
|||
|
} else {
|
|||
|
l = m + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return ans;
|
|||
|
},
|
|||
|
|
|||
|
isFinal: function (acceptor) {
|
|||
|
return this.dict[acceptor.l].length == acceptor.strOffset;
|
|||
|
},
|
|||
|
|
|||
|
createAcceptor: function () {
|
|||
|
return {
|
|||
|
l: 0,
|
|||
|
r: this.dict.length - 1,
|
|||
|
strOffset: 0,
|
|||
|
isFinal: false,
|
|||
|
dict: this,
|
|||
|
transit: function (ch) {
|
|||
|
return this.dict.transit(this, ch);
|
|||
|
},
|
|||
|
isError: false,
|
|||
|
tag: "DICT",
|
|||
|
w: 1,
|
|||
|
type: "DICT",
|
|||
|
};
|
|||
|
},
|
|||
|
|
|||
|
transit: function (acceptor, ch) {
|
|||
|
var l = this.dictSeek(
|
|||
|
acceptor.l,
|
|||
|
acceptor.r,
|
|||
|
ch,
|
|||
|
acceptor.strOffset,
|
|||
|
LEFT
|
|||
|
);
|
|||
|
if (l !== null) {
|
|||
|
var r = this.dictSeek(
|
|||
|
l,
|
|||
|
acceptor.r,
|
|||
|
ch,
|
|||
|
acceptor.strOffset,
|
|||
|
RIGHT
|
|||
|
);
|
|||
|
acceptor.l = l;
|
|||
|
acceptor.r = r;
|
|||
|
acceptor.strOffset++;
|
|||
|
acceptor.isFinal = this.isFinal(acceptor);
|
|||
|
} else {
|
|||
|
acceptor.isError = true;
|
|||
|
}
|
|||
|
return acceptor;
|
|||
|
},
|
|||
|
|
|||
|
sortuniq: function (a) {
|
|||
|
return a.sort().filter(function (item, pos, arr) {
|
|||
|
return !pos || item != arr[pos - 1];
|
|||
|
});
|
|||
|
},
|
|||
|
|
|||
|
flatten: function (a) {
|
|||
|
//[[1,2],[3]] -> [1,2,3]
|
|||
|
return [].concat.apply([], a);
|
|||
|
},
|
|||
|
};
|
|||
|
module.exports = WordcutDict;
|
|||
|
}.call(this, "/dist/tmp"));
|
|||
|
},
|
|||
|
{ glob: 16, path: 22 },
|
|||
|
],
|
|||
|
3: [
|
|||
|
function (require, module, exports) {
|
|||
|
var WordRule = {
|
|||
|
createAcceptor: function (tag) {
|
|||
|
if (tag["WORD_RULE"]) return null;
|
|||
|
|
|||
|
return {
|
|||
|
strOffset: 0,
|
|||
|
isFinal: false,
|
|||
|
transit: function (ch) {
|
|||
|
var lch = ch.toLowerCase();
|
|||
|
if (lch >= "a" && lch <= "z") {
|
|||
|
this.isFinal = true;
|
|||
|
this.strOffset++;
|
|||
|
} else {
|
|||
|
this.isError = true;
|
|||
|
}
|
|||
|
return this;
|
|||
|
},
|
|||
|
isError: false,
|
|||
|
tag: "WORD_RULE",
|
|||
|
type: "WORD_RULE",
|
|||
|
w: 1,
|
|||
|
};
|
|||
|
},
|
|||
|
};
|
|||
|
|
|||
|
var NumberRule = {
|
|||
|
createAcceptor: function (tag) {
|
|||
|
if (tag["NUMBER_RULE"]) return null;
|
|||
|
|
|||
|
return {
|
|||
|
strOffset: 0,
|
|||
|
isFinal: false,
|
|||
|
transit: function (ch) {
|
|||
|
if (ch >= "0" && ch <= "9") {
|
|||
|
this.isFinal = true;
|
|||
|
this.strOffset++;
|
|||
|
} else {
|
|||
|
this.isError = true;
|
|||
|
}
|
|||
|
return this;
|
|||
|
},
|
|||
|
isError: false,
|
|||
|
tag: "NUMBER_RULE",
|
|||
|
type: "NUMBER_RULE",
|
|||
|
w: 1,
|
|||
|
};
|
|||
|
},
|
|||
|
};
|
|||
|
|
|||
|
var SpaceRule = {
|
|||
|
tag: "SPACE_RULE",
|
|||
|
createAcceptor: function (tag) {
|
|||
|
if (tag["SPACE_RULE"]) return null;
|
|||
|
|
|||
|
return {
|
|||
|
strOffset: 0,
|
|||
|
isFinal: false,
|
|||
|
transit: function (ch) {
|
|||
|
if (
|
|||
|
ch == " " ||
|
|||
|
ch == "\t" ||
|
|||
|
ch == "\r" ||
|
|||
|
ch == "\n" ||
|
|||
|
ch == "\u00A0" ||
|
|||
|
ch == "\u2003" //nbsp and emsp
|
|||
|
) {
|
|||
|
this.isFinal = true;
|
|||
|
this.strOffset++;
|
|||
|
} else {
|
|||
|
this.isError = true;
|
|||
|
}
|
|||
|
return this;
|
|||
|
},
|
|||
|
isError: false,
|
|||
|
tag: SpaceRule.tag,
|
|||
|
w: 1,
|
|||
|
type: "SPACE_RULE",
|
|||
|
};
|
|||
|
},
|
|||
|
};
|
|||
|
|
|||
|
var SingleSymbolRule = {
|
|||
|
tag: "SINSYM",
|
|||
|
createAcceptor: function (tag) {
|
|||
|
return {
|
|||
|
strOffset: 0,
|
|||
|
isFinal: false,
|
|||
|
transit: function (ch) {
|
|||
|
if (this.strOffset == 0 && ch.match(/^[\@\(\)\/\,\-\."`]$/)) {
|
|||
|
this.isFinal = true;
|
|||
|
this.strOffset++;
|
|||
|
} else {
|
|||
|
this.isError = true;
|
|||
|
}
|
|||
|
return this;
|
|||
|
},
|
|||
|
isError: false,
|
|||
|
tag: "SINSYM",
|
|||
|
w: 1,
|
|||
|
type: "SINSYM",
|
|||
|
};
|
|||
|
},
|
|||
|
};
|
|||
|
|
|||
|
var LatinRules = [WordRule, SpaceRule, SingleSymbolRule, NumberRule];
|
|||
|
|
|||
|
module.exports = LatinRules;
|
|||
|
},
|
|||
|
{},
|
|||
|
],
|
|||
|
4: [
|
|||
|
function (require, module, exports) {
|
|||
|
var _ = require("underscore"),
|
|||
|
WordcutCore = require("./wordcut_core");
|
|||
|
var PathInfoBuilder = {
|
|||
|
/*
|
|||
|
buildByPartAcceptors: function(path, acceptors, i) {
|
|||
|
var
|
|||
|
var genInfos = partAcceptors.reduce(function(genInfos, acceptor) {
|
|||
|
|
|||
|
}, []);
|
|||
|
|
|||
|
return genInfos;
|
|||
|
}
|
|||
|
*/
|
|||
|
|
|||
|
buildByAcceptors: function (path, finalAcceptors, i) {
|
|||
|
var self = this;
|
|||
|
var infos = finalAcceptors.map(function (acceptor) {
|
|||
|
var p = i - acceptor.strOffset + 1,
|
|||
|
_info = path[p];
|
|||
|
|
|||
|
var info = {
|
|||
|
p: p,
|
|||
|
mw: _info.mw + (acceptor.mw === undefined ? 0 : acceptor.mw),
|
|||
|
w: acceptor.w + _info.w,
|
|||
|
unk: (acceptor.unk ? acceptor.unk : 0) + _info.unk,
|
|||
|
type: acceptor.type,
|
|||
|
};
|
|||
|
|
|||
|
if (acceptor.type == "PART") {
|
|||
|
for (var j = p + 1; j <= i; j++) {
|
|||
|
path[j].merge = p;
|
|||
|
}
|
|||
|
info.merge = p;
|
|||
|
}
|
|||
|
|
|||
|
return info;
|
|||
|
});
|
|||
|
return infos.filter(function (info) {
|
|||
|
return info;
|
|||
|
});
|
|||
|
},
|
|||
|
|
|||
|
fallback: function (path, leftBoundary, text, i) {
|
|||
|
var _info = path[leftBoundary];
|
|||
|
if (text[i].match(/[\u0E48-\u0E4E]/)) {
|
|||
|
if (leftBoundary != 0) leftBoundary = path[leftBoundary].p;
|
|||
|
return {
|
|||
|
p: leftBoundary,
|
|||
|
mw: 0,
|
|||
|
w: 1 + _info.w,
|
|||
|
unk: 1 + _info.unk,
|
|||
|
type: "UNK",
|
|||
|
};
|
|||
|
/* } else if(leftBoundary > 0 && path[leftBoundary].type !== "UNK") {
|
|||
|
leftBoundary = path[leftBoundary].p;
|
|||
|
return {p: leftBoundary,
|
|||
|
w: 1 + _info.w,
|
|||
|
unk: 1 + _info.unk,
|
|||
|
type: "UNK"}; */
|
|||
|
} else {
|
|||
|
return {
|
|||
|
p: leftBoundary,
|
|||
|
mw: _info.mw,
|
|||
|
w: 1 + _info.w,
|
|||
|
unk: 1 + _info.unk,
|
|||
|
type: "UNK",
|
|||
|
};
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
build: function (path, finalAcceptors, i, leftBoundary, text) {
|
|||
|
var basicPathInfos = this.buildByAcceptors(
|
|||
|
path,
|
|||
|
finalAcceptors,
|
|||
|
i
|
|||
|
);
|
|||
|
if (basicPathInfos.length > 0) {
|
|||
|
return basicPathInfos;
|
|||
|
} else {
|
|||
|
return [this.fallback(path, leftBoundary, text, i)];
|
|||
|
}
|
|||
|
},
|
|||
|
};
|
|||
|
|
|||
|
module.exports = function () {
|
|||
|
return _.clone(PathInfoBuilder);
|
|||
|
};
|
|||
|
},
|
|||
|
{ "./wordcut_core": 8, underscore: 25 },
|
|||
|
],
|
|||
|
5: [
|
|||
|
function (require, module, exports) {
|
|||
|
var _ = require("underscore");
|
|||
|
|
|||
|
var PathSelector = {
|
|||
|
selectPath: function (paths) {
|
|||
|
var path = paths.reduce(function (selectedPath, path) {
|
|||
|
if (selectedPath == null) {
|
|||
|
return path;
|
|||
|
} else {
|
|||
|
if (path.unk < selectedPath.unk) return path;
|
|||
|
if (path.unk == selectedPath.unk) {
|
|||
|
if (path.mw < selectedPath.mw) return path;
|
|||
|
if (path.mw == selectedPath.mw) {
|
|||
|
if (path.w < selectedPath.w) return path;
|
|||
|
}
|
|||
|
}
|
|||
|
return selectedPath;
|
|||
|
}
|
|||
|
}, null);
|
|||
|
return path;
|
|||
|
},
|
|||
|
|
|||
|
createPath: function () {
|
|||
|
return [{ p: null, w: 0, unk: 0, type: "INIT", mw: 0 }];
|
|||
|
},
|
|||
|
};
|
|||
|
|
|||
|
module.exports = function () {
|
|||
|
return _.clone(PathSelector);
|
|||
|
};
|
|||
|
},
|
|||
|
{ underscore: 25 },
|
|||
|
],
|
|||
|
6: [
|
|||
|
function (require, module, exports) {
|
|||
|
function isMatch(pat, offset, ch) {
|
|||
|
if (pat.length <= offset) return false;
|
|||
|
var _ch = pat[offset];
|
|||
|
return (
|
|||
|
_ch == ch ||
|
|||
|
(_ch.match(/[กข]/) && ch.match(/[ก-ฮ]/)) ||
|
|||
|
(_ch.match(/[มบ]/) && ch.match(/[ก-ฮ]/)) ||
|
|||
|
(_ch.match(/\u0E49/) && ch.match(/[\u0E48-\u0E4B]/))
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
var Rule0 = {
|
|||
|
pat: "เหก็ม",
|
|||
|
createAcceptor: function (tag) {
|
|||
|
return {
|
|||
|
strOffset: 0,
|
|||
|
isFinal: false,
|
|||
|
transit: function (ch) {
|
|||
|
if (isMatch(Rule0.pat, this.strOffset, ch)) {
|
|||
|
this.isFinal = this.strOffset + 1 == Rule0.pat.length;
|
|||
|
this.strOffset++;
|
|||
|
} else {
|
|||
|
this.isError = true;
|
|||
|
}
|
|||
|
return this;
|
|||
|
},
|
|||
|
isError: false,
|
|||
|
tag: "THAI_RULE",
|
|||
|
type: "THAI_RULE",
|
|||
|
w: 1,
|
|||
|
};
|
|||
|
},
|
|||
|
};
|
|||
|
|
|||
|
var PartRule = {
|
|||
|
createAcceptor: function (tag) {
|
|||
|
return {
|
|||
|
strOffset: 0,
|
|||
|
patterns: ["แก", "เก", "ก้", "กก์", "กา", "กี", "กิ", "กืก"],
|
|||
|
isFinal: false,
|
|||
|
transit: function (ch) {
|
|||
|
var offset = this.strOffset;
|
|||
|
this.patterns = this.patterns.filter(function (pat) {
|
|||
|
return isMatch(pat, offset, ch);
|
|||
|
});
|
|||
|
|
|||
|
if (this.patterns.length > 0) {
|
|||
|
var len = 1 + offset;
|
|||
|
this.isFinal = this.patterns.some(function (pat) {
|
|||
|
return pat.length == len;
|
|||
|
});
|
|||
|
this.strOffset++;
|
|||
|
} else {
|
|||
|
this.isError = true;
|
|||
|
}
|
|||
|
return this;
|
|||
|
},
|
|||
|
isError: false,
|
|||
|
tag: "PART",
|
|||
|
type: "PART",
|
|||
|
unk: 1,
|
|||
|
w: 1,
|
|||
|
};
|
|||
|
},
|
|||
|
};
|
|||
|
|
|||
|
var ThaiRules = [Rule0, PartRule];
|
|||
|
|
|||
|
module.exports = ThaiRules;
|
|||
|
},
|
|||
|
{},
|
|||
|
],
|
|||
|
7: [
|
|||
|
function (require, module, exports) {
|
|||
|
var sys = require("sys"),
|
|||
|
WordcutDict = require("./dict"),
|
|||
|
WordcutCore = require("./wordcut_core"),
|
|||
|
PathInfoBuilder = require("./path_info_builder"),
|
|||
|
PathSelector = require("./path_selector"),
|
|||
|
Acceptors = require("./acceptors"),
|
|||
|
latinRules = require("./latin_rules"),
|
|||
|
thaiRules = require("./thai_rules"),
|
|||
|
_ = require("underscore");
|
|||
|
|
|||
|
var Wordcut = Object.create(WordcutCore);
|
|||
|
Wordcut.defaultPathInfoBuilder = PathInfoBuilder;
|
|||
|
Wordcut.defaultPathSelector = PathSelector;
|
|||
|
Wordcut.defaultAcceptors = Acceptors;
|
|||
|
Wordcut.defaultLatinRules = latinRules;
|
|||
|
Wordcut.defaultThaiRules = thaiRules;
|
|||
|
Wordcut.defaultDict = WordcutDict;
|
|||
|
|
|||
|
Wordcut.initNoDict = function (dict_path) {
|
|||
|
var self = this;
|
|||
|
self.pathInfoBuilder = new self.defaultPathInfoBuilder();
|
|||
|
self.pathSelector = new self.defaultPathSelector();
|
|||
|
self.acceptors = new self.defaultAcceptors();
|
|||
|
self.defaultLatinRules.forEach(function (rule) {
|
|||
|
self.acceptors.creators.push(rule);
|
|||
|
});
|
|||
|
self.defaultThaiRules.forEach(function (rule) {
|
|||
|
self.acceptors.creators.push(rule);
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
Wordcut.init = function (dict_path, withDefault, additionalWords) {
|
|||
|
withDefault = withDefault || false;
|
|||
|
this.initNoDict();
|
|||
|
var dict = _.clone(this.defaultDict);
|
|||
|
dict.init(dict_path, withDefault, additionalWords);
|
|||
|
this.acceptors.creators.push(dict);
|
|||
|
};
|
|||
|
|
|||
|
module.exports = Wordcut;
|
|||
|
},
|
|||
|
{
|
|||
|
"./acceptors": 1,
|
|||
|
"./dict": 2,
|
|||
|
"./latin_rules": 3,
|
|||
|
"./path_info_builder": 4,
|
|||
|
"./path_selector": 5,
|
|||
|
"./thai_rules": 6,
|
|||
|
"./wordcut_core": 8,
|
|||
|
sys: 28,
|
|||
|
underscore: 25,
|
|||
|
},
|
|||
|
],
|
|||
|
8: [
|
|||
|
function (require, module, exports) {
|
|||
|
var WordcutCore = {
|
|||
|
buildPath: function (text) {
|
|||
|
var self = this,
|
|||
|
path = self.pathSelector.createPath(),
|
|||
|
leftBoundary = 0;
|
|||
|
self.acceptors.reset();
|
|||
|
for (var i = 0; i < text.length; i++) {
|
|||
|
var ch = text[i];
|
|||
|
self.acceptors.transit(ch);
|
|||
|
|
|||
|
var possiblePathInfos = self.pathInfoBuilder.build(
|
|||
|
path,
|
|||
|
self.acceptors.getFinalAcceptors(),
|
|||
|
i,
|
|||
|
leftBoundary,
|
|||
|
text
|
|||
|
);
|
|||
|
var selectedPath = self.pathSelector.selectPath(
|
|||
|
possiblePathInfos
|
|||
|
);
|
|||
|
|
|||
|
path.push(selectedPath);
|
|||
|
if (selectedPath.type !== "UNK") {
|
|||
|
leftBoundary = i;
|
|||
|
}
|
|||
|
}
|
|||
|
return path;
|
|||
|
},
|
|||
|
|
|||
|
pathToRanges: function (path) {
|
|||
|
var e = path.length - 1,
|
|||
|
ranges = [];
|
|||
|
|
|||
|
while (e > 0) {
|
|||
|
var info = path[e],
|
|||
|
s = info.p;
|
|||
|
|
|||
|
if (info.merge !== undefined && ranges.length > 0) {
|
|||
|
var r = ranges[ranges.length - 1];
|
|||
|
r.s = info.merge;
|
|||
|
s = r.s;
|
|||
|
} else {
|
|||
|
ranges.push({ s: s, e: e });
|
|||
|
}
|
|||
|
e = s;
|
|||
|
}
|
|||
|
return ranges.reverse();
|
|||
|
},
|
|||
|
|
|||
|
rangesToText: function (text, ranges, delimiter) {
|
|||
|
return ranges
|
|||
|
.map(function (r) {
|
|||
|
return text.substring(r.s, r.e);
|
|||
|
})
|
|||
|
.join(delimiter);
|
|||
|
},
|
|||
|
|
|||
|
cut: function (text, delimiter) {
|
|||
|
var path = this.buildPath(text),
|
|||
|
ranges = this.pathToRanges(path);
|
|||
|
return this.rangesToText(
|
|||
|
text,
|
|||
|
ranges,
|
|||
|
delimiter === undefined ? "|" : delimiter
|
|||
|
);
|
|||
|
},
|
|||
|
|
|||
|
cutIntoRanges: function (text, noText) {
|
|||
|
var path = this.buildPath(text),
|
|||
|
ranges = this.pathToRanges(path);
|
|||
|
|
|||
|
if (!noText) {
|
|||
|
ranges.forEach(function (r) {
|
|||
|
r.text = text.substring(r.s, r.e);
|
|||
|
});
|
|||
|
}
|
|||
|
return ranges;
|
|||
|
},
|
|||
|
|
|||
|
cutIntoArray: function (text) {
|
|||
|
var path = this.buildPath(text),
|
|||
|
ranges = this.pathToRanges(path);
|
|||
|
|
|||
|
return ranges.map(function (r) {
|
|||
|
return text.substring(r.s, r.e);
|
|||
|
});
|
|||
|
},
|
|||
|
};
|
|||
|
|
|||
|
module.exports = WordcutCore;
|
|||
|
},
|
|||
|
{},
|
|||
|
],
|
|||
|
9: [
|
|||
|
function (require, module, exports) {
|
|||
|
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
|
|||
|
//
|
|||
|
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
|
|||
|
//
|
|||
|
// Originally from narwhal.js (http://narwhaljs.org)
|
|||
|
// Copyright (c) 2009 Thomas Robinson <280north.com>
|
|||
|
//
|
|||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|||
|
// of this software and associated documentation files (the 'Software'), to
|
|||
|
// deal in the Software without restriction, including without limitation the
|
|||
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|||
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|||
|
// furnished to do so, subject to the following conditions:
|
|||
|
//
|
|||
|
// The above copyright notice and this permission notice shall be included in
|
|||
|
// all copies or substantial portions of the Software.
|
|||
|
//
|
|||
|
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|||
|
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|||
|
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|||
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|
|||
|
// when used in node, this will actually load the util module we depend on
|
|||
|
// versus loading the builtin util module as happens otherwise
|
|||
|
// this is a bug in node module loading as far as I am concerned
|
|||
|
var util = require("util/");
|
|||
|
|
|||
|
var pSlice = Array.prototype.slice;
|
|||
|
var hasOwn = Object.prototype.hasOwnProperty;
|
|||
|
|
|||
|
// 1. The assert module provides functions that throw
|
|||
|
// AssertionError's when particular conditions are not met. The
|
|||
|
// assert module must conform to the following interface.
|
|||
|
|
|||
|
var assert = (module.exports = ok);
|
|||
|
|
|||
|
// 2. The AssertionError is defined in assert.
|
|||
|
// new assert.AssertionError({ message: message,
|
|||
|
// actual: actual,
|
|||
|
// expected: expected })
|
|||
|
|
|||
|
assert.AssertionError = function AssertionError(options) {
|
|||
|
this.name = "AssertionError";
|
|||
|
this.actual = options.actual;
|
|||
|
this.expected = options.expected;
|
|||
|
this.operator = options.operator;
|
|||
|
if (options.message) {
|
|||
|
this.message = options.message;
|
|||
|
this.generatedMessage = false;
|
|||
|
} else {
|
|||
|
this.message = getMessage(this);
|
|||
|
this.generatedMessage = true;
|
|||
|
}
|
|||
|
var stackStartFunction = options.stackStartFunction || fail;
|
|||
|
|
|||
|
if (Error.captureStackTrace) {
|
|||
|
Error.captureStackTrace(this, stackStartFunction);
|
|||
|
} else {
|
|||
|
// non v8 browsers so we can have a stacktrace
|
|||
|
var err = new Error();
|
|||
|
if (err.stack) {
|
|||
|
var out = err.stack;
|
|||
|
|
|||
|
// try to strip useless frames
|
|||
|
var fn_name = stackStartFunction.name;
|
|||
|
var idx = out.indexOf("\n" + fn_name);
|
|||
|
if (idx >= 0) {
|
|||
|
// once we have located the function frame
|
|||
|
// we need to strip out everything before it (and its line)
|
|||
|
var next_line = out.indexOf("\n", idx + 1);
|
|||
|
out = out.substring(next_line + 1);
|
|||
|
}
|
|||
|
|
|||
|
this.stack = out;
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// assert.AssertionError instanceof Error
|
|||
|
util.inherits(assert.AssertionError, Error);
|
|||
|
|
|||
|
function replacer(key, value) {
|
|||
|
if (util.isUndefined(value)) {
|
|||
|
return "" + value;
|
|||
|
}
|
|||
|
if (util.isNumber(value) && !isFinite(value)) {
|
|||
|
return value.toString();
|
|||
|
}
|
|||
|
if (util.isFunction(value) || util.isRegExp(value)) {
|
|||
|
return value.toString();
|
|||
|
}
|
|||
|
return value;
|
|||
|
}
|
|||
|
|
|||
|
function truncate(s, n) {
|
|||
|
if (util.isString(s)) {
|
|||
|
return s.length < n ? s : s.slice(0, n);
|
|||
|
} else {
|
|||
|
return s;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function getMessage(self) {
|
|||
|
return (
|
|||
|
truncate(JSON.stringify(self.actual, replacer), 128) +
|
|||
|
" " +
|
|||
|
self.operator +
|
|||
|
" " +
|
|||
|
truncate(JSON.stringify(self.expected, replacer), 128)
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
// At present only the three keys mentioned above are used and
|
|||
|
// understood by the spec. Implementations or sub modules can pass
|
|||
|
// other keys to the AssertionError's constructor - they will be
|
|||
|
// ignored.
|
|||
|
|
|||
|
// 3. All of the following functions must throw an AssertionError
|
|||
|
// when a corresponding condition is not met, with a message that
|
|||
|
// may be undefined if not provided. All assertion methods provide
|
|||
|
// both the actual and expected values to the assertion error for
|
|||
|
// display purposes.
|
|||
|
|
|||
|
function fail(
|
|||
|
actual,
|
|||
|
expected,
|
|||
|
message,
|
|||
|
operator,
|
|||
|
stackStartFunction
|
|||
|
) {
|
|||
|
throw new assert.AssertionError({
|
|||
|
message: message,
|
|||
|
actual: actual,
|
|||
|
expected: expected,
|
|||
|
operator: operator,
|
|||
|
stackStartFunction: stackStartFunction,
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
// EXTENSION! allows for well behaved errors defined elsewhere.
|
|||
|
assert.fail = fail;
|
|||
|
|
|||
|
// 4. Pure assertion tests whether a value is truthy, as determined
|
|||
|
// by !!guard.
|
|||
|
// assert.ok(guard, message_opt);
|
|||
|
// This statement is equivalent to assert.equal(true, !!guard,
|
|||
|
// message_opt);. To test strictly for the value true, use
|
|||
|
// assert.strictEqual(true, guard, message_opt);.
|
|||
|
|
|||
|
function ok(value, message) {
|
|||
|
if (!value) fail(value, true, message, "==", assert.ok);
|
|||
|
}
|
|||
|
assert.ok = ok;
|
|||
|
|
|||
|
// 5. The equality assertion tests shallow, coercive equality with
|
|||
|
// ==.
|
|||
|
// assert.equal(actual, expected, message_opt);
|
|||
|
|
|||
|
assert.equal = function equal(actual, expected, message) {
|
|||
|
if (actual != expected)
|
|||
|
fail(actual, expected, message, "==", assert.equal);
|
|||
|
};
|
|||
|
|
|||
|
// 6. The non-equality assertion tests for whether two objects are not equal
|
|||
|
// with != assert.notEqual(actual, expected, message_opt);
|
|||
|
|
|||
|
assert.notEqual = function notEqual(actual, expected, message) {
|
|||
|
if (actual == expected) {
|
|||
|
fail(actual, expected, message, "!=", assert.notEqual);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// 7. The equivalence assertion tests a deep equality relation.
|
|||
|
// assert.deepEqual(actual, expected, message_opt);
|
|||
|
|
|||
|
assert.deepEqual = function deepEqual(actual, expected, message) {
|
|||
|
if (!_deepEqual(actual, expected)) {
|
|||
|
fail(actual, expected, message, "deepEqual", assert.deepEqual);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
function _deepEqual(actual, expected) {
|
|||
|
// 7.1. All identical values are equivalent, as determined by ===.
|
|||
|
if (actual === expected) {
|
|||
|
return true;
|
|||
|
} else if (util.isBuffer(actual) && util.isBuffer(expected)) {
|
|||
|
if (actual.length != expected.length) return false;
|
|||
|
|
|||
|
for (var i = 0; i < actual.length; i++) {
|
|||
|
if (actual[i] !== expected[i]) return false;
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
|
|||
|
// 7.2. If the expected value is a Date object, the actual value is
|
|||
|
// equivalent if it is also a Date object that refers to the same time.
|
|||
|
} else if (util.isDate(actual) && util.isDate(expected)) {
|
|||
|
return actual.getTime() === expected.getTime();
|
|||
|
|
|||
|
// 7.3 If the expected value is a RegExp object, the actual value is
|
|||
|
// equivalent if it is also a RegExp object with the same source and
|
|||
|
// properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
|
|||
|
} else if (util.isRegExp(actual) && util.isRegExp(expected)) {
|
|||
|
return (
|
|||
|
actual.source === expected.source &&
|
|||
|
actual.global === expected.global &&
|
|||
|
actual.multiline === expected.multiline &&
|
|||
|
actual.lastIndex === expected.lastIndex &&
|
|||
|
actual.ignoreCase === expected.ignoreCase
|
|||
|
);
|
|||
|
|
|||
|
// 7.4. Other pairs that do not both pass typeof value == 'object',
|
|||
|
// equivalence is determined by ==.
|
|||
|
} else if (!util.isObject(actual) && !util.isObject(expected)) {
|
|||
|
return actual == expected;
|
|||
|
|
|||
|
// 7.5 For all other Object pairs, including Array objects, equivalence is
|
|||
|
// determined by having the same number of owned properties (as verified
|
|||
|
// with Object.prototype.hasOwnProperty.call), the same set of keys
|
|||
|
// (although not necessarily the same order), equivalent values for every
|
|||
|
// corresponding key, and an identical 'prototype' property. Note: this
|
|||
|
// accounts for both named and indexed properties on Arrays.
|
|||
|
} else {
|
|||
|
return objEquiv(actual, expected);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function isArguments(object) {
|
|||
|
return (
|
|||
|
Object.prototype.toString.call(object) == "[object Arguments]"
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
function objEquiv(a, b) {
|
|||
|
if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b))
|
|||
|
return false;
|
|||
|
// an identical 'prototype' property.
|
|||
|
if (a.prototype !== b.prototype) return false;
|
|||
|
// if one is a primitive, the other must be same
|
|||
|
if (util.isPrimitive(a) || util.isPrimitive(b)) {
|
|||
|
return a === b;
|
|||
|
}
|
|||
|
var aIsArgs = isArguments(a),
|
|||
|
bIsArgs = isArguments(b);
|
|||
|
if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) return false;
|
|||
|
if (aIsArgs) {
|
|||
|
a = pSlice.call(a);
|
|||
|
b = pSlice.call(b);
|
|||
|
return _deepEqual(a, b);
|
|||
|
}
|
|||
|
var ka = objectKeys(a),
|
|||
|
kb = objectKeys(b),
|
|||
|
key,
|
|||
|
i;
|
|||
|
// having the same number of owned properties (keys incorporates
|
|||
|
// hasOwnProperty)
|
|||
|
if (ka.length != kb.length) return false;
|
|||
|
//the same set of keys (although not necessarily the same order),
|
|||
|
ka.sort();
|
|||
|
kb.sort();
|
|||
|
//~~~cheap key test
|
|||
|
for (i = ka.length - 1; i >= 0; i--) {
|
|||
|
if (ka[i] != kb[i]) return false;
|
|||
|
}
|
|||
|
//equivalent values for every corresponding key, and
|
|||
|
//~~~possibly expensive deep test
|
|||
|
for (i = ka.length - 1; i >= 0; i--) {
|
|||
|
key = ka[i];
|
|||
|
if (!_deepEqual(a[key], b[key])) return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
// 8. The non-equivalence assertion tests for any deep inequality.
|
|||
|
// assert.notDeepEqual(actual, expected, message_opt);
|
|||
|
|
|||
|
assert.notDeepEqual = function notDeepEqual(
|
|||
|
actual,
|
|||
|
expected,
|
|||
|
message
|
|||
|
) {
|
|||
|
if (_deepEqual(actual, expected)) {
|
|||
|
fail(
|
|||
|
actual,
|
|||
|
expected,
|
|||
|
message,
|
|||
|
"notDeepEqual",
|
|||
|
assert.notDeepEqual
|
|||
|
);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// 9. The strict equality assertion tests strict equality, as determined by ===.
|
|||
|
// assert.strictEqual(actual, expected, message_opt);
|
|||
|
|
|||
|
assert.strictEqual = function strictEqual(actual, expected, message) {
|
|||
|
if (actual !== expected) {
|
|||
|
fail(actual, expected, message, "===", assert.strictEqual);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// 10. The strict non-equality assertion tests for strict inequality, as
|
|||
|
// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
|
|||
|
|
|||
|
assert.notStrictEqual = function notStrictEqual(
|
|||
|
actual,
|
|||
|
expected,
|
|||
|
message
|
|||
|
) {
|
|||
|
if (actual === expected) {
|
|||
|
fail(actual, expected, message, "!==", assert.notStrictEqual);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
function expectedException(actual, expected) {
|
|||
|
if (!actual || !expected) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
if (Object.prototype.toString.call(expected) == "[object RegExp]") {
|
|||
|
return expected.test(actual);
|
|||
|
} else if (actual instanceof expected) {
|
|||
|
return true;
|
|||
|
} else if (expected.call({}, actual) === true) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
function _throws(shouldThrow, block, expected, message) {
|
|||
|
var actual;
|
|||
|
|
|||
|
if (util.isString(expected)) {
|
|||
|
message = expected;
|
|||
|
expected = null;
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
block();
|
|||
|
} catch (e) {
|
|||
|
actual = e;
|
|||
|
}
|
|||
|
|
|||
|
message =
|
|||
|
(expected && expected.name ? " (" + expected.name + ")." : ".") +
|
|||
|
(message ? " " + message : ".");
|
|||
|
|
|||
|
if (shouldThrow && !actual) {
|
|||
|
fail(actual, expected, "Missing expected exception" + message);
|
|||
|
}
|
|||
|
|
|||
|
if (!shouldThrow && expectedException(actual, expected)) {
|
|||
|
fail(actual, expected, "Got unwanted exception" + message);
|
|||
|
}
|
|||
|
|
|||
|
if (
|
|||
|
(shouldThrow &&
|
|||
|
actual &&
|
|||
|
expected &&
|
|||
|
!expectedException(actual, expected)) ||
|
|||
|
(!shouldThrow && actual)
|
|||
|
) {
|
|||
|
throw actual;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 11. Expected to throw an error:
|
|||
|
// assert.throws(block, Error_opt, message_opt);
|
|||
|
|
|||
|
assert.throws = function (
|
|||
|
block,
|
|||
|
/*optional*/ error,
|
|||
|
/*optional*/ message
|
|||
|
) {
|
|||
|
_throws.apply(this, [true].concat(pSlice.call(arguments)));
|
|||
|
};
|
|||
|
|
|||
|
// EXTENSION! This is annoying to write outside this module.
|
|||
|
assert.doesNotThrow = function (block, /*optional*/ message) {
|
|||
|
_throws.apply(this, [false].concat(pSlice.call(arguments)));
|
|||
|
};
|
|||
|
|
|||
|
assert.ifError = function (err) {
|
|||
|
if (err) {
|
|||
|
throw err;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
var objectKeys =
|
|||
|
Object.keys ||
|
|||
|
function (obj) {
|
|||
|
var keys = [];
|
|||
|
for (var key in obj) {
|
|||
|
if (hasOwn.call(obj, key)) keys.push(key);
|
|||
|
}
|
|||
|
return keys;
|
|||
|
};
|
|||
|
},
|
|||
|
{ "util/": 28 },
|
|||
|
],
|
|||
|
10: [
|
|||
|
function (require, module, exports) {
|
|||
|
"use strict";
|
|||
|
module.exports = balanced;
|
|||
|
function balanced(a, b, str) {
|
|||
|
if (a instanceof RegExp) a = maybeMatch(a, str);
|
|||
|
if (b instanceof RegExp) b = maybeMatch(b, str);
|
|||
|
|
|||
|
var r = range(a, b, str);
|
|||
|
|
|||
|
return (
|
|||
|
r && {
|
|||
|
start: r[0],
|
|||
|
end: r[1],
|
|||
|
pre: str.slice(0, r[0]),
|
|||
|
body: str.slice(r[0] + a.length, r[1]),
|
|||
|
post: str.slice(r[1] + b.length),
|
|||
|
}
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
function maybeMatch(reg, str) {
|
|||
|
var m = str.match(reg);
|
|||
|
return m ? m[0] : null;
|
|||
|
}
|
|||
|
|
|||
|
balanced.range = range;
|
|||
|
function range(a, b, str) {
|
|||
|
var begs, beg, left, right, result;
|
|||
|
var ai = str.indexOf(a);
|
|||
|
var bi = str.indexOf(b, ai + 1);
|
|||
|
var i = ai;
|
|||
|
|
|||
|
if (ai >= 0 && bi > 0) {
|
|||
|
begs = [];
|
|||
|
left = str.length;
|
|||
|
|
|||
|
while (i >= 0 && !result) {
|
|||
|
if (i == ai) {
|
|||
|
begs.push(i);
|
|||
|
ai = str.indexOf(a, i + 1);
|
|||
|
} else if (begs.length == 1) {
|
|||
|
result = [begs.pop(), bi];
|
|||
|
} else {
|
|||
|
beg = begs.pop();
|
|||
|
if (beg < left) {
|
|||
|
left = beg;
|
|||
|
right = bi;
|
|||
|
}
|
|||
|
|
|||
|
bi = str.indexOf(b, i + 1);
|
|||
|
}
|
|||
|
|
|||
|
i = ai < bi && ai >= 0 ? ai : bi;
|
|||
|
}
|
|||
|
|
|||
|
if (begs.length) {
|
|||
|
result = [left, right];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
},
|
|||
|
{},
|
|||
|
],
|
|||
|
11: [
|
|||
|
function (require, module, exports) {
|
|||
|
var concatMap = require("concat-map");
|
|||
|
var balanced = require("balanced-match");
|
|||
|
|
|||
|
module.exports = expandTop;
|
|||
|
|
|||
|
var escSlash = "\0SLASH" + Math.random() + "\0";
|
|||
|
var escOpen = "\0OPEN" + Math.random() + "\0";
|
|||
|
var escClose = "\0CLOSE" + Math.random() + "\0";
|
|||
|
var escComma = "\0COMMA" + Math.random() + "\0";
|
|||
|
var escPeriod = "\0PERIOD" + Math.random() + "\0";
|
|||
|
|
|||
|
function numeric(str) {
|
|||
|
return parseInt(str, 10) == str
|
|||
|
? parseInt(str, 10)
|
|||
|
: str.charCodeAt(0);
|
|||
|
}
|
|||
|
|
|||
|
function escapeBraces(str) {
|
|||
|
return str
|
|||
|
.split("\\\\")
|
|||
|
.join(escSlash)
|
|||
|
.split("\\{")
|
|||
|
.join(escOpen)
|
|||
|
.split("\\}")
|
|||
|
.join(escClose)
|
|||
|
.split("\\,")
|
|||
|
.join(escComma)
|
|||
|
.split("\\.")
|
|||
|
.join(escPeriod);
|
|||
|
}
|
|||
|
|
|||
|
function unescapeBraces(str) {
|
|||
|
return str
|
|||
|
.split(escSlash)
|
|||
|
.join("\\")
|
|||
|
.split(escOpen)
|
|||
|
.join("{")
|
|||
|
.split(escClose)
|
|||
|
.join("}")
|
|||
|
.split(escComma)
|
|||
|
.join(",")
|
|||
|
.split(escPeriod)
|
|||
|
.join(".");
|
|||
|
}
|
|||
|
|
|||
|
// Basically just str.split(","), but handling cases
|
|||
|
// where we have nested braced sections, which should be
|
|||
|
// treated as individual members, like {a,{b,c},d}
|
|||
|
function parseCommaParts(str) {
|
|||
|
if (!str) return [""];
|
|||
|
|
|||
|
var parts = [];
|
|||
|
var m = balanced("{", "}", str);
|
|||
|
|
|||
|
if (!m) return str.split(",");
|
|||
|
|
|||
|
var pre = m.pre;
|
|||
|
var body = m.body;
|
|||
|
var post = m.post;
|
|||
|
var p = pre.split(",");
|
|||
|
|
|||
|
p[p.length - 1] += "{" + body + "}";
|
|||
|
var postParts = parseCommaParts(post);
|
|||
|
if (post.length) {
|
|||
|
p[p.length - 1] += postParts.shift();
|
|||
|
p.push.apply(p, postParts);
|
|||
|
}
|
|||
|
|
|||
|
parts.push.apply(parts, p);
|
|||
|
|
|||
|
return parts;
|
|||
|
}
|
|||
|
|
|||
|
function expandTop(str) {
|
|||
|
if (!str) return [];
|
|||
|
|
|||
|
// I don't know why Bash 4.3 does this, but it does.
|
|||
|
// Anything starting with {} will have the first two bytes preserved
|
|||
|
// but *only* at the top level, so {},a}b will not expand to anything,
|
|||
|
// but a{},b}c will be expanded to [a}c,abc].
|
|||
|
// One could argue that this is a bug in Bash, but since the goal of
|
|||
|
// this module is to match Bash's rules, we escape a leading {}
|
|||
|
if (str.substr(0, 2) === "{}") {
|
|||
|
str = "\\{\\}" + str.substr(2);
|
|||
|
}
|
|||
|
|
|||
|
return expand(escapeBraces(str), true).map(unescapeBraces);
|
|||
|
}
|
|||
|
|
|||
|
function identity(e) {
|
|||
|
return e;
|
|||
|
}
|
|||
|
|
|||
|
function embrace(str) {
|
|||
|
return "{" + str + "}";
|
|||
|
}
|
|||
|
function isPadded(el) {
|
|||
|
return /^-?0\d/.test(el);
|
|||
|
}
|
|||
|
|
|||
|
function lte(i, y) {
|
|||
|
return i <= y;
|
|||
|
}
|
|||
|
function gte(i, y) {
|
|||
|
return i >= y;
|
|||
|
}
|
|||
|
|
|||
|
function expand(str, isTop) {
|
|||
|
var expansions = [];
|
|||
|
|
|||
|
var m = balanced("{", "}", str);
|
|||
|
if (!m || /\$$/.test(m.pre)) return [str];
|
|||
|
|
|||
|
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(
|
|||
|
m.body
|
|||
|
);
|
|||
|
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(
|
|||
|
m.body
|
|||
|
);
|
|||
|
var isSequence = isNumericSequence || isAlphaSequence;
|
|||
|
var isOptions = m.body.indexOf(",") >= 0;
|
|||
|
if (!isSequence && !isOptions) {
|
|||
|
// {a},b}
|
|||
|
if (m.post.match(/,.*\}/)) {
|
|||
|
str = m.pre + "{" + m.body + escClose + m.post;
|
|||
|
return expand(str);
|
|||
|
}
|
|||
|
return [str];
|
|||
|
}
|
|||
|
|
|||
|
var n;
|
|||
|
if (isSequence) {
|
|||
|
n = m.body.split(/\.\./);
|
|||
|
} else {
|
|||
|
n = parseCommaParts(m.body);
|
|||
|
if (n.length === 1) {
|
|||
|
// x{{a,b}}y ==> x{a}y x{b}y
|
|||
|
n = expand(n[0], false).map(embrace);
|
|||
|
if (n.length === 1) {
|
|||
|
var post = m.post.length ? expand(m.post, false) : [""];
|
|||
|
return post.map(function (p) {
|
|||
|
return m.pre + n[0] + p;
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// at this point, n is the parts, and we know it's not a comma set
|
|||
|
// with a single entry.
|
|||
|
|
|||
|
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
|||
|
var pre = m.pre;
|
|||
|
var post = m.post.length ? expand(m.post, false) : [""];
|
|||
|
|
|||
|
var N;
|
|||
|
|
|||
|
if (isSequence) {
|
|||
|
var x = numeric(n[0]);
|
|||
|
var y = numeric(n[1]);
|
|||
|
var width = Math.max(n[0].length, n[1].length);
|
|||
|
var incr = n.length == 3 ? Math.abs(numeric(n[2])) : 1;
|
|||
|
var test = lte;
|
|||
|
var reverse = y < x;
|
|||
|
if (reverse) {
|
|||
|
incr *= -1;
|
|||
|
test = gte;
|
|||
|
}
|
|||
|
var pad = n.some(isPadded);
|
|||
|
|
|||
|
N = [];
|
|||
|
|
|||
|
for (var i = x; test(i, y); i += incr) {
|
|||
|
var c;
|
|||
|
if (isAlphaSequence) {
|
|||
|
c = String.fromCharCode(i);
|
|||
|
if (c === "\\") c = "";
|
|||
|
} else {
|
|||
|
c = String(i);
|
|||
|
if (pad) {
|
|||
|
var need = width - c.length;
|
|||
|
if (need > 0) {
|
|||
|
var z = new Array(need + 1).join("0");
|
|||
|
if (i < 0) c = "-" + z + c.slice(1);
|
|||
|
else c = z + c;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
N.push(c);
|
|||
|
}
|
|||
|
} else {
|
|||
|
N = concatMap(n, function (el) {
|
|||
|
return expand(el, false);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
for (var j = 0; j < N.length; j++) {
|
|||
|
for (var k = 0; k < post.length; k++) {
|
|||
|
var expansion = pre + N[j] + post[k];
|
|||
|
if (!isTop || isSequence || expansion)
|
|||
|
expansions.push(expansion);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return expansions;
|
|||
|
}
|
|||
|
},
|
|||
|
{ "balanced-match": 10, "concat-map": 13 },
|
|||
|
],
|
|||
|
12: [function (require, module, exports) {}, {}],
|
|||
|
13: [
|
|||
|
function (require, module, exports) {
|
|||
|
module.exports = function (xs, fn) {
|
|||
|
var res = [];
|
|||
|
for (var i = 0; i < xs.length; i++) {
|
|||
|
var x = fn(xs[i], i);
|
|||
|
if (isArray(x)) res.push.apply(res, x);
|
|||
|
else res.push(x);
|
|||
|
}
|
|||
|
return res;
|
|||
|
};
|
|||
|
|
|||
|
var isArray =
|
|||
|
Array.isArray ||
|
|||
|
function (xs) {
|
|||
|
return Object.prototype.toString.call(xs) === "[object Array]";
|
|||
|
};
|
|||
|
},
|
|||
|
{},
|
|||
|
],
|
|||
|
14: [
|
|||
|
function (require, module, exports) {
|
|||
|
// Copyright Joyent, Inc. and other Node contributors.
|
|||
|
//
|
|||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
|
// copy of this software and associated documentation files (the
|
|||
|
// "Software"), to deal in the Software without restriction, including
|
|||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
|
// persons to whom the Software is furnished to do so, subject to the
|
|||
|
// following conditions:
|
|||
|
//
|
|||
|
// The above copyright notice and this permission notice shall be included
|
|||
|
// in all copies or substantial portions of the Software.
|
|||
|
//
|
|||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|
|||
|
function EventEmitter() {
|
|||
|
this._events = this._events || {};
|
|||
|
this._maxListeners = this._maxListeners || undefined;
|
|||
|
}
|
|||
|
module.exports = EventEmitter;
|
|||
|
|
|||
|
// Backwards-compat with node 0.10.x
|
|||
|
EventEmitter.EventEmitter = EventEmitter;
|
|||
|
|
|||
|
EventEmitter.prototype._events = undefined;
|
|||
|
EventEmitter.prototype._maxListeners = undefined;
|
|||
|
|
|||
|
// By default EventEmitters will print a warning if more than 10 listeners are
|
|||
|
// added to it. This is a useful default which helps finding memory leaks.
|
|||
|
EventEmitter.defaultMaxListeners = 10;
|
|||
|
|
|||
|
// Obviously not all Emitters should be limited to 10. This function allows
|
|||
|
// that to be increased. Set to zero for unlimited.
|
|||
|
EventEmitter.prototype.setMaxListeners = function (n) {
|
|||
|
if (!isNumber(n) || n < 0 || isNaN(n))
|
|||
|
throw TypeError("n must be a positive number");
|
|||
|
this._maxListeners = n;
|
|||
|
return this;
|
|||
|
};
|
|||
|
|
|||
|
EventEmitter.prototype.emit = function (type) {
|
|||
|
var er, handler, len, args, i, listeners;
|
|||
|
|
|||
|
if (!this._events) this._events = {};
|
|||
|
|
|||
|
// If there is no 'error' event listener then throw.
|
|||
|
if (type === "error") {
|
|||
|
if (
|
|||
|
!this._events.error ||
|
|||
|
(isObject(this._events.error) && !this._events.error.length)
|
|||
|
) {
|
|||
|
er = arguments[1];
|
|||
|
if (er instanceof Error) {
|
|||
|
throw er; // Unhandled 'error' event
|
|||
|
}
|
|||
|
throw TypeError('Uncaught, unspecified "error" event.');
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
handler = this._events[type];
|
|||
|
|
|||
|
if (isUndefined(handler)) return false;
|
|||
|
|
|||
|
if (isFunction(handler)) {
|
|||
|
switch (arguments.length) {
|
|||
|
// fast cases
|
|||
|
case 1:
|
|||
|
handler.call(this);
|
|||
|
break;
|
|||
|
case 2:
|
|||
|
handler.call(this, arguments[1]);
|
|||
|
break;
|
|||
|
case 3:
|
|||
|
handler.call(this, arguments[1], arguments[2]);
|
|||
|
break;
|
|||
|
// slower
|
|||
|
default:
|
|||
|
len = arguments.length;
|
|||
|
args = new Array(len - 1);
|
|||
|
for (i = 1; i < len; i++) args[i - 1] = arguments[i];
|
|||
|
handler.apply(this, args);
|
|||
|
}
|
|||
|
} else if (isObject(handler)) {
|
|||
|
len = arguments.length;
|
|||
|
args = new Array(len - 1);
|
|||
|
for (i = 1; i < len; i++) args[i - 1] = arguments[i];
|
|||
|
|
|||
|
listeners = handler.slice();
|
|||
|
len = listeners.length;
|
|||
|
for (i = 0; i < len; i++) listeners[i].apply(this, args);
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
EventEmitter.prototype.addListener = function (type, listener) {
|
|||
|
var m;
|
|||
|
|
|||
|
if (!isFunction(listener))
|
|||
|
throw TypeError("listener must be a function");
|
|||
|
|
|||
|
if (!this._events) this._events = {};
|
|||
|
|
|||
|
// To avoid recursion in the case that type === "newListener"! Before
|
|||
|
// adding it to the listeners, first emit "newListener".
|
|||
|
if (this._events.newListener)
|
|||
|
this.emit(
|
|||
|
"newListener",
|
|||
|
type,
|
|||
|
isFunction(listener.listener) ? listener.listener : listener
|
|||
|
);
|
|||
|
|
|||
|
if (!this._events[type])
|
|||
|
// Optimize the case of one listener. Don't need the extra array object.
|
|||
|
this._events[type] = listener;
|
|||
|
else if (isObject(this._events[type]))
|
|||
|
// If we've already got an array, just append.
|
|||
|
this._events[type].push(listener);
|
|||
|
// Adding the second element, need to change to array.
|
|||
|
else this._events[type] = [this._events[type], listener];
|
|||
|
|
|||
|
// Check for listener leak
|
|||
|
if (isObject(this._events[type]) && !this._events[type].warned) {
|
|||
|
var m;
|
|||
|
if (!isUndefined(this._maxListeners)) {
|
|||
|
m = this._maxListeners;
|
|||
|
} else {
|
|||
|
m = EventEmitter.defaultMaxListeners;
|
|||
|
}
|
|||
|
|
|||
|
if (m && m > 0 && this._events[type].length > m) {
|
|||
|
this._events[type].warned = true;
|
|||
|
console.error(
|
|||
|
"(node) warning: possible EventEmitter memory " +
|
|||
|
"leak detected. %d listeners added. " +
|
|||
|
"Use emitter.setMaxListeners() to increase limit.",
|
|||
|
this._events[type].length
|
|||
|
);
|
|||
|
if (typeof console.trace === "function") {
|
|||
|
// not supported in IE 10
|
|||
|
console.trace();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return this;
|
|||
|
};
|
|||
|
|
|||
|
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
|||
|
|
|||
|
EventEmitter.prototype.once = function (type, listener) {
|
|||
|
if (!isFunction(listener))
|
|||
|
throw TypeError("listener must be a function");
|
|||
|
|
|||
|
var fired = false;
|
|||
|
|
|||
|
function g() {
|
|||
|
this.removeListener(type, g);
|
|||
|
|
|||
|
if (!fired) {
|
|||
|
fired = true;
|
|||
|
listener.apply(this, arguments);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
g.listener = listener;
|
|||
|
this.on(type, g);
|
|||
|
|
|||
|
return this;
|
|||
|
};
|
|||
|
|
|||
|
// emits a 'removeListener' event iff the listener was removed
|
|||
|
EventEmitter.prototype.removeListener = function (type, listener) {
|
|||
|
var list, position, length, i;
|
|||
|
|
|||
|
if (!isFunction(listener))
|
|||
|
throw TypeError("listener must be a function");
|
|||
|
|
|||
|
if (!this._events || !this._events[type]) return this;
|
|||
|
|
|||
|
list = this._events[type];
|
|||
|
length = list.length;
|
|||
|
position = -1;
|
|||
|
|
|||
|
if (
|
|||
|
list === listener ||
|
|||
|
(isFunction(list.listener) && list.listener === listener)
|
|||
|
) {
|
|||
|
delete this._events[type];
|
|||
|
if (this._events.removeListener)
|
|||
|
this.emit("removeListener", type, listener);
|
|||
|
} else if (isObject(list)) {
|
|||
|
for (i = length; i-- > 0; ) {
|
|||
|
if (
|
|||
|
list[i] === listener ||
|
|||
|
(list[i].listener && list[i].listener === listener)
|
|||
|
) {
|
|||
|
position = i;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (position < 0) return this;
|
|||
|
|
|||
|
if (list.length === 1) {
|
|||
|
list.length = 0;
|
|||
|
delete this._events[type];
|
|||
|
} else {
|
|||
|
list.splice(position, 1);
|
|||
|
}
|
|||
|
|
|||
|
if (this._events.removeListener)
|
|||
|
this.emit("removeListener", type, listener);
|
|||
|
}
|
|||
|
|
|||
|
return this;
|
|||
|
};
|
|||
|
|
|||
|
EventEmitter.prototype.removeAllListeners = function (type) {
|
|||
|
var key, listeners;
|
|||
|
|
|||
|
if (!this._events) return this;
|
|||
|
|
|||
|
// not listening for removeListener, no need to emit
|
|||
|
if (!this._events.removeListener) {
|
|||
|
if (arguments.length === 0) this._events = {};
|
|||
|
else if (this._events[type]) delete this._events[type];
|
|||
|
return this;
|
|||
|
}
|
|||
|
|
|||
|
// emit removeListener for all listeners on all events
|
|||
|
if (arguments.length === 0) {
|
|||
|
for (key in this._events) {
|
|||
|
if (key === "removeListener") continue;
|
|||
|
this.removeAllListeners(key);
|
|||
|
}
|
|||
|
this.removeAllListeners("removeListener");
|
|||
|
this._events = {};
|
|||
|
return this;
|
|||
|
}
|
|||
|
|
|||
|
listeners = this._events[type];
|
|||
|
|
|||
|
if (isFunction(listeners)) {
|
|||
|
this.removeListener(type, listeners);
|
|||
|
} else {
|
|||
|
// LIFO order
|
|||
|
while (listeners.length)
|
|||
|
this.removeListener(type, listeners[listeners.length - 1]);
|
|||
|
}
|
|||
|
delete this._events[type];
|
|||
|
|
|||
|
return this;
|
|||
|
};
|
|||
|
|
|||
|
EventEmitter.prototype.listeners = function (type) {
|
|||
|
var ret;
|
|||
|
if (!this._events || !this._events[type]) ret = [];
|
|||
|
else if (isFunction(this._events[type])) ret = [this._events[type]];
|
|||
|
else ret = this._events[type].slice();
|
|||
|
return ret;
|
|||
|
};
|
|||
|
|
|||
|
EventEmitter.listenerCount = function (emitter, type) {
|
|||
|
var ret;
|
|||
|
if (!emitter._events || !emitter._events[type]) ret = 0;
|
|||
|
else if (isFunction(emitter._events[type])) ret = 1;
|
|||
|
else ret = emitter._events[type].length;
|
|||
|
return ret;
|
|||
|
};
|
|||
|
|
|||
|
function isFunction(arg) {
|
|||
|
return typeof arg === "function";
|
|||
|
}
|
|||
|
|
|||
|
function isNumber(arg) {
|
|||
|
return typeof arg === "number";
|
|||
|
}
|
|||
|
|
|||
|
function isObject(arg) {
|
|||
|
return typeof arg === "object" && arg !== null;
|
|||
|
}
|
|||
|
|
|||
|
function isUndefined(arg) {
|
|||
|
return arg === void 0;
|
|||
|
}
|
|||
|
},
|
|||
|
{},
|
|||
|
],
|
|||
|
15: [
|
|||
|
function (require, module, exports) {
|
|||
|
(function (process) {
|
|||
|
exports.alphasort = alphasort;
|
|||
|
exports.alphasorti = alphasorti;
|
|||
|
exports.setopts = setopts;
|
|||
|
exports.ownProp = ownProp;
|
|||
|
exports.makeAbs = makeAbs;
|
|||
|
exports.finish = finish;
|
|||
|
exports.mark = mark;
|
|||
|
exports.isIgnored = isIgnored;
|
|||
|
exports.childrenIgnored = childrenIgnored;
|
|||
|
|
|||
|
function ownProp(obj, field) {
|
|||
|
return Object.prototype.hasOwnProperty.call(obj, field);
|
|||
|
}
|
|||
|
|
|||
|
var path = require("path");
|
|||
|
var minimatch = require("minimatch");
|
|||
|
var isAbsolute = require("path-is-absolute");
|
|||
|
var Minimatch = minimatch.Minimatch;
|
|||
|
|
|||
|
function alphasorti(a, b) {
|
|||
|
return a.toLowerCase().localeCompare(b.toLowerCase());
|
|||
|
}
|
|||
|
|
|||
|
function alphasort(a, b) {
|
|||
|
return a.localeCompare(b);
|
|||
|
}
|
|||
|
|
|||
|
function setupIgnores(self, options) {
|
|||
|
self.ignore = options.ignore || [];
|
|||
|
|
|||
|
if (!Array.isArray(self.ignore)) self.ignore = [self.ignore];
|
|||
|
|
|||
|
if (self.ignore.length) {
|
|||
|
self.ignore = self.ignore.map(ignoreMap);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function ignoreMap(pattern) {
|
|||
|
var gmatcher = null;
|
|||
|
if (pattern.slice(-3) === "/**") {
|
|||
|
var gpattern = pattern.replace(/(\/\*\*)+$/, "");
|
|||
|
gmatcher = new Minimatch(gpattern);
|
|||
|
}
|
|||
|
|
|||
|
return {
|
|||
|
matcher: new Minimatch(pattern),
|
|||
|
gmatcher: gmatcher,
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
function setopts(self, pattern, options) {
|
|||
|
if (!options) options = {};
|
|||
|
|
|||
|
// base-matching: just use globstar for that.
|
|||
|
if (options.matchBase && -1 === pattern.indexOf("/")) {
|
|||
|
if (options.noglobstar) {
|
|||
|
throw new Error("base matching requires globstar");
|
|||
|
}
|
|||
|
pattern = "**/" + pattern;
|
|||
|
}
|
|||
|
|
|||
|
self.silent = !!options.silent;
|
|||
|
self.pattern = pattern;
|
|||
|
self.strict = options.strict !== false;
|
|||
|
self.realpath = !!options.realpath;
|
|||
|
self.realpathCache = options.realpathCache || Object.create(null);
|
|||
|
self.follow = !!options.follow;
|
|||
|
self.dot = !!options.dot;
|
|||
|
self.mark = !!options.mark;
|
|||
|
self.nodir = !!options.nodir;
|
|||
|
if (self.nodir) self.mark = true;
|
|||
|
self.sync = !!options.sync;
|
|||
|
self.nounique = !!options.nounique;
|
|||
|
self.nonull = !!options.nonull;
|
|||
|
self.nosort = !!options.nosort;
|
|||
|
self.nocase = !!options.nocase;
|
|||
|
self.stat = !!options.stat;
|
|||
|
self.noprocess = !!options.noprocess;
|
|||
|
|
|||
|
self.maxLength = options.maxLength || Infinity;
|
|||
|
self.cache = options.cache || Object.create(null);
|
|||
|
self.statCache = options.statCache || Object.create(null);
|
|||
|
self.symlinks = options.symlinks || Object.create(null);
|
|||
|
|
|||
|
setupIgnores(self, options);
|
|||
|
|
|||
|
self.changedCwd = false;
|
|||
|
var cwd = process.cwd();
|
|||
|
if (!ownProp(options, "cwd")) self.cwd = cwd;
|
|||
|
else {
|
|||
|
self.cwd = options.cwd;
|
|||
|
self.changedCwd = path.resolve(options.cwd) !== cwd;
|
|||
|
}
|
|||
|
|
|||
|
self.root = options.root || path.resolve(self.cwd, "/");
|
|||
|
self.root = path.resolve(self.root);
|
|||
|
if (process.platform === "win32")
|
|||
|
self.root = self.root.replace(/\\/g, "/");
|
|||
|
|
|||
|
self.nomount = !!options.nomount;
|
|||
|
|
|||
|
// disable comments and negation unless the user explicitly
|
|||
|
// passes in false as the option.
|
|||
|
options.nonegate = options.nonegate === false ? false : true;
|
|||
|
options.nocomment = options.nocomment === false ? false : true;
|
|||
|
deprecationWarning(options);
|
|||
|
|
|||
|
self.minimatch = new Minimatch(pattern, options);
|
|||
|
self.options = self.minimatch.options;
|
|||
|
}
|
|||
|
|
|||
|
// TODO(isaacs): remove entirely in v6
|
|||
|
// exported to reset in tests
|
|||
|
exports.deprecationWarned;
|
|||
|
function deprecationWarning(options) {
|
|||
|
if (!options.nonegate || !options.nocomment) {
|
|||
|
if (
|
|||
|
process.noDeprecation !== true &&
|
|||
|
!exports.deprecationWarned
|
|||
|
) {
|
|||
|
var msg =
|
|||
|
"glob WARNING: comments and negation will be disabled in v6";
|
|||
|
if (process.throwDeprecation) throw new Error(msg);
|
|||
|
else if (process.traceDeprecation) console.trace(msg);
|
|||
|
else console.error(msg);
|
|||
|
|
|||
|
exports.deprecationWarned = true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function finish(self) {
|
|||
|
var nou = self.nounique;
|
|||
|
var all = nou ? [] : Object.create(null);
|
|||
|
|
|||
|
for (var i = 0, l = self.matches.length; i < l; i++) {
|
|||
|
var matches = self.matches[i];
|
|||
|
if (!matches || Object.keys(matches).length === 0) {
|
|||
|
if (self.nonull) {
|
|||
|
// do like the shell, and spit out the literal glob
|
|||
|
var literal = self.minimatch.globSet[i];
|
|||
|
if (nou) all.push(literal);
|
|||
|
else all[literal] = true;
|
|||
|
}
|
|||
|
} else {
|
|||
|
// had matches
|
|||
|
var m = Object.keys(matches);
|
|||
|
if (nou) all.push.apply(all, m);
|
|||
|
else
|
|||
|
m.forEach(function (m) {
|
|||
|
all[m] = true;
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!nou) all = Object.keys(all);
|
|||
|
|
|||
|
if (!self.nosort)
|
|||
|
all = all.sort(self.nocase ? alphasorti : alphasort);
|
|||
|
|
|||
|
// at *some* point we statted all of these
|
|||
|
if (self.mark) {
|
|||
|
for (var i = 0; i < all.length; i++) {
|
|||
|
all[i] = self._mark(all[i]);
|
|||
|
}
|
|||
|
if (self.nodir) {
|
|||
|
all = all.filter(function (e) {
|
|||
|
return !/\/$/.test(e);
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (self.ignore.length)
|
|||
|
all = all.filter(function (m) {
|
|||
|
return !isIgnored(self, m);
|
|||
|
});
|
|||
|
|
|||
|
self.found = all;
|
|||
|
}
|
|||
|
|
|||
|
function mark(self, p) {
|
|||
|
var abs = makeAbs(self, p);
|
|||
|
var c = self.cache[abs];
|
|||
|
var m = p;
|
|||
|
if (c) {
|
|||
|
var isDir = c === "DIR" || Array.isArray(c);
|
|||
|
var slash = p.slice(-1) === "/";
|
|||
|
|
|||
|
if (isDir && !slash) m += "/";
|
|||
|
else if (!isDir && slash) m = m.slice(0, -1);
|
|||
|
|
|||
|
if (m !== p) {
|
|||
|
var mabs = makeAbs(self, m);
|
|||
|
self.statCache[mabs] = self.statCache[abs];
|
|||
|
self.cache[mabs] = self.cache[abs];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return m;
|
|||
|
}
|
|||
|
|
|||
|
// lotta situps...
|
|||
|
function makeAbs(self, f) {
|
|||
|
var abs = f;
|
|||
|
if (f.charAt(0) === "/") {
|
|||
|
abs = path.join(self.root, f);
|
|||
|
} else if (isAbsolute(f) || f === "") {
|
|||
|
abs = f;
|
|||
|
} else if (self.changedCwd) {
|
|||
|
abs = path.resolve(self.cwd, f);
|
|||
|
} else {
|
|||
|
abs = path.resolve(f);
|
|||
|
}
|
|||
|
return abs;
|
|||
|
}
|
|||
|
|
|||
|
// Return true, if pattern ends with globstar '**', for the accompanying parent directory.
|
|||
|
// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents
|
|||
|
function isIgnored(self, path) {
|
|||
|
if (!self.ignore.length) return false;
|
|||
|
|
|||
|
return self.ignore.some(function (item) {
|
|||
|
return (
|
|||
|
item.matcher.match(path) ||
|
|||
|
!!(item.gmatcher && item.gmatcher.match(path))
|
|||
|
);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
function childrenIgnored(self, path) {
|
|||
|
if (!self.ignore.length) return false;
|
|||
|
|
|||
|
return self.ignore.some(function (item) {
|
|||
|
return !!(item.gmatcher && item.gmatcher.match(path));
|
|||
|
});
|
|||
|
}
|
|||
|
}.call(this, require("_process")));
|
|||
|
},
|
|||
|
{ _process: 24, minimatch: 20, path: 22, "path-is-absolute": 23 },
|
|||
|
],
|
|||
|
16: [
|
|||
|
function (require, module, exports) {
|
|||
|
(function (process) {
|
|||
|
// Approach:
|
|||
|
//
|
|||
|
// 1. Get the minimatch set
|
|||
|
// 2. For each pattern in the set, PROCESS(pattern, false)
|
|||
|
// 3. Store matches per-set, then uniq them
|
|||
|
//
|
|||
|
// PROCESS(pattern, inGlobStar)
|
|||
|
// Get the first [n] items from pattern that are all strings
|
|||
|
// Join these together. This is PREFIX.
|
|||
|
// If there is no more remaining, then stat(PREFIX) and
|
|||
|
// add to matches if it succeeds. END.
|
|||
|
//
|
|||
|
// If inGlobStar and PREFIX is symlink and points to dir
|
|||
|
// set ENTRIES = []
|
|||
|
// else readdir(PREFIX) as ENTRIES
|
|||
|
// If fail, END
|
|||
|
//
|
|||
|
// with ENTRIES
|
|||
|
// If pattern[n] is GLOBSTAR
|
|||
|
// // handle the case where the globstar match is empty
|
|||
|
// // by pruning it out, and testing the resulting pattern
|
|||
|
// PROCESS(pattern[0..n] + pattern[n+1 .. $], false)
|
|||
|
// // handle other cases.
|
|||
|
// for ENTRY in ENTRIES (not dotfiles)
|
|||
|
// // attach globstar + tail onto the entry
|
|||
|
// // Mark that this entry is a globstar match
|
|||
|
// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true)
|
|||
|
//
|
|||
|
// else // not globstar
|
|||
|
// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
|
|||
|
// Test ENTRY against pattern[n]
|
|||
|
// If fails, continue
|
|||
|
// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
|
|||
|
//
|
|||
|
// Caveat:
|
|||
|
// Cache all stats and readdirs results to minimize syscall. Since all
|
|||
|
// we ever care about is existence and directory-ness, we can just keep
|
|||
|
// `true` for files, and [children,...] for directories, or `false` for
|
|||
|
// things that don't exist.
|
|||
|
|
|||
|
module.exports = glob;
|
|||
|
|
|||
|
var fs = require("fs");
|
|||
|
var minimatch = require("minimatch");
|
|||
|
var Minimatch = minimatch.Minimatch;
|
|||
|
var inherits = require("inherits");
|
|||
|
var EE = require("events").EventEmitter;
|
|||
|
var path = require("path");
|
|||
|
var assert = require("assert");
|
|||
|
var isAbsolute = require("path-is-absolute");
|
|||
|
var globSync = require("./sync.js");
|
|||
|
var common = require("./common.js");
|
|||
|
var alphasort = common.alphasort;
|
|||
|
var alphasorti = common.alphasorti;
|
|||
|
var setopts = common.setopts;
|
|||
|
var ownProp = common.ownProp;
|
|||
|
var inflight = require("inflight");
|
|||
|
var util = require("util");
|
|||
|
var childrenIgnored = common.childrenIgnored;
|
|||
|
var isIgnored = common.isIgnored;
|
|||
|
|
|||
|
var once = require("once");
|
|||
|
|
|||
|
function glob(pattern, options, cb) {
|
|||
|
if (typeof options === "function") (cb = options), (options = {});
|
|||
|
if (!options) options = {};
|
|||
|
|
|||
|
if (options.sync) {
|
|||
|
if (cb) throw new TypeError("callback provided to sync glob");
|
|||
|
return globSync(pattern, options);
|
|||
|
}
|
|||
|
|
|||
|
return new Glob(pattern, options, cb);
|
|||
|
}
|
|||
|
|
|||
|
glob.sync = globSync;
|
|||
|
var GlobSync = (glob.GlobSync = globSync.GlobSync);
|
|||
|
|
|||
|
// old api surface
|
|||
|
glob.glob = glob;
|
|||
|
|
|||
|
glob.hasMagic = function (pattern, options_) {
|
|||
|
var options = util._extend({}, options_);
|
|||
|
options.noprocess = true;
|
|||
|
|
|||
|
var g = new Glob(pattern, options);
|
|||
|
var set = g.minimatch.set;
|
|||
|
if (set.length > 1) return true;
|
|||
|
|
|||
|
for (var j = 0; j < set[0].length; j++) {
|
|||
|
if (typeof set[0][j] !== "string") return true;
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
glob.Glob = Glob;
|
|||
|
inherits(Glob, EE);
|
|||
|
function Glob(pattern, options, cb) {
|
|||
|
if (typeof options === "function") {
|
|||
|
cb = options;
|
|||
|
options = null;
|
|||
|
}
|
|||
|
|
|||
|
if (options && options.sync) {
|
|||
|
if (cb) throw new TypeError("callback provided to sync glob");
|
|||
|
return new GlobSync(pattern, options);
|
|||
|
}
|
|||
|
|
|||
|
if (!(this instanceof Glob))
|
|||
|
return new Glob(pattern, options, cb);
|
|||
|
|
|||
|
setopts(this, pattern, options);
|
|||
|
this._didRealPath = false;
|
|||
|
|
|||
|
// process each pattern in the minimatch set
|
|||
|
var n = this.minimatch.set.length;
|
|||
|
|
|||
|
// The matches are stored as {<filename>: true,...} so that
|
|||
|
// duplicates are automagically pruned.
|
|||
|
// Later, we do an Object.keys() on these.
|
|||
|
// Keep them as a list so we can fill in when nonull is set.
|
|||
|
this.matches = new Array(n);
|
|||
|
|
|||
|
if (typeof cb === "function") {
|
|||
|
cb = once(cb);
|
|||
|
this.on("error", cb);
|
|||
|
this.on("end", function (matches) {
|
|||
|
cb(null, matches);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
var self = this;
|
|||
|
var n = this.minimatch.set.length;
|
|||
|
this._processing = 0;
|
|||
|
this.matches = new Array(n);
|
|||
|
|
|||
|
this._emitQueue = [];
|
|||
|
this._processQueue = [];
|
|||
|
this.paused = false;
|
|||
|
|
|||
|
if (this.noprocess) return this;
|
|||
|
|
|||
|
if (n === 0) return done();
|
|||
|
|
|||
|
for (var i = 0; i < n; i++) {
|
|||
|
this._process(this.minimatch.set[i], i, false, done);
|
|||
|
}
|
|||
|
|
|||
|
function done() {
|
|||
|
--self._processing;
|
|||
|
if (self._processing <= 0) self._finish();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Glob.prototype._finish = function () {
|
|||
|
assert(this instanceof Glob);
|
|||
|
if (this.aborted) return;
|
|||
|
|
|||
|
if (this.realpath && !this._didRealpath) return this._realpath();
|
|||
|
|
|||
|
common.finish(this);
|
|||
|
this.emit("end", this.found);
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._realpath = function () {
|
|||
|
if (this._didRealpath) return;
|
|||
|
|
|||
|
this._didRealpath = true;
|
|||
|
|
|||
|
var n = this.matches.length;
|
|||
|
if (n === 0) return this._finish();
|
|||
|
|
|||
|
var self = this;
|
|||
|
for (var i = 0; i < this.matches.length; i++)
|
|||
|
this._realpathSet(i, next);
|
|||
|
|
|||
|
function next() {
|
|||
|
if (--n === 0) self._finish();
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._realpathSet = function (index, cb) {
|
|||
|
var matchset = this.matches[index];
|
|||
|
if (!matchset) return cb();
|
|||
|
|
|||
|
var found = Object.keys(matchset);
|
|||
|
var self = this;
|
|||
|
var n = found.length;
|
|||
|
|
|||
|
if (n === 0) return cb();
|
|||
|
|
|||
|
var set = (this.matches[index] = Object.create(null));
|
|||
|
found.forEach(function (p, i) {
|
|||
|
// If there's a problem with the stat, then it means that
|
|||
|
// one or more of the links in the realpath couldn't be
|
|||
|
// resolved. just return the abs value in that case.
|
|||
|
p = self._makeAbs(p);
|
|||
|
fs.realpath(p, self.realpathCache, function (er, real) {
|
|||
|
if (!er) set[real] = true;
|
|||
|
else if (er.syscall === "stat") set[p] = true;
|
|||
|
else self.emit("error", er); // srsly wtf right here
|
|||
|
|
|||
|
if (--n === 0) {
|
|||
|
self.matches[index] = set;
|
|||
|
cb();
|
|||
|
}
|
|||
|
});
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._mark = function (p) {
|
|||
|
return common.mark(this, p);
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._makeAbs = function (f) {
|
|||
|
return common.makeAbs(this, f);
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype.abort = function () {
|
|||
|
this.aborted = true;
|
|||
|
this.emit("abort");
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype.pause = function () {
|
|||
|
if (!this.paused) {
|
|||
|
this.paused = true;
|
|||
|
this.emit("pause");
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype.resume = function () {
|
|||
|
if (this.paused) {
|
|||
|
this.emit("resume");
|
|||
|
this.paused = false;
|
|||
|
if (this._emitQueue.length) {
|
|||
|
var eq = this._emitQueue.slice(0);
|
|||
|
this._emitQueue.length = 0;
|
|||
|
for (var i = 0; i < eq.length; i++) {
|
|||
|
var e = eq[i];
|
|||
|
this._emitMatch(e[0], e[1]);
|
|||
|
}
|
|||
|
}
|
|||
|
if (this._processQueue.length) {
|
|||
|
var pq = this._processQueue.slice(0);
|
|||
|
this._processQueue.length = 0;
|
|||
|
for (var i = 0; i < pq.length; i++) {
|
|||
|
var p = pq[i];
|
|||
|
this._processing--;
|
|||
|
this._process(p[0], p[1], p[2], p[3]);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._process = function (
|
|||
|
pattern,
|
|||
|
index,
|
|||
|
inGlobStar,
|
|||
|
cb
|
|||
|
) {
|
|||
|
assert(this instanceof Glob);
|
|||
|
assert(typeof cb === "function");
|
|||
|
|
|||
|
if (this.aborted) return;
|
|||
|
|
|||
|
this._processing++;
|
|||
|
if (this.paused) {
|
|||
|
this._processQueue.push([pattern, index, inGlobStar, cb]);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
//console.error('PROCESS %d', this._processing, pattern)
|
|||
|
|
|||
|
// Get the first [n] parts of pattern that are all strings.
|
|||
|
var n = 0;
|
|||
|
while (typeof pattern[n] === "string") {
|
|||
|
n++;
|
|||
|
}
|
|||
|
// now n is the index of the first one that is *not* a string.
|
|||
|
|
|||
|
// see if there's anything else
|
|||
|
var prefix;
|
|||
|
switch (n) {
|
|||
|
// if not, then this is rather simple
|
|||
|
case pattern.length:
|
|||
|
this._processSimple(pattern.join("/"), index, cb);
|
|||
|
return;
|
|||
|
|
|||
|
case 0:
|
|||
|
// pattern *starts* with some non-trivial item.
|
|||
|
// going to readdir(cwd), but not include the prefix in matches.
|
|||
|
prefix = null;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
// pattern has some string bits in the front.
|
|||
|
// whatever it starts with, whether that's 'absolute' like /foo/bar,
|
|||
|
// or 'relative' like '../baz'
|
|||
|
prefix = pattern.slice(0, n).join("/");
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
var remain = pattern.slice(n);
|
|||
|
|
|||
|
// get the list of entries.
|
|||
|
var read;
|
|||
|
if (prefix === null) read = ".";
|
|||
|
else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) {
|
|||
|
if (!prefix || !isAbsolute(prefix)) prefix = "/" + prefix;
|
|||
|
read = prefix;
|
|||
|
} else read = prefix;
|
|||
|
|
|||
|
var abs = this._makeAbs(read);
|
|||
|
|
|||
|
//if ignored, skip _processing
|
|||
|
if (childrenIgnored(this, read)) return cb();
|
|||
|
|
|||
|
var isGlobStar = remain[0] === minimatch.GLOBSTAR;
|
|||
|
if (isGlobStar)
|
|||
|
this._processGlobStar(
|
|||
|
prefix,
|
|||
|
read,
|
|||
|
abs,
|
|||
|
remain,
|
|||
|
index,
|
|||
|
inGlobStar,
|
|||
|
cb
|
|||
|
);
|
|||
|
else
|
|||
|
this._processReaddir(
|
|||
|
prefix,
|
|||
|
read,
|
|||
|
abs,
|
|||
|
remain,
|
|||
|
index,
|
|||
|
inGlobStar,
|
|||
|
cb
|
|||
|
);
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._processReaddir = function (
|
|||
|
prefix,
|
|||
|
read,
|
|||
|
abs,
|
|||
|
remain,
|
|||
|
index,
|
|||
|
inGlobStar,
|
|||
|
cb
|
|||
|
) {
|
|||
|
var self = this;
|
|||
|
this._readdir(abs, inGlobStar, function (er, entries) {
|
|||
|
return self._processReaddir2(
|
|||
|
prefix,
|
|||
|
read,
|
|||
|
abs,
|
|||
|
remain,
|
|||
|
index,
|
|||
|
inGlobStar,
|
|||
|
entries,
|
|||
|
cb
|
|||
|
);
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._processReaddir2 = function (
|
|||
|
prefix,
|
|||
|
read,
|
|||
|
abs,
|
|||
|
remain,
|
|||
|
index,
|
|||
|
inGlobStar,
|
|||
|
entries,
|
|||
|
cb
|
|||
|
) {
|
|||
|
// if the abs isn't a dir, then nothing can match!
|
|||
|
if (!entries) return cb();
|
|||
|
|
|||
|
// It will only match dot entries if it starts with a dot, or if
|
|||
|
// dot is set. Stuff like @(.foo|.bar) isn't allowed.
|
|||
|
var pn = remain[0];
|
|||
|
var negate = !!this.minimatch.negate;
|
|||
|
var rawGlob = pn._glob;
|
|||
|
var dotOk = this.dot || rawGlob.charAt(0) === ".";
|
|||
|
|
|||
|
var matchedEntries = [];
|
|||
|
for (var i = 0; i < entries.length; i++) {
|
|||
|
var e = entries[i];
|
|||
|
if (e.charAt(0) !== "." || dotOk) {
|
|||
|
var m;
|
|||
|
if (negate && !prefix) {
|
|||
|
m = !e.match(pn);
|
|||
|
} else {
|
|||
|
m = e.match(pn);
|
|||
|
}
|
|||
|
if (m) matchedEntries.push(e);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries)
|
|||
|
|
|||
|
var len = matchedEntries.length;
|
|||
|
// If there are no matched entries, then nothing matches.
|
|||
|
if (len === 0) return cb();
|
|||
|
|
|||
|
// if this is the last remaining pattern bit, then no need for
|
|||
|
// an additional stat *unless* the user has specified mark or
|
|||
|
// stat explicitly. We know they exist, since readdir returned
|
|||
|
// them.
|
|||
|
|
|||
|
if (remain.length === 1 && !this.mark && !this.stat) {
|
|||
|
if (!this.matches[index])
|
|||
|
this.matches[index] = Object.create(null);
|
|||
|
|
|||
|
for (var i = 0; i < len; i++) {
|
|||
|
var e = matchedEntries[i];
|
|||
|
if (prefix) {
|
|||
|
if (prefix !== "/") e = prefix + "/" + e;
|
|||
|
else e = prefix + e;
|
|||
|
}
|
|||
|
|
|||
|
if (e.charAt(0) === "/" && !this.nomount) {
|
|||
|
e = path.join(this.root, e);
|
|||
|
}
|
|||
|
this._emitMatch(index, e);
|
|||
|
}
|
|||
|
// This was the last one, and no stats were needed
|
|||
|
return cb();
|
|||
|
}
|
|||
|
|
|||
|
// now test all matched entries as stand-ins for that part
|
|||
|
// of the pattern.
|
|||
|
remain.shift();
|
|||
|
for (var i = 0; i < len; i++) {
|
|||
|
var e = matchedEntries[i];
|
|||
|
var newPattern;
|
|||
|
if (prefix) {
|
|||
|
if (prefix !== "/") e = prefix + "/" + e;
|
|||
|
else e = prefix + e;
|
|||
|
}
|
|||
|
this._process([e].concat(remain), index, inGlobStar, cb);
|
|||
|
}
|
|||
|
cb();
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._emitMatch = function (index, e) {
|
|||
|
if (this.aborted) return;
|
|||
|
|
|||
|
if (this.matches[index][e]) return;
|
|||
|
|
|||
|
if (isIgnored(this, e)) return;
|
|||
|
|
|||
|
if (this.paused) {
|
|||
|
this._emitQueue.push([index, e]);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
var abs = this._makeAbs(e);
|
|||
|
|
|||
|
if (this.nodir) {
|
|||
|
var c = this.cache[abs];
|
|||
|
if (c === "DIR" || Array.isArray(c)) return;
|
|||
|
}
|
|||
|
|
|||
|
if (this.mark) e = this._mark(e);
|
|||
|
|
|||
|
this.matches[index][e] = true;
|
|||
|
|
|||
|
var st = this.statCache[abs];
|
|||
|
if (st) this.emit("stat", e, st);
|
|||
|
|
|||
|
this.emit("match", e);
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._readdirInGlobStar = function (abs, cb) {
|
|||
|
if (this.aborted) return;
|
|||
|
|
|||
|
// follow all symlinked directories forever
|
|||
|
// just proceed as if this is a non-globstar situation
|
|||
|
if (this.follow) return this._readdir(abs, false, cb);
|
|||
|
|
|||
|
var lstatkey = "lstat\0" + abs;
|
|||
|
var self = this;
|
|||
|
var lstatcb = inflight(lstatkey, lstatcb_);
|
|||
|
|
|||
|
if (lstatcb) fs.lstat(abs, lstatcb);
|
|||
|
|
|||
|
function lstatcb_(er, lstat) {
|
|||
|
if (er) return cb();
|
|||
|
|
|||
|
var isSym = lstat.isSymbolicLink();
|
|||
|
self.symlinks[abs] = isSym;
|
|||
|
|
|||
|
// If it's not a symlink or a dir, then it's definitely a regular file.
|
|||
|
// don't bother doing a readdir in that case.
|
|||
|
if (!isSym && !lstat.isDirectory()) {
|
|||
|
self.cache[abs] = "FILE";
|
|||
|
cb();
|
|||
|
} else self._readdir(abs, false, cb);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._readdir = function (abs, inGlobStar, cb) {
|
|||
|
if (this.aborted) return;
|
|||
|
|
|||
|
cb = inflight("readdir\0" + abs + "\0" + inGlobStar, cb);
|
|||
|
if (!cb) return;
|
|||
|
|
|||
|
//console.error('RD %j %j', +inGlobStar, abs)
|
|||
|
if (inGlobStar && !ownProp(this.symlinks, abs))
|
|||
|
return this._readdirInGlobStar(abs, cb);
|
|||
|
|
|||
|
if (ownProp(this.cache, abs)) {
|
|||
|
var c = this.cache[abs];
|
|||
|
if (!c || c === "FILE") return cb();
|
|||
|
|
|||
|
if (Array.isArray(c)) return cb(null, c);
|
|||
|
}
|
|||
|
|
|||
|
var self = this;
|
|||
|
fs.readdir(abs, readdirCb(this, abs, cb));
|
|||
|
};
|
|||
|
|
|||
|
function readdirCb(self, abs, cb) {
|
|||
|
return function (er, entries) {
|
|||
|
if (er) self._readdirError(abs, er, cb);
|
|||
|
else self._readdirEntries(abs, entries, cb);
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
Glob.prototype._readdirEntries = function (abs, entries, cb) {
|
|||
|
if (this.aborted) return;
|
|||
|
|
|||
|
// if we haven't asked to stat everything, then just
|
|||
|
// assume that everything in there exists, so we can avoid
|
|||
|
// having to stat it a second time.
|
|||
|
if (!this.mark && !this.stat) {
|
|||
|
for (var i = 0; i < entries.length; i++) {
|
|||
|
var e = entries[i];
|
|||
|
if (abs === "/") e = abs + e;
|
|||
|
else e = abs + "/" + e;
|
|||
|
this.cache[e] = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
this.cache[abs] = entries;
|
|||
|
return cb(null, entries);
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._readdirError = function (f, er, cb) {
|
|||
|
if (this.aborted) return;
|
|||
|
|
|||
|
// handle errors, and cache the information
|
|||
|
switch (er.code) {
|
|||
|
case "ENOTSUP": // https://github.com/isaacs/node-glob/issues/205
|
|||
|
case "ENOTDIR": // totally normal. means it *does* exist.
|
|||
|
this.cache[this._makeAbs(f)] = "FILE";
|
|||
|
break;
|
|||
|
|
|||
|
case "ENOENT": // not terribly unusual
|
|||
|
case "ELOOP":
|
|||
|
case "ENAMETOOLONG":
|
|||
|
case "UNKNOWN":
|
|||
|
this.cache[this._makeAbs(f)] = false;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
// some unusual error. Treat as failure.
|
|||
|
this.cache[this._makeAbs(f)] = false;
|
|||
|
if (this.strict) {
|
|||
|
this.emit("error", er);
|
|||
|
// If the error is handled, then we abort
|
|||
|
// if not, we threw out of here
|
|||
|
this.abort();
|
|||
|
}
|
|||
|
if (!this.silent) console.error("glob error", er);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return cb();
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._processGlobStar = function (
|
|||
|
prefix,
|
|||
|
read,
|
|||
|
abs,
|
|||
|
remain,
|
|||
|
index,
|
|||
|
inGlobStar,
|
|||
|
cb
|
|||
|
) {
|
|||
|
var self = this;
|
|||
|
this._readdir(abs, inGlobStar, function (er, entries) {
|
|||
|
self._processGlobStar2(
|
|||
|
prefix,
|
|||
|
read,
|
|||
|
abs,
|
|||
|
remain,
|
|||
|
index,
|
|||
|
inGlobStar,
|
|||
|
entries,
|
|||
|
cb
|
|||
|
);
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._processGlobStar2 = function (
|
|||
|
prefix,
|
|||
|
read,
|
|||
|
abs,
|
|||
|
remain,
|
|||
|
index,
|
|||
|
inGlobStar,
|
|||
|
entries,
|
|||
|
cb
|
|||
|
) {
|
|||
|
//console.error('pgs2', prefix, remain[0], entries)
|
|||
|
|
|||
|
// no entries means not a dir, so it can never have matches
|
|||
|
// foo.txt/** doesn't match foo.txt
|
|||
|
if (!entries) return cb();
|
|||
|
|
|||
|
// test without the globstar, and with every child both below
|
|||
|
// and replacing the globstar.
|
|||
|
var remainWithoutGlobStar = remain.slice(1);
|
|||
|
var gspref = prefix ? [prefix] : [];
|
|||
|
var noGlobStar = gspref.concat(remainWithoutGlobStar);
|
|||
|
|
|||
|
// the noGlobStar pattern exits the inGlobStar state
|
|||
|
this._process(noGlobStar, index, false, cb);
|
|||
|
|
|||
|
var isSym = this.symlinks[abs];
|
|||
|
var len = entries.length;
|
|||
|
|
|||
|
// If it's a symlink, and we're in a globstar, then stop
|
|||
|
if (isSym && inGlobStar) return cb();
|
|||
|
|
|||
|
for (var i = 0; i < len; i++) {
|
|||
|
var e = entries[i];
|
|||
|
if (e.charAt(0) === "." && !this.dot) continue;
|
|||
|
|
|||
|
// these two cases enter the inGlobStar state
|
|||
|
var instead = gspref.concat(entries[i], remainWithoutGlobStar);
|
|||
|
this._process(instead, index, true, cb);
|
|||
|
|
|||
|
var below = gspref.concat(entries[i], remain);
|
|||
|
this._process(below, index, true, cb);
|
|||
|
}
|
|||
|
|
|||
|
cb();
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._processSimple = function (prefix, index, cb) {
|
|||
|
// XXX review this. Shouldn't it be doing the mounting etc
|
|||
|
// before doing stat? kinda weird?
|
|||
|
var self = this;
|
|||
|
this._stat(prefix, function (er, exists) {
|
|||
|
self._processSimple2(prefix, index, er, exists, cb);
|
|||
|
});
|
|||
|
};
|
|||
|
Glob.prototype._processSimple2 = function (
|
|||
|
prefix,
|
|||
|
index,
|
|||
|
er,
|
|||
|
exists,
|
|||
|
cb
|
|||
|
) {
|
|||
|
//console.error('ps2', prefix, exists)
|
|||
|
|
|||
|
if (!this.matches[index])
|
|||
|
this.matches[index] = Object.create(null);
|
|||
|
|
|||
|
// If it doesn't exist, then just mark the lack of results
|
|||
|
if (!exists) return cb();
|
|||
|
|
|||
|
if (prefix && isAbsolute(prefix) && !this.nomount) {
|
|||
|
var trail = /[\/\\]$/.test(prefix);
|
|||
|
if (prefix.charAt(0) === "/") {
|
|||
|
prefix = path.join(this.root, prefix);
|
|||
|
} else {
|
|||
|
prefix = path.resolve(this.root, prefix);
|
|||
|
if (trail) prefix += "/";
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (process.platform === "win32")
|
|||
|
prefix = prefix.replace(/\\/g, "/");
|
|||
|
|
|||
|
// Mark this as a match
|
|||
|
this._emitMatch(index, prefix);
|
|||
|
cb();
|
|||
|
};
|
|||
|
|
|||
|
// Returns either 'DIR', 'FILE', or false
|
|||
|
Glob.prototype._stat = function (f, cb) {
|
|||
|
var abs = this._makeAbs(f);
|
|||
|
var needDir = f.slice(-1) === "/";
|
|||
|
|
|||
|
if (f.length > this.maxLength) return cb();
|
|||
|
|
|||
|
if (!this.stat && ownProp(this.cache, abs)) {
|
|||
|
var c = this.cache[abs];
|
|||
|
|
|||
|
if (Array.isArray(c)) c = "DIR";
|
|||
|
|
|||
|
// It exists, but maybe not how we need it
|
|||
|
if (!needDir || c === "DIR") return cb(null, c);
|
|||
|
|
|||
|
if (needDir && c === "FILE") return cb();
|
|||
|
|
|||
|
// otherwise we have to stat, because maybe c=true
|
|||
|
// if we know it exists, but not what it is.
|
|||
|
}
|
|||
|
|
|||
|
var exists;
|
|||
|
var stat = this.statCache[abs];
|
|||
|
if (stat !== undefined) {
|
|||
|
if (stat === false) return cb(null, stat);
|
|||
|
else {
|
|||
|
var type = stat.isDirectory() ? "DIR" : "FILE";
|
|||
|
if (needDir && type === "FILE") return cb();
|
|||
|
else return cb(null, type, stat);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var self = this;
|
|||
|
var statcb = inflight("stat\0" + abs, lstatcb_);
|
|||
|
if (statcb) fs.lstat(abs, statcb);
|
|||
|
|
|||
|
function lstatcb_(er, lstat) {
|
|||
|
if (lstat && lstat.isSymbolicLink()) {
|
|||
|
// If it's a symlink, then treat it as the target, unless
|
|||
|
// the target does not exist, then treat it as a file.
|
|||
|
return fs.stat(abs, function (er, stat) {
|
|||
|
if (er) self._stat2(f, abs, null, lstat, cb);
|
|||
|
else self._stat2(f, abs, er, stat, cb);
|
|||
|
});
|
|||
|
} else {
|
|||
|
self._stat2(f, abs, er, lstat, cb);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Glob.prototype._stat2 = function (f, abs, er, stat, cb) {
|
|||
|
if (er) {
|
|||
|
this.statCache[abs] = false;
|
|||
|
return cb();
|
|||
|
}
|
|||
|
|
|||
|
var needDir = f.slice(-1) === "/";
|
|||
|
this.statCache[abs] = stat;
|
|||
|
|
|||
|
if (abs.slice(-1) === "/" && !stat.isDirectory())
|
|||
|
return cb(null, false, stat);
|
|||
|
|
|||
|
var c = stat.isDirectory() ? "DIR" : "FILE";
|
|||
|
this.cache[abs] = this.cache[abs] || c;
|
|||
|
|
|||
|
if (needDir && c !== "DIR") return cb();
|
|||
|
|
|||
|
return cb(null, c, stat);
|
|||
|
};
|
|||
|
}.call(this, require("_process")));
|
|||
|
},
|
|||
|
{
|
|||
|
"./common.js": 15,
|
|||
|
"./sync.js": 17,
|
|||
|
_process: 24,
|
|||
|
assert: 9,
|
|||
|
events: 14,
|
|||
|
fs: 12,
|
|||
|
inflight: 18,
|
|||
|
inherits: 19,
|
|||
|
minimatch: 20,
|
|||
|
once: 21,
|
|||
|
path: 22,
|
|||
|
"path-is-absolute": 23,
|
|||
|
util: 28,
|
|||
|
},
|
|||
|
],
|
|||
|
17: [
|
|||
|
function (require, module, exports) {
|
|||
|
(function (process) {
|
|||
|
module.exports = globSync;
|
|||
|
globSync.GlobSync = GlobSync;
|
|||
|
|
|||
|
var fs = require("fs");
|
|||
|
var minimatch = require("minimatch");
|
|||
|
var Minimatch = minimatch.Minimatch;
|
|||
|
var Glob = require("./glob.js").Glob;
|
|||
|
var util = require("util");
|
|||
|
var path = require("path");
|
|||
|
var assert = require("assert");
|
|||
|
var isAbsolute = require("path-is-absolute");
|
|||
|
var common = require("./common.js");
|
|||
|
var alphasort = common.alphasort;
|
|||
|
var alphasorti = common.alphasorti;
|
|||
|
var setopts = common.setopts;
|
|||
|
var ownProp = common.ownProp;
|
|||
|
var childrenIgnored = common.childrenIgnored;
|
|||
|
|
|||
|
function globSync(pattern, options) {
|
|||
|
if (typeof options === "function" || arguments.length === 3)
|
|||
|
throw new TypeError(
|
|||
|
"callback provided to sync glob\n" +
|
|||
|
"See: https://github.com/isaacs/node-glob/issues/167"
|
|||
|
);
|
|||
|
|
|||
|
return new GlobSync(pattern, options).found;
|
|||
|
}
|
|||
|
|
|||
|
function GlobSync(pattern, options) {
|
|||
|
if (!pattern) throw new Error("must provide pattern");
|
|||
|
|
|||
|
if (typeof options === "function" || arguments.length === 3)
|
|||
|
throw new TypeError(
|
|||
|
"callback provided to sync glob\n" +
|
|||
|
"See: https://github.com/isaacs/node-glob/issues/167"
|
|||
|
);
|
|||
|
|
|||
|
if (!(this instanceof GlobSync))
|
|||
|
return new GlobSync(pattern, options);
|
|||
|
|
|||
|
setopts(this, pattern, options);
|
|||
|
|
|||
|
if (this.noprocess) return this;
|
|||
|
|
|||
|
var n = this.minimatch.set.length;
|
|||
|
this.matches = new Array(n);
|
|||
|
for (var i = 0; i < n; i++) {
|
|||
|
this._process(this.minimatch.set[i], i, false);
|
|||
|
}
|
|||
|
this._finish();
|
|||
|
}
|
|||
|
|
|||
|
GlobSync.prototype._finish = function () {
|
|||
|
assert(this instanceof GlobSync);
|
|||
|
if (this.realpath) {
|
|||
|
var self = this;
|
|||
|
this.matches.forEach(function (matchset, index) {
|
|||
|
var set = (self.matches[index] = Object.create(null));
|
|||
|
for (var p in matchset) {
|
|||
|
try {
|
|||
|
p = self._makeAbs(p);
|
|||
|
var real = fs.realpathSync(p, self.realpathCache);
|
|||
|
set[real] = true;
|
|||
|
} catch (er) {
|
|||
|
if (er.syscall === "stat") set[self._makeAbs(p)] = true;
|
|||
|
else throw er;
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
common.finish(this);
|
|||
|
};
|
|||
|
|
|||
|
GlobSync.prototype._process = function (
|
|||
|
pattern,
|
|||
|
index,
|
|||
|
inGlobStar
|
|||
|
) {
|
|||
|
assert(this instanceof GlobSync);
|
|||
|
|
|||
|
// Get the first [n] parts of pattern that are all strings.
|
|||
|
var n = 0;
|
|||
|
while (typeof pattern[n] === "string") {
|
|||
|
n++;
|
|||
|
}
|
|||
|
// now n is the index of the first one that is *not* a string.
|
|||
|
|
|||
|
// See if there's anything else
|
|||
|
var prefix;
|
|||
|
switch (n) {
|
|||
|
// if not, then this is rather simple
|
|||
|
case pattern.length:
|
|||
|
this._processSimple(pattern.join("/"), index);
|
|||
|
return;
|
|||
|
|
|||
|
case 0:
|
|||
|
// pattern *starts* with some non-trivial item.
|
|||
|
// going to readdir(cwd), but not include the prefix in matches.
|
|||
|
prefix = null;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
// pattern has some string bits in the front.
|
|||
|
// whatever it starts with, whether that's 'absolute' like /foo/bar,
|
|||
|
// or 'relative' like '../baz'
|
|||
|
prefix = pattern.slice(0, n).join("/");
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
var remain = pattern.slice(n);
|
|||
|
|
|||
|
// get the list of entries.
|
|||
|
var read;
|
|||
|
if (prefix === null) read = ".";
|
|||
|
else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) {
|
|||
|
if (!prefix || !isAbsolute(prefix)) prefix = "/" + prefix;
|
|||
|
read = prefix;
|
|||
|
} else read = prefix;
|
|||
|
|
|||
|
var abs = this._makeAbs(read);
|
|||
|
|
|||
|
//if ignored, skip processing
|
|||
|
if (childrenIgnored(this, read)) return;
|
|||
|
|
|||
|
var isGlobStar = remain[0] === minimatch.GLOBSTAR;
|
|||
|
if (isGlobStar)
|
|||
|
this._processGlobStar(
|
|||
|
prefix,
|
|||
|
read,
|
|||
|
abs,
|
|||
|
remain,
|
|||
|
index,
|
|||
|
inGlobStar
|
|||
|
);
|
|||
|
else
|
|||
|
this._processReaddir(
|
|||
|
prefix,
|
|||
|
read,
|
|||
|
abs,
|
|||
|
remain,
|
|||
|
index,
|
|||
|
inGlobStar
|
|||
|
);
|
|||
|
};
|
|||
|
|
|||
|
GlobSync.prototype._processReaddir = function (
|
|||
|
prefix,
|
|||
|
read,
|
|||
|
abs,
|
|||
|
remain,
|
|||
|
index,
|
|||
|
inGlobStar
|
|||
|
) {
|
|||
|
var entries = this._readdir(abs, inGlobStar);
|
|||
|
|
|||
|
// if the abs isn't a dir, then nothing can match!
|
|||
|
if (!entries) return;
|
|||
|
|
|||
|
// It will only match dot entries if it starts with a dot, or if
|
|||
|
// dot is set. Stuff like @(.foo|.bar) isn't allowed.
|
|||
|
var pn = remain[0];
|
|||
|
var negate = !!this.minimatch.negate;
|
|||
|
var rawGlob = pn._glob;
|
|||
|
var dotOk = this.dot || rawGlob.charAt(0) === ".";
|
|||
|
|
|||
|
var matchedEntries = [];
|
|||
|
for (var i = 0; i < entries.length; i++) {
|
|||
|
var e = entries[i];
|
|||
|
if (e.charAt(0) !== "." || dotOk) {
|
|||
|
var m;
|
|||
|
if (negate && !prefix) {
|
|||
|
m = !e.match(pn);
|
|||
|
} else {
|
|||
|
m = e.match(pn);
|
|||
|
}
|
|||
|
if (m) matchedEntries.push(e);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var len = matchedEntries.length;
|
|||
|
// If there are no matched entries, then nothing matches.
|
|||
|
if (len === 0) return;
|
|||
|
|
|||
|
// if this is the last remaining pattern bit, then no need for
|
|||
|
// an additional stat *unless* the user has specified mark or
|
|||
|
// stat explicitly. We know they exist, since readdir returned
|
|||
|
// them.
|
|||
|
|
|||
|
if (remain.length === 1 && !this.mark && !this.stat) {
|
|||
|
if (!this.matches[index])
|
|||
|
this.matches[index] = Object.create(null);
|
|||
|
|
|||
|
for (var i = 0; i < len; i++) {
|
|||
|
var e = matchedEntries[i];
|
|||
|
if (prefix) {
|
|||
|
if (prefix.slice(-1) !== "/") e = prefix + "/" + e;
|
|||
|
else e = prefix + e;
|
|||
|
}
|
|||
|
|
|||
|
if (e.charAt(0) === "/" && !this.nomount) {
|
|||
|
e = path.join(this.root, e);
|
|||
|
}
|
|||
|
this.matches[index][e] = true;
|
|||
|
}
|
|||
|
// This was the last one, and no stats were needed
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// now test all matched entries as stand-ins for that part
|
|||
|
// of the pattern.
|
|||
|
remain.shift();
|
|||
|
for (var i = 0; i < len; i++) {
|
|||
|
var e = matchedEntries[i];
|
|||
|
var newPattern;
|
|||
|
if (prefix) newPattern = [prefix, e];
|
|||
|
else newPattern = [e];
|
|||
|
this._process(newPattern.concat(remain), index, inGlobStar);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
GlobSync.prototype._emitMatch = function (index, e) {
|
|||
|
var abs = this._makeAbs(e);
|
|||
|
if (this.mark) e = this._mark(e);
|
|||
|
|
|||
|
if (this.matches[index][e]) return;
|
|||
|
|
|||
|
if (this.nodir) {
|
|||
|
var c = this.cache[this._makeAbs(e)];
|
|||
|
if (c === "DIR" || Array.isArray(c)) return;
|
|||
|
}
|
|||
|
|
|||
|
this.matches[index][e] = true;
|
|||
|
if (this.stat) this._stat(e);
|
|||
|
};
|
|||
|
|
|||
|
GlobSync.prototype._readdirInGlobStar = function (abs) {
|
|||
|
// follow all symlinked directories forever
|
|||
|
// just proceed as if this is a non-globstar situation
|
|||
|
if (this.follow) return this._readdir(abs, false);
|
|||
|
|
|||
|
var entries;
|
|||
|
var lstat;
|
|||
|
var stat;
|
|||
|
try {
|
|||
|
lstat = fs.lstatSync(abs);
|
|||
|
} catch (er) {
|
|||
|
// lstat failed, doesn't exist
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
var isSym = lstat.isSymbolicLink();
|
|||
|
this.symlinks[abs] = isSym;
|
|||
|
|
|||
|
// If it's not a symlink or a dir, then it's definitely a regular file.
|
|||
|
// don't bother doing a readdir in that case.
|
|||
|
if (!isSym && !lstat.isDirectory()) this.cache[abs] = "FILE";
|
|||
|
else entries = this._readdir(abs, false);
|
|||
|
|
|||
|
return entries;
|
|||
|
};
|
|||
|
|
|||
|
GlobSync.prototype._readdir = function (abs, inGlobStar) {
|
|||
|
var entries;
|
|||
|
|
|||
|
if (inGlobStar && !ownProp(this.symlinks, abs))
|
|||
|
return this._readdirInGlobStar(abs);
|
|||
|
|
|||
|
if (ownProp(this.cache, abs)) {
|
|||
|
var c = this.cache[abs];
|
|||
|
if (!c || c === "FILE") return null;
|
|||
|
|
|||
|
if (Array.isArray(c)) return c;
|
|||
|
}
|
|||
|
|
|||
|
try {
|
|||
|
return this._readdirEntries(abs, fs.readdirSync(abs));
|
|||
|
} catch (er) {
|
|||
|
this._readdirError(abs, er);
|
|||
|
return null;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
GlobSync.prototype._readdirEntries = function (abs, entries) {
|
|||
|
// if we haven't asked to stat everything, then just
|
|||
|
// assume that everything in there exists, so we can avoid
|
|||
|
// having to stat it a second time.
|
|||
|
if (!this.mark && !this.stat) {
|
|||
|
for (var i = 0; i < entries.length; i++) {
|
|||
|
var e = entries[i];
|
|||
|
if (abs === "/") e = abs + e;
|
|||
|
else e = abs + "/" + e;
|
|||
|
this.cache[e] = true;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
this.cache[abs] = entries;
|
|||
|
|
|||
|
// mark and cache dir-ness
|
|||
|
return entries;
|
|||
|
};
|
|||
|
|
|||
|
GlobSync.prototype._readdirError = function (f, er) {
|
|||
|
// handle errors, and cache the information
|
|||
|
switch (er.code) {
|
|||
|
case "ENOTSUP": // https://github.com/isaacs/node-glob/issues/205
|
|||
|
case "ENOTDIR": // totally normal. means it *does* exist.
|
|||
|
this.cache[this._makeAbs(f)] = "FILE";
|
|||
|
break;
|
|||
|
|
|||
|
case "ENOENT": // not terribly unusual
|
|||
|
case "ELOOP":
|
|||
|
case "ENAMETOOLONG":
|
|||
|
case "UNKNOWN":
|
|||
|
this.cache[this._makeAbs(f)] = false;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
// some unusual error. Treat as failure.
|
|||
|
this.cache[this._makeAbs(f)] = false;
|
|||
|
if (this.strict) throw er;
|
|||
|
if (!this.silent) console.error("glob error", er);
|
|||
|
break;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
GlobSync.prototype._processGlobStar = function (
|
|||
|
prefix,
|
|||
|
read,
|
|||
|
abs,
|
|||
|
remain,
|
|||
|
index,
|
|||
|
inGlobStar
|
|||
|
) {
|
|||
|
var entries = this._readdir(abs, inGlobStar);
|
|||
|
|
|||
|
// no entries means not a dir, so it can never have matches
|
|||
|
// foo.txt/** doesn't match foo.txt
|
|||
|
if (!entries) return;
|
|||
|
|
|||
|
// test without the globstar, and with every child both below
|
|||
|
// and replacing the globstar.
|
|||
|
var remainWithoutGlobStar = remain.slice(1);
|
|||
|
var gspref = prefix ? [prefix] : [];
|
|||
|
var noGlobStar = gspref.concat(remainWithoutGlobStar);
|
|||
|
|
|||
|
// the noGlobStar pattern exits the inGlobStar state
|
|||
|
this._process(noGlobStar, index, false);
|
|||
|
|
|||
|
var len = entries.length;
|
|||
|
var isSym = this.symlinks[abs];
|
|||
|
|
|||
|
// If it's a symlink, and we're in a globstar, then stop
|
|||
|
if (isSym && inGlobStar) return;
|
|||
|
|
|||
|
for (var i = 0; i < len; i++) {
|
|||
|
var e = entries[i];
|
|||
|
if (e.charAt(0) === "." && !this.dot) continue;
|
|||
|
|
|||
|
// these two cases enter the inGlobStar state
|
|||
|
var instead = gspref.concat(entries[i], remainWithoutGlobStar);
|
|||
|
this._process(instead, index, true);
|
|||
|
|
|||
|
var below = gspref.concat(entries[i], remain);
|
|||
|
this._process(below, index, true);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
GlobSync.prototype._processSimple = function (prefix, index) {
|
|||
|
// XXX review this. Shouldn't it be doing the mounting etc
|
|||
|
// before doing stat? kinda weird?
|
|||
|
var exists = this._stat(prefix);
|
|||
|
|
|||
|
if (!this.matches[index])
|
|||
|
this.matches[index] = Object.create(null);
|
|||
|
|
|||
|
// If it doesn't exist, then just mark the lack of results
|
|||
|
if (!exists) return;
|
|||
|
|
|||
|
if (prefix && isAbsolute(prefix) && !this.nomount) {
|
|||
|
var trail = /[\/\\]$/.test(prefix);
|
|||
|
if (prefix.charAt(0) === "/") {
|
|||
|
prefix = path.join(this.root, prefix);
|
|||
|
} else {
|
|||
|
prefix = path.resolve(this.root, prefix);
|
|||
|
if (trail) prefix += "/";
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (process.platform === "win32")
|
|||
|
prefix = prefix.replace(/\\/g, "/");
|
|||
|
|
|||
|
// Mark this as a match
|
|||
|
this.matches[index][prefix] = true;
|
|||
|
};
|
|||
|
|
|||
|
// Returns either 'DIR', 'FILE', or false
|
|||
|
GlobSync.prototype._stat = function (f) {
|
|||
|
var abs = this._makeAbs(f);
|
|||
|
var needDir = f.slice(-1) === "/";
|
|||
|
|
|||
|
if (f.length > this.maxLength) return false;
|
|||
|
|
|||
|
if (!this.stat && ownProp(this.cache, abs)) {
|
|||
|
var c = this.cache[abs];
|
|||
|
|
|||
|
if (Array.isArray(c)) c = "DIR";
|
|||
|
|
|||
|
// It exists, but maybe not how we need it
|
|||
|
if (!needDir || c === "DIR") return c;
|
|||
|
|
|||
|
if (needDir && c === "FILE") return false;
|
|||
|
|
|||
|
// otherwise we have to stat, because maybe c=true
|
|||
|
// if we know it exists, but not what it is.
|
|||
|
}
|
|||
|
|
|||
|
var exists;
|
|||
|
var stat = this.statCache[abs];
|
|||
|
if (!stat) {
|
|||
|
var lstat;
|
|||
|
try {
|
|||
|
lstat = fs.lstatSync(abs);
|
|||
|
} catch (er) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
if (lstat.isSymbolicLink()) {
|
|||
|
try {
|
|||
|
stat = fs.statSync(abs);
|
|||
|
} catch (er) {
|
|||
|
stat = lstat;
|
|||
|
}
|
|||
|
} else {
|
|||
|
stat = lstat;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
this.statCache[abs] = stat;
|
|||
|
|
|||
|
var c = stat.isDirectory() ? "DIR" : "FILE";
|
|||
|
this.cache[abs] = this.cache[abs] || c;
|
|||
|
|
|||
|
if (needDir && c !== "DIR") return false;
|
|||
|
|
|||
|
return c;
|
|||
|
};
|
|||
|
|
|||
|
GlobSync.prototype._mark = function (p) {
|
|||
|
return common.mark(this, p);
|
|||
|
};
|
|||
|
|
|||
|
GlobSync.prototype._makeAbs = function (f) {
|
|||
|
return common.makeAbs(this, f);
|
|||
|
};
|
|||
|
}.call(this, require("_process")));
|
|||
|
},
|
|||
|
{
|
|||
|
"./common.js": 15,
|
|||
|
"./glob.js": 16,
|
|||
|
_process: 24,
|
|||
|
assert: 9,
|
|||
|
fs: 12,
|
|||
|
minimatch: 20,
|
|||
|
path: 22,
|
|||
|
"path-is-absolute": 23,
|
|||
|
util: 28,
|
|||
|
},
|
|||
|
],
|
|||
|
18: [
|
|||
|
function (require, module, exports) {
|
|||
|
(function (process) {
|
|||
|
var wrappy = require("wrappy");
|
|||
|
var reqs = Object.create(null);
|
|||
|
var once = require("once");
|
|||
|
|
|||
|
module.exports = wrappy(inflight);
|
|||
|
|
|||
|
function inflight(key, cb) {
|
|||
|
if (reqs[key]) {
|
|||
|
reqs[key].push(cb);
|
|||
|
return null;
|
|||
|
} else {
|
|||
|
reqs[key] = [cb];
|
|||
|
return makeres(key);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function makeres(key) {
|
|||
|
return once(function RES() {
|
|||
|
var cbs = reqs[key];
|
|||
|
var len = cbs.length;
|
|||
|
var args = slice(arguments);
|
|||
|
|
|||
|
// XXX It's somewhat ambiguous whether a new callback added in this
|
|||
|
// pass should be queued for later execution if something in the
|
|||
|
// list of callbacks throws, or if it should just be discarded.
|
|||
|
// However, it's such an edge case that it hardly matters, and either
|
|||
|
// choice is likely as surprising as the other.
|
|||
|
// As it happens, we do go ahead and schedule it for later execution.
|
|||
|
try {
|
|||
|
for (var i = 0; i < len; i++) {
|
|||
|
cbs[i].apply(null, args);
|
|||
|
}
|
|||
|
} finally {
|
|||
|
if (cbs.length > len) {
|
|||
|
// added more in the interim.
|
|||
|
// de-zalgo, just in case, but don't call again.
|
|||
|
cbs.splice(0, len);
|
|||
|
process.nextTick(function () {
|
|||
|
RES.apply(null, args);
|
|||
|
});
|
|||
|
} else {
|
|||
|
delete reqs[key];
|
|||
|
}
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
function slice(args) {
|
|||
|
var length = args.length;
|
|||
|
var array = [];
|
|||
|
|
|||
|
for (var i = 0; i < length; i++) array[i] = args[i];
|
|||
|
return array;
|
|||
|
}
|
|||
|
}.call(this, require("_process")));
|
|||
|
},
|
|||
|
{ _process: 24, once: 21, wrappy: 29 },
|
|||
|
],
|
|||
|
19: [
|
|||
|
function (require, module, exports) {
|
|||
|
if (typeof Object.create === "function") {
|
|||
|
// implementation from standard node.js 'util' module
|
|||
|
module.exports = function inherits(ctor, superCtor) {
|
|||
|
ctor.super_ = superCtor;
|
|||
|
ctor.prototype = Object.create(superCtor.prototype, {
|
|||
|
constructor: {
|
|||
|
value: ctor,
|
|||
|
enumerable: false,
|
|||
|
writable: true,
|
|||
|
configurable: true,
|
|||
|
},
|
|||
|
});
|
|||
|
};
|
|||
|
} else {
|
|||
|
// old school shim for old browsers
|
|||
|
module.exports = function inherits(ctor, superCtor) {
|
|||
|
ctor.super_ = superCtor;
|
|||
|
var TempCtor = function () {};
|
|||
|
TempCtor.prototype = superCtor.prototype;
|
|||
|
ctor.prototype = new TempCtor();
|
|||
|
ctor.prototype.constructor = ctor;
|
|||
|
};
|
|||
|
}
|
|||
|
},
|
|||
|
{},
|
|||
|
],
|
|||
|
20: [
|
|||
|
function (require, module, exports) {
|
|||
|
module.exports = minimatch;
|
|||
|
minimatch.Minimatch = Minimatch;
|
|||
|
|
|||
|
var path = { sep: "/" };
|
|||
|
try {
|
|||
|
path = require("path");
|
|||
|
} catch (er) {}
|
|||
|
|
|||
|
var GLOBSTAR = (minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {});
|
|||
|
var expand = require("brace-expansion");
|
|||
|
|
|||
|
var plTypes = {
|
|||
|
"!": { open: "(?:(?!(?:", close: "))[^/]*?)" },
|
|||
|
"?": { open: "(?:", close: ")?" },
|
|||
|
"+": { open: "(?:", close: ")+" },
|
|||
|
"*": { open: "(?:", close: ")*" },
|
|||
|
"@": { open: "(?:", close: ")" },
|
|||
|
};
|
|||
|
|
|||
|
// any single thing other than /
|
|||
|
// don't need to escape / when using new RegExp()
|
|||
|
var qmark = "[^/]";
|
|||
|
|
|||
|
// * => any number of characters
|
|||
|
var star = qmark + "*?";
|
|||
|
|
|||
|
// ** when dots are allowed. Anything goes, except .. and .
|
|||
|
// not (^ or / followed by one or two dots followed by $ or /),
|
|||
|
// followed by anything, any number of times.
|
|||
|
var twoStarDot = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?";
|
|||
|
|
|||
|
// not a ^ or / followed by a dot,
|
|||
|
// followed by anything, any number of times.
|
|||
|
var twoStarNoDot = "(?:(?!(?:\\/|^)\\.).)*?";
|
|||
|
|
|||
|
// characters that need to be escaped in RegExp.
|
|||
|
var reSpecials = charSet("().*{}+?[]^$\\!");
|
|||
|
|
|||
|
// "abc" -> { a:true, b:true, c:true }
|
|||
|
function charSet(s) {
|
|||
|
return s.split("").reduce(function (set, c) {
|
|||
|
set[c] = true;
|
|||
|
return set;
|
|||
|
}, {});
|
|||
|
}
|
|||
|
|
|||
|
// normalizes slashes.
|
|||
|
var slashSplit = /\/+/;
|
|||
|
|
|||
|
minimatch.filter = filter;
|
|||
|
function filter(pattern, options) {
|
|||
|
options = options || {};
|
|||
|
return function (p, i, list) {
|
|||
|
return minimatch(p, pattern, options);
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
function ext(a, b) {
|
|||
|
a = a || {};
|
|||
|
b = b || {};
|
|||
|
var t = {};
|
|||
|
Object.keys(b).forEach(function (k) {
|
|||
|
t[k] = b[k];
|
|||
|
});
|
|||
|
Object.keys(a).forEach(function (k) {
|
|||
|
t[k] = a[k];
|
|||
|
});
|
|||
|
return t;
|
|||
|
}
|
|||
|
|
|||
|
minimatch.defaults = function (def) {
|
|||
|
if (!def || !Object.keys(def).length) return minimatch;
|
|||
|
|
|||
|
var orig = minimatch;
|
|||
|
|
|||
|
var m = function minimatch(p, pattern, options) {
|
|||
|
return orig.minimatch(p, pattern, ext(def, options));
|
|||
|
};
|
|||
|
|
|||
|
m.Minimatch = function Minimatch(pattern, options) {
|
|||
|
return new orig.Minimatch(pattern, ext(def, options));
|
|||
|
};
|
|||
|
|
|||
|
return m;
|
|||
|
};
|
|||
|
|
|||
|
Minimatch.defaults = function (def) {
|
|||
|
if (!def || !Object.keys(def).length) return Minimatch;
|
|||
|
return minimatch.defaults(def).Minimatch;
|
|||
|
};
|
|||
|
|
|||
|
function minimatch(p, pattern, options) {
|
|||
|
if (typeof pattern !== "string") {
|
|||
|
throw new TypeError("glob pattern string required");
|
|||
|
}
|
|||
|
|
|||
|
if (!options) options = {};
|
|||
|
|
|||
|
// shortcut: comments match nothing.
|
|||
|
if (!options.nocomment && pattern.charAt(0) === "#") {
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// "" only matches ""
|
|||
|
if (pattern.trim() === "") return p === "";
|
|||
|
|
|||
|
return new Minimatch(pattern, options).match(p);
|
|||
|
}
|
|||
|
|
|||
|
function Minimatch(pattern, options) {
|
|||
|
if (!(this instanceof Minimatch)) {
|
|||
|
return new Minimatch(pattern, options);
|
|||
|
}
|
|||
|
|
|||
|
if (typeof pattern !== "string") {
|
|||
|
throw new TypeError("glob pattern string required");
|
|||
|
}
|
|||
|
|
|||
|
if (!options) options = {};
|
|||
|
pattern = pattern.trim();
|
|||
|
|
|||
|
// windows support: need to use /, not \
|
|||
|
if (path.sep !== "/") {
|
|||
|
pattern = pattern.split(path.sep).join("/");
|
|||
|
}
|
|||
|
|
|||
|
this.options = options;
|
|||
|
this.set = [];
|
|||
|
this.pattern = pattern;
|
|||
|
this.regexp = null;
|
|||
|
this.negate = false;
|
|||
|
this.comment = false;
|
|||
|
this.empty = false;
|
|||
|
|
|||
|
// make the set of regexps etc.
|
|||
|
this.make();
|
|||
|
}
|
|||
|
|
|||
|
Minimatch.prototype.debug = function () {};
|
|||
|
|
|||
|
Minimatch.prototype.make = make;
|
|||
|
function make() {
|
|||
|
// don't do it more than once.
|
|||
|
if (this._made) return;
|
|||
|
|
|||
|
var pattern = this.pattern;
|
|||
|
var options = this.options;
|
|||
|
|
|||
|
// empty patterns and comments match nothing.
|
|||
|
if (!options.nocomment && pattern.charAt(0) === "#") {
|
|||
|
this.comment = true;
|
|||
|
return;
|
|||
|
}
|
|||
|
if (!pattern) {
|
|||
|
this.empty = true;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// step 1: figure out negation, etc.
|
|||
|
this.parseNegate();
|
|||
|
|
|||
|
// step 2: expand braces
|
|||
|
var set = (this.globSet = this.braceExpand());
|
|||
|
|
|||
|
if (options.debug) this.debug = console.error;
|
|||
|
|
|||
|
this.debug(this.pattern, set);
|
|||
|
|
|||
|
// step 3: now we have a set, so turn each one into a series of path-portion
|
|||
|
// matching patterns.
|
|||
|
// These will be regexps, except in the case of "**", which is
|
|||
|
// set to the GLOBSTAR object for globstar behavior,
|
|||
|
// and will not contain any / characters
|
|||
|
set = this.globParts = set.map(function (s) {
|
|||
|
return s.split(slashSplit);
|
|||
|
});
|
|||
|
|
|||
|
this.debug(this.pattern, set);
|
|||
|
|
|||
|
// glob --> regexps
|
|||
|
set = set.map(function (s, si, set) {
|
|||
|
return s.map(this.parse, this);
|
|||
|
}, this);
|
|||
|
|
|||
|
this.debug(this.pattern, set);
|
|||
|
|
|||
|
// filter out everything that didn't compile properly.
|
|||
|
set = set.filter(function (s) {
|
|||
|
return s.indexOf(false) === -1;
|
|||
|
});
|
|||
|
|
|||
|
this.debug(this.pattern, set);
|
|||
|
|
|||
|
this.set = set;
|
|||
|
}
|
|||
|
|
|||
|
Minimatch.prototype.parseNegate = parseNegate;
|
|||
|
function parseNegate() {
|
|||
|
var pattern = this.pattern;
|
|||
|
var negate = false;
|
|||
|
var options = this.options;
|
|||
|
var negateOffset = 0;
|
|||
|
|
|||
|
if (options.nonegate) return;
|
|||
|
|
|||
|
for (
|
|||
|
var i = 0, l = pattern.length;
|
|||
|
i < l && pattern.charAt(i) === "!";
|
|||
|
i++
|
|||
|
) {
|
|||
|
negate = !negate;
|
|||
|
negateOffset++;
|
|||
|
}
|
|||
|
|
|||
|
if (negateOffset) this.pattern = pattern.substr(negateOffset);
|
|||
|
this.negate = negate;
|
|||
|
}
|
|||
|
|
|||
|
// Brace expansion:
|
|||
|
// a{b,c}d -> abd acd
|
|||
|
// a{b,}c -> abc ac
|
|||
|
// a{0..3}d -> a0d a1d a2d a3d
|
|||
|
// a{b,c{d,e}f}g -> abg acdfg acefg
|
|||
|
// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
|
|||
|
//
|
|||
|
// Invalid sets are not expanded.
|
|||
|
// a{2..}b -> a{2..}b
|
|||
|
// a{b}c -> a{b}c
|
|||
|
minimatch.braceExpand = function (pattern, options) {
|
|||
|
return braceExpand(pattern, options);
|
|||
|
};
|
|||
|
|
|||
|
Minimatch.prototype.braceExpand = braceExpand;
|
|||
|
|
|||
|
function braceExpand(pattern, options) {
|
|||
|
if (!options) {
|
|||
|
if (this instanceof Minimatch) {
|
|||
|
options = this.options;
|
|||
|
} else {
|
|||
|
options = {};
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pattern = typeof pattern === "undefined" ? this.pattern : pattern;
|
|||
|
|
|||
|
if (typeof pattern === "undefined") {
|
|||
|
throw new TypeError("undefined pattern");
|
|||
|
}
|
|||
|
|
|||
|
if (options.nobrace || !pattern.match(/\{.*\}/)) {
|
|||
|
// shortcut. no need to expand.
|
|||
|
return [pattern];
|
|||
|
}
|
|||
|
|
|||
|
return expand(pattern);
|
|||
|
}
|
|||
|
|
|||
|
// parse a component of the expanded set.
|
|||
|
// At this point, no pattern may contain "/" in it
|
|||
|
// so we're going to return a 2d array, where each entry is the full
|
|||
|
// pattern, split on '/', and then turned into a regular expression.
|
|||
|
// A regexp is made at the end which joins each array with an
|
|||
|
// escaped /, and another full one which joins each regexp with |.
|
|||
|
//
|
|||
|
// Following the lead of Bash 4.1, note that "**" only has special meaning
|
|||
|
// when it is the *only* thing in a path portion. Otherwise, any series
|
|||
|
// of * is equivalent to a single *. Globstar behavior is enabled by
|
|||
|
// default, and can be disabled by setting options.noglobstar.
|
|||
|
Minimatch.prototype.parse = parse;
|
|||
|
var SUBPARSE = {};
|
|||
|
function parse(pattern, isSub) {
|
|||
|
if (pattern.length > 1024 * 64) {
|
|||
|
throw new TypeError("pattern is too long");
|
|||
|
}
|
|||
|
|
|||
|
var options = this.options;
|
|||
|
|
|||
|
// shortcuts
|
|||
|
if (!options.noglobstar && pattern === "**") return GLOBSTAR;
|
|||
|
if (pattern === "") return "";
|
|||
|
|
|||
|
var re = "";
|
|||
|
var hasMagic = !!options.nocase;
|
|||
|
var escaping = false;
|
|||
|
// ? => one single character
|
|||
|
var patternListStack = [];
|
|||
|
var negativeLists = [];
|
|||
|
var stateChar;
|
|||
|
var inClass = false;
|
|||
|
var reClassStart = -1;
|
|||
|
var classStart = -1;
|
|||
|
// . and .. never match anything that doesn't start with .,
|
|||
|
// even when options.dot is set.
|
|||
|
var patternStart =
|
|||
|
pattern.charAt(0) === "."
|
|||
|
? "" // anything
|
|||
|
: // not (start or / followed by . or .. followed by / or end)
|
|||
|
options.dot
|
|||
|
? "(?!(?:^|\\/)\\.{1,2}(?:$|\\/))"
|
|||
|
: "(?!\\.)";
|
|||
|
var self = this;
|
|||
|
|
|||
|
function clearStateChar() {
|
|||
|
if (stateChar) {
|
|||
|
// we had some state-tracking character
|
|||
|
// that wasn't consumed by this pass.
|
|||
|
switch (stateChar) {
|
|||
|
case "*":
|
|||
|
re += star;
|
|||
|
hasMagic = true;
|
|||
|
break;
|
|||
|
case "?":
|
|||
|
re += qmark;
|
|||
|
hasMagic = true;
|
|||
|
break;
|
|||
|
default:
|
|||
|
re += "\\" + stateChar;
|
|||
|
break;
|
|||
|
}
|
|||
|
self.debug("clearStateChar %j %j", stateChar, re);
|
|||
|
stateChar = false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
for (
|
|||
|
var i = 0, len = pattern.length, c;
|
|||
|
i < len && (c = pattern.charAt(i));
|
|||
|
i++
|
|||
|
) {
|
|||
|
this.debug("%s\t%s %s %j", pattern, i, re, c);
|
|||
|
|
|||
|
// skip over any that are escaped.
|
|||
|
if (escaping && reSpecials[c]) {
|
|||
|
re += "\\" + c;
|
|||
|
escaping = false;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
switch (c) {
|
|||
|
case "/":
|
|||
|
// completely not allowed, even escaped.
|
|||
|
// Should already be path-split by now.
|
|||
|
return false;
|
|||
|
|
|||
|
case "\\":
|
|||
|
clearStateChar();
|
|||
|
escaping = true;
|
|||
|
continue;
|
|||
|
|
|||
|
// the various stateChar values
|
|||
|
// for the "extglob" stuff.
|
|||
|
case "?":
|
|||
|
case "*":
|
|||
|
case "+":
|
|||
|
case "@":
|
|||
|
case "!":
|
|||
|
this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c);
|
|||
|
|
|||
|
// all of those are literals inside a class, except that
|
|||
|
// the glob [!a] means [^a] in regexp
|
|||
|
if (inClass) {
|
|||
|
this.debug(" in class");
|
|||
|
if (c === "!" && i === classStart + 1) c = "^";
|
|||
|
re += c;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// if we already have a stateChar, then it means
|
|||
|
// that there was something like ** or +? in there.
|
|||
|
// Handle the stateChar, then proceed with this one.
|
|||
|
self.debug("call clearStateChar %j", stateChar);
|
|||
|
clearStateChar();
|
|||
|
stateChar = c;
|
|||
|
// if extglob is disabled, then +(asdf|foo) isn't a thing.
|
|||
|
// just clear the statechar *now*, rather than even diving into
|
|||
|
// the patternList stuff.
|
|||
|
if (options.noext) clearStateChar();
|
|||
|
continue;
|
|||
|
|
|||
|
case "(":
|
|||
|
if (inClass) {
|
|||
|
re += "(";
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if (!stateChar) {
|
|||
|
re += "\\(";
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
patternListStack.push({
|
|||
|
type: stateChar,
|
|||
|
start: i - 1,
|
|||
|
reStart: re.length,
|
|||
|
open: plTypes[stateChar].open,
|
|||
|
close: plTypes[stateChar].close,
|
|||
|
});
|
|||
|
// negation is (?:(?!js)[^/]*)
|
|||
|
re += stateChar === "!" ? "(?:(?!(?:" : "(?:";
|
|||
|
this.debug("plType %j %j", stateChar, re);
|
|||
|
stateChar = false;
|
|||
|
continue;
|
|||
|
|
|||
|
case ")":
|
|||
|
if (inClass || !patternListStack.length) {
|
|||
|
re += "\\)";
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
clearStateChar();
|
|||
|
hasMagic = true;
|
|||
|
var pl = patternListStack.pop();
|
|||
|
// negation is (?:(?!js)[^/]*)
|
|||
|
// The others are (?:<pattern>)<type>
|
|||
|
re += pl.close;
|
|||
|
if (pl.type === "!") {
|
|||
|
negativeLists.push(pl);
|
|||
|
}
|
|||
|
pl.reEnd = re.length;
|
|||
|
continue;
|
|||
|
|
|||
|
case "|":
|
|||
|
if (inClass || !patternListStack.length || escaping) {
|
|||
|
re += "\\|";
|
|||
|
escaping = false;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
clearStateChar();
|
|||
|
re += "|";
|
|||
|
continue;
|
|||
|
|
|||
|
// these are mostly the same in regexp and glob
|
|||
|
case "[":
|
|||
|
// swallow any state-tracking char before the [
|
|||
|
clearStateChar();
|
|||
|
|
|||
|
if (inClass) {
|
|||
|
re += "\\" + c;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
inClass = true;
|
|||
|
classStart = i;
|
|||
|
reClassStart = re.length;
|
|||
|
re += c;
|
|||
|
continue;
|
|||
|
|
|||
|
case "]":
|
|||
|
// a right bracket shall lose its special
|
|||
|
// meaning and represent itself in
|
|||
|
// a bracket expression if it occurs
|
|||
|
// first in the list. -- POSIX.2 2.8.3.2
|
|||
|
if (i === classStart + 1 || !inClass) {
|
|||
|
re += "\\" + c;
|
|||
|
escaping = false;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// handle the case where we left a class open.
|
|||
|
// "[z-a]" is valid, equivalent to "\[z-a\]"
|
|||
|
if (inClass) {
|
|||
|
// split where the last [ was, make sure we don't have
|
|||
|
// an invalid re. if so, re-walk the contents of the
|
|||
|
// would-be class to re-translate any characters that
|
|||
|
// were passed through as-is
|
|||
|
// TODO: It would probably be faster to determine this
|
|||
|
// without a try/catch and a new RegExp, but it's tricky
|
|||
|
// to do safely. For now, this is safe and works.
|
|||
|
var cs = pattern.substring(classStart + 1, i);
|
|||
|
try {
|
|||
|
RegExp("[" + cs + "]");
|
|||
|
} catch (er) {
|
|||
|
// not a valid class!
|
|||
|
var sp = this.parse(cs, SUBPARSE);
|
|||
|
re = re.substr(0, reClassStart) + "\\[" + sp[0] + "\\]";
|
|||
|
hasMagic = hasMagic || sp[1];
|
|||
|
inClass = false;
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// finish up the class.
|
|||
|
hasMagic = true;
|
|||
|
inClass = false;
|
|||
|
re += c;
|
|||
|
continue;
|
|||
|
|
|||
|
default:
|
|||
|
// swallow any state char that wasn't consumed
|
|||
|
clearStateChar();
|
|||
|
|
|||
|
if (escaping) {
|
|||
|
// no need
|
|||
|
escaping = false;
|
|||
|
} else if (reSpecials[c] && !(c === "^" && inClass)) {
|
|||
|
re += "\\";
|
|||
|
}
|
|||
|
|
|||
|
re += c;
|
|||
|
} // switch
|
|||
|
} // for
|
|||
|
|
|||
|
// handle the case where we left a class open.
|
|||
|
// "[abc" is valid, equivalent to "\[abc"
|
|||
|
if (inClass) {
|
|||
|
// split where the last [ was, and escape it
|
|||
|
// this is a huge pita. We now have to re-walk
|
|||
|
// the contents of the would-be class to re-translate
|
|||
|
// any characters that were passed through as-is
|
|||
|
cs = pattern.substr(classStart + 1);
|
|||
|
sp = this.parse(cs, SUBPARSE);
|
|||
|
re = re.substr(0, reClassStart) + "\\[" + sp[0];
|
|||
|
hasMagic = hasMagic || sp[1];
|
|||
|
}
|
|||
|
|
|||
|
// handle the case where we had a +( thing at the *end*
|
|||
|
// of the pattern.
|
|||
|
// each pattern list stack adds 3 chars, and we need to go through
|
|||
|
// and escape any | chars that were passed through as-is for the regexp.
|
|||
|
// Go through and escape them, taking care not to double-escape any
|
|||
|
// | chars that were already escaped.
|
|||
|
for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {
|
|||
|
var tail = re.slice(pl.reStart + pl.open.length);
|
|||
|
this.debug("setting tail", re, pl);
|
|||
|
// maybe some even number of \, then maybe 1 \, followed by a |
|
|||
|
tail = tail.replace(
|
|||
|
/((?:\\{2}){0,64})(\\?)\|/g,
|
|||
|
function (_, $1, $2) {
|
|||
|
if (!$2) {
|
|||
|
// the | isn't already escaped, so escape it.
|
|||
|
$2 = "\\";
|
|||
|
}
|
|||
|
|
|||
|
// need to escape all those slashes *again*, without escaping the
|
|||
|
// one that we need for escaping the | character. As it works out,
|
|||
|
// escaping an even number of slashes can be done by simply repeating
|
|||
|
// it exactly after itself. That's why this trick works.
|
|||
|
//
|
|||
|
// I am sorry that you have to see this.
|
|||
|
return $1 + $1 + $2 + "|";
|
|||
|
}
|
|||
|
);
|
|||
|
|
|||
|
this.debug("tail=%j\n %s", tail, tail, pl, re);
|
|||
|
var t =
|
|||
|
pl.type === "*"
|
|||
|
? star
|
|||
|
: pl.type === "?"
|
|||
|
? qmark
|
|||
|
: "\\" + pl.type;
|
|||
|
|
|||
|
hasMagic = true;
|
|||
|
re = re.slice(0, pl.reStart) + t + "\\(" + tail;
|
|||
|
}
|
|||
|
|
|||
|
// handle trailing things that only matter at the very end.
|
|||
|
clearStateChar();
|
|||
|
if (escaping) {
|
|||
|
// trailing \\
|
|||
|
re += "\\\\";
|
|||
|
}
|
|||
|
|
|||
|
// only need to apply the nodot start if the re starts with
|
|||
|
// something that could conceivably capture a dot
|
|||
|
var addPatternStart = false;
|
|||
|
switch (re.charAt(0)) {
|
|||
|
case ".":
|
|||
|
case "[":
|
|||
|
case "(":
|
|||
|
addPatternStart = true;
|
|||
|
}
|
|||
|
|
|||
|
// Hack to work around lack of negative lookbehind in JS
|
|||
|
// A pattern like: *.!(x).!(y|z) needs to ensure that a name
|
|||
|
// like 'a.xyz.yz' doesn't match. So, the first negative
|
|||
|
// lookahead, has to look ALL the way ahead, to the end of
|
|||
|
// the pattern.
|
|||
|
for (var n = negativeLists.length - 1; n > -1; n--) {
|
|||
|
var nl = negativeLists[n];
|
|||
|
|
|||
|
var nlBefore = re.slice(0, nl.reStart);
|
|||
|
var nlFirst = re.slice(nl.reStart, nl.reEnd - 8);
|
|||
|
var nlLast = re.slice(nl.reEnd - 8, nl.reEnd);
|
|||
|
var nlAfter = re.slice(nl.reEnd);
|
|||
|
|
|||
|
nlLast += nlAfter;
|
|||
|
|
|||
|
// Handle nested stuff like *(*.js|!(*.json)), where open parens
|
|||
|
// mean that we should *not* include the ) in the bit that is considered
|
|||
|
// "after" the negated section.
|
|||
|
var openParensBefore = nlBefore.split("(").length - 1;
|
|||
|
var cleanAfter = nlAfter;
|
|||
|
for (i = 0; i < openParensBefore; i++) {
|
|||
|
cleanAfter = cleanAfter.replace(/\)[+*?]?/, "");
|
|||
|
}
|
|||
|
nlAfter = cleanAfter;
|
|||
|
|
|||
|
var dollar = "";
|
|||
|
if (nlAfter === "" && isSub !== SUBPARSE) {
|
|||
|
dollar = "$";
|
|||
|
}
|
|||
|
var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast;
|
|||
|
re = newRe;
|
|||
|
}
|
|||
|
|
|||
|
// if the re is not "" at this point, then we need to make sure
|
|||
|
// it doesn't match against an empty path part.
|
|||
|
// Otherwise a/* will match a/, which it should not.
|
|||
|
if (re !== "" && hasMagic) {
|
|||
|
re = "(?=.)" + re;
|
|||
|
}
|
|||
|
|
|||
|
if (addPatternStart) {
|
|||
|
re = patternStart + re;
|
|||
|
}
|
|||
|
|
|||
|
// parsing just a piece of a larger pattern.
|
|||
|
if (isSub === SUBPARSE) {
|
|||
|
return [re, hasMagic];
|
|||
|
}
|
|||
|
|
|||
|
// skip the regexp for non-magical patterns
|
|||
|
// unescape anything in it, though, so that it'll be
|
|||
|
// an exact match against a file etc.
|
|||
|
if (!hasMagic) {
|
|||
|
return globUnescape(pattern);
|
|||
|
}
|
|||
|
|
|||
|
var flags = options.nocase ? "i" : "";
|
|||
|
try {
|
|||
|
var regExp = new RegExp("^" + re + "$", flags);
|
|||
|
} catch (er) {
|
|||
|
// If it was an invalid regular expression, then it can't match
|
|||
|
// anything. This trick looks for a character after the end of
|
|||
|
// the string, which is of course impossible, except in multi-line
|
|||
|
// mode, but it's not a /m regex.
|
|||
|
return new RegExp("$.");
|
|||
|
}
|
|||
|
|
|||
|
regExp._glob = pattern;
|
|||
|
regExp._src = re;
|
|||
|
|
|||
|
return regExp;
|
|||
|
}
|
|||
|
|
|||
|
minimatch.makeRe = function (pattern, options) {
|
|||
|
return new Minimatch(pattern, options || {}).makeRe();
|
|||
|
};
|
|||
|
|
|||
|
Minimatch.prototype.makeRe = makeRe;
|
|||
|
function makeRe() {
|
|||
|
if (this.regexp || this.regexp === false) return this.regexp;
|
|||
|
|
|||
|
// at this point, this.set is a 2d array of partial
|
|||
|
// pattern strings, or "**".
|
|||
|
//
|
|||
|
// It's better to use .match(). This function shouldn't
|
|||
|
// be used, really, but it's pretty convenient sometimes,
|
|||
|
// when you just want to work with a regex.
|
|||
|
var set = this.set;
|
|||
|
|
|||
|
if (!set.length) {
|
|||
|
this.regexp = false;
|
|||
|
return this.regexp;
|
|||
|
}
|
|||
|
var options = this.options;
|
|||
|
|
|||
|
var twoStar = options.noglobstar
|
|||
|
? star
|
|||
|
: options.dot
|
|||
|
? twoStarDot
|
|||
|
: twoStarNoDot;
|
|||
|
var flags = options.nocase ? "i" : "";
|
|||
|
|
|||
|
var re = set
|
|||
|
.map(function (pattern) {
|
|||
|
return pattern
|
|||
|
.map(function (p) {
|
|||
|
return p === GLOBSTAR
|
|||
|
? twoStar
|
|||
|
: typeof p === "string"
|
|||
|
? regExpEscape(p)
|
|||
|
: p._src;
|
|||
|
})
|
|||
|
.join("\\/");
|
|||
|
})
|
|||
|
.join("|");
|
|||
|
|
|||
|
// must match entire pattern
|
|||
|
// ending in a * or ** will make it less strict.
|
|||
|
re = "^(?:" + re + ")$";
|
|||
|
|
|||
|
// can match anything, as long as it's not this.
|
|||
|
if (this.negate) re = "^(?!" + re + ").*$";
|
|||
|
|
|||
|
try {
|
|||
|
this.regexp = new RegExp(re, flags);
|
|||
|
} catch (ex) {
|
|||
|
this.regexp = false;
|
|||
|
}
|
|||
|
return this.regexp;
|
|||
|
}
|
|||
|
|
|||
|
minimatch.match = function (list, pattern, options) {
|
|||
|
options = options || {};
|
|||
|
var mm = new Minimatch(pattern, options);
|
|||
|
list = list.filter(function (f) {
|
|||
|
return mm.match(f);
|
|||
|
});
|
|||
|
if (mm.options.nonull && !list.length) {
|
|||
|
list.push(pattern);
|
|||
|
}
|
|||
|
return list;
|
|||
|
};
|
|||
|
|
|||
|
Minimatch.prototype.match = match;
|
|||
|
function match(f, partial) {
|
|||
|
this.debug("match", f, this.pattern);
|
|||
|
// short-circuit in the case of busted things.
|
|||
|
// comments, etc.
|
|||
|
if (this.comment) return false;
|
|||
|
if (this.empty) return f === "";
|
|||
|
|
|||
|
if (f === "/" && partial) return true;
|
|||
|
|
|||
|
var options = this.options;
|
|||
|
|
|||
|
// windows: need to use /, not \
|
|||
|
if (path.sep !== "/") {
|
|||
|
f = f.split(path.sep).join("/");
|
|||
|
}
|
|||
|
|
|||
|
// treat the test path as a set of pathparts.
|
|||
|
f = f.split(slashSplit);
|
|||
|
this.debug(this.pattern, "split", f);
|
|||
|
|
|||
|
// just ONE of the pattern sets in this.set needs to match
|
|||
|
// in order for it to be valid. If negating, then just one
|
|||
|
// match means that we have failed.
|
|||
|
// Either way, return on the first hit.
|
|||
|
|
|||
|
var set = this.set;
|
|||
|
this.debug(this.pattern, "set", set);
|
|||
|
|
|||
|
// Find the basename of the path by looking for the last non-empty segment
|
|||
|
var filename;
|
|||
|
var i;
|
|||
|
for (i = f.length - 1; i >= 0; i--) {
|
|||
|
filename = f[i];
|
|||
|
if (filename) break;
|
|||
|
}
|
|||
|
|
|||
|
for (i = 0; i < set.length; i++) {
|
|||
|
var pattern = set[i];
|
|||
|
var file = f;
|
|||
|
if (options.matchBase && pattern.length === 1) {
|
|||
|
file = [filename];
|
|||
|
}
|
|||
|
var hit = this.matchOne(file, pattern, partial);
|
|||
|
if (hit) {
|
|||
|
if (options.flipNegate) return true;
|
|||
|
return !this.negate;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// didn't get any hits. this is success if it's a negative
|
|||
|
// pattern, failure otherwise.
|
|||
|
if (options.flipNegate) return false;
|
|||
|
return this.negate;
|
|||
|
}
|
|||
|
|
|||
|
// set partial to true to test if, for example,
|
|||
|
// "/a/b" matches the start of "/*/b/*/d"
|
|||
|
// Partial means, if you run out of file before you run
|
|||
|
// out of pattern, then that's fine, as long as all
|
|||
|
// the parts match.
|
|||
|
Minimatch.prototype.matchOne = function (file, pattern, partial) {
|
|||
|
var options = this.options;
|
|||
|
|
|||
|
this.debug("matchOne", {
|
|||
|
this: this,
|
|||
|
file: file,
|
|||
|
pattern: pattern,
|
|||
|
});
|
|||
|
|
|||
|
this.debug("matchOne", file.length, pattern.length);
|
|||
|
|
|||
|
for (
|
|||
|
var fi = 0, pi = 0, fl = file.length, pl = pattern.length;
|
|||
|
fi < fl && pi < pl;
|
|||
|
fi++, pi++
|
|||
|
) {
|
|||
|
this.debug("matchOne loop");
|
|||
|
var p = pattern[pi];
|
|||
|
var f = file[fi];
|
|||
|
|
|||
|
this.debug(pattern, p, f);
|
|||
|
|
|||
|
// should be impossible.
|
|||
|
// some invalid regexp stuff in the set.
|
|||
|
if (p === false) return false;
|
|||
|
|
|||
|
if (p === GLOBSTAR) {
|
|||
|
this.debug("GLOBSTAR", [pattern, p, f]);
|
|||
|
|
|||
|
// "**"
|
|||
|
// a/**/b/**/c would match the following:
|
|||
|
// a/b/x/y/z/c
|
|||
|
// a/x/y/z/b/c
|
|||
|
// a/b/x/b/x/c
|
|||
|
// a/b/c
|
|||
|
// To do this, take the rest of the pattern after
|
|||
|
// the **, and see if it would match the file remainder.
|
|||
|
// If so, return success.
|
|||
|
// If not, the ** "swallows" a segment, and try again.
|
|||
|
// This is recursively awful.
|
|||
|
//
|
|||
|
// a/**/b/**/c matching a/b/x/y/z/c
|
|||
|
// - a matches a
|
|||
|
// - doublestar
|
|||
|
// - matchOne(b/x/y/z/c, b/**/c)
|
|||
|
// - b matches b
|
|||
|
// - doublestar
|
|||
|
// - matchOne(x/y/z/c, c) -> no
|
|||
|
// - matchOne(y/z/c, c) -> no
|
|||
|
// - matchOne(z/c, c) -> no
|
|||
|
// - matchOne(c, c) yes, hit
|
|||
|
var fr = fi;
|
|||
|
var pr = pi + 1;
|
|||
|
if (pr === pl) {
|
|||
|
this.debug("** at the end");
|
|||
|
// a ** at the end will just swallow the rest.
|
|||
|
// We have found a match.
|
|||
|
// however, it will not swallow /.x, unless
|
|||
|
// options.dot is set.
|
|||
|
// . and .. are *never* matched by **, for explosively
|
|||
|
// exponential reasons.
|
|||
|
for (; fi < fl; fi++) {
|
|||
|
if (
|
|||
|
file[fi] === "." ||
|
|||
|
file[fi] === ".." ||
|
|||
|
(!options.dot && file[fi].charAt(0) === ".")
|
|||
|
)
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
// ok, let's see if we can swallow whatever we can.
|
|||
|
while (fr < fl) {
|
|||
|
var swallowee = file[fr];
|
|||
|
|
|||
|
this.debug(
|
|||
|
"\nglobstar while",
|
|||
|
file,
|
|||
|
fr,
|
|||
|
pattern,
|
|||
|
pr,
|
|||
|
swallowee
|
|||
|
);
|
|||
|
|
|||
|
// XXX remove this slice. Just pass the start index.
|
|||
|
if (
|
|||
|
this.matchOne(file.slice(fr), pattern.slice(pr), partial)
|
|||
|
) {
|
|||
|
this.debug("globstar found match!", fr, fl, swallowee);
|
|||
|
// found a match.
|
|||
|
return true;
|
|||
|
} else {
|
|||
|
// can't swallow "." or ".." ever.
|
|||
|
// can only swallow ".foo" when explicitly asked.
|
|||
|
if (
|
|||
|
swallowee === "." ||
|
|||
|
swallowee === ".." ||
|
|||
|
(!options.dot && swallowee.charAt(0) === ".")
|
|||
|
) {
|
|||
|
this.debug("dot detected!", file, fr, pattern, pr);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// ** swallows a segment, and continue.
|
|||
|
this.debug("globstar swallow a segment, and continue");
|
|||
|
fr++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// no match was found.
|
|||
|
// However, in partial mode, we can't say this is necessarily over.
|
|||
|
// If there's more *pattern* left, then
|
|||
|
if (partial) {
|
|||
|
// ran out of file
|
|||
|
this.debug("\n>>> no match, partial?", file, fr, pattern, pr);
|
|||
|
if (fr === fl) return true;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// something other than **
|
|||
|
// non-magic patterns just have to match exactly
|
|||
|
// patterns with magic have been turned into regexps.
|
|||
|
var hit;
|
|||
|
if (typeof p === "string") {
|
|||
|
if (options.nocase) {
|
|||
|
hit = f.toLowerCase() === p.toLowerCase();
|
|||
|
} else {
|
|||
|
hit = f === p;
|
|||
|
}
|
|||
|
this.debug("string match", p, f, hit);
|
|||
|
} else {
|
|||
|
hit = f.match(p);
|
|||
|
this.debug("pattern match", p, f, hit);
|
|||
|
}
|
|||
|
|
|||
|
if (!hit) return false;
|
|||
|
}
|
|||
|
|
|||
|
// Note: ending in / means that we'll get a final ""
|
|||
|
// at the end of the pattern. This can only match a
|
|||
|
// corresponding "" at the end of the file.
|
|||
|
// If the file ends in /, then it can only match a
|
|||
|
// a pattern that ends in /, unless the pattern just
|
|||
|
// doesn't have any more for it. But, a/b/ should *not*
|
|||
|
// match "a/b/*", even though "" matches against the
|
|||
|
// [^/]*? pattern, except in partial mode, where it might
|
|||
|
// simply not be reached yet.
|
|||
|
// However, a/b/ should still satisfy a/*
|
|||
|
|
|||
|
// now either we fell off the end of the pattern, or we're done.
|
|||
|
if (fi === fl && pi === pl) {
|
|||
|
// ran out of pattern and filename at the same time.
|
|||
|
// an exact hit!
|
|||
|
return true;
|
|||
|
} else if (fi === fl) {
|
|||
|
// ran out of file, but still had pattern left.
|
|||
|
// this is ok if we're doing the match as part of
|
|||
|
// a glob fs traversal.
|
|||
|
return partial;
|
|||
|
} else if (pi === pl) {
|
|||
|
// ran out of pattern, still have file left.
|
|||
|
// this is only acceptable if we're on the very last
|
|||
|
// empty segment of a file with a trailing slash.
|
|||
|
// a/* should match a/b/
|
|||
|
var emptyFileEnd = fi === fl - 1 && file[fi] === "";
|
|||
|
return emptyFileEnd;
|
|||
|
}
|
|||
|
|
|||
|
// should be unreachable.
|
|||
|
throw new Error("wtf?");
|
|||
|
};
|
|||
|
|
|||
|
// replace stuff like \* with *
|
|||
|
function globUnescape(s) {
|
|||
|
return s.replace(/\\(.)/g, "$1");
|
|||
|
}
|
|||
|
|
|||
|
function regExpEscape(s) {
|
|||
|
return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
|||
|
}
|
|||
|
},
|
|||
|
{ "brace-expansion": 11, path: 22 },
|
|||
|
],
|
|||
|
21: [
|
|||
|
function (require, module, exports) {
|
|||
|
var wrappy = require("wrappy");
|
|||
|
module.exports = wrappy(once);
|
|||
|
module.exports.strict = wrappy(onceStrict);
|
|||
|
|
|||
|
once.proto = once(function () {
|
|||
|
Object.defineProperty(Function.prototype, "once", {
|
|||
|
value: function () {
|
|||
|
return once(this);
|
|||
|
},
|
|||
|
configurable: true,
|
|||
|
});
|
|||
|
|
|||
|
Object.defineProperty(Function.prototype, "onceStrict", {
|
|||
|
value: function () {
|
|||
|
return onceStrict(this);
|
|||
|
},
|
|||
|
configurable: true,
|
|||
|
});
|
|||
|
});
|
|||
|
|
|||
|
function once(fn) {
|
|||
|
var f = function () {
|
|||
|
if (f.called) return f.value;
|
|||
|
f.called = true;
|
|||
|
return (f.value = fn.apply(this, arguments));
|
|||
|
};
|
|||
|
f.called = false;
|
|||
|
return f;
|
|||
|
}
|
|||
|
|
|||
|
function onceStrict(fn) {
|
|||
|
var f = function () {
|
|||
|
if (f.called) throw new Error(f.onceError);
|
|||
|
f.called = true;
|
|||
|
return (f.value = fn.apply(this, arguments));
|
|||
|
};
|
|||
|
var name = fn.name || "Function wrapped with `once`";
|
|||
|
f.onceError = name + " shouldn't be called more than once";
|
|||
|
f.called = false;
|
|||
|
return f;
|
|||
|
}
|
|||
|
},
|
|||
|
{ wrappy: 29 },
|
|||
|
],
|
|||
|
22: [
|
|||
|
function (require, module, exports) {
|
|||
|
(function (process) {
|
|||
|
// Copyright Joyent, Inc. and other Node contributors.
|
|||
|
//
|
|||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
|
// copy of this software and associated documentation files (the
|
|||
|
// "Software"), to deal in the Software without restriction, including
|
|||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
|
// persons to whom the Software is furnished to do so, subject to the
|
|||
|
// following conditions:
|
|||
|
//
|
|||
|
// The above copyright notice and this permission notice shall be included
|
|||
|
// in all copies or substantial portions of the Software.
|
|||
|
//
|
|||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|
|||
|
// resolves . and .. elements in a path array with directory names there
|
|||
|
// must be no slashes, empty elements, or device names (c:\) in the array
|
|||
|
// (so also no leading and trailing slashes - it does not distinguish
|
|||
|
// relative and absolute paths)
|
|||
|
function normalizeArray(parts, allowAboveRoot) {
|
|||
|
// if the path tries to go above the root, `up` ends up > 0
|
|||
|
var up = 0;
|
|||
|
for (var i = parts.length - 1; i >= 0; i--) {
|
|||
|
var last = parts[i];
|
|||
|
if (last === ".") {
|
|||
|
parts.splice(i, 1);
|
|||
|
} else if (last === "..") {
|
|||
|
parts.splice(i, 1);
|
|||
|
up++;
|
|||
|
} else if (up) {
|
|||
|
parts.splice(i, 1);
|
|||
|
up--;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// if the path is allowed to go above the root, restore leading ..s
|
|||
|
if (allowAboveRoot) {
|
|||
|
for (; up--; up) {
|
|||
|
parts.unshift("..");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return parts;
|
|||
|
}
|
|||
|
|
|||
|
// Split a filename into [root, dir, basename, ext], unix version
|
|||
|
// 'root' is just a slash, or nothing.
|
|||
|
var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
|
|||
|
var splitPath = function (filename) {
|
|||
|
return splitPathRe.exec(filename).slice(1);
|
|||
|
};
|
|||
|
|
|||
|
// path.resolve([from ...], to)
|
|||
|
// posix version
|
|||
|
exports.resolve = function () {
|
|||
|
var resolvedPath = "",
|
|||
|
resolvedAbsolute = false;
|
|||
|
|
|||
|
for (
|
|||
|
var i = arguments.length - 1;
|
|||
|
i >= -1 && !resolvedAbsolute;
|
|||
|
i--
|
|||
|
) {
|
|||
|
var path = i >= 0 ? arguments[i] : process.cwd();
|
|||
|
|
|||
|
// Skip empty and invalid entries
|
|||
|
if (typeof path !== "string") {
|
|||
|
throw new TypeError(
|
|||
|
"Arguments to path.resolve must be strings"
|
|||
|
);
|
|||
|
} else if (!path) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
resolvedPath = path + "/" + resolvedPath;
|
|||
|
resolvedAbsolute = path.charAt(0) === "/";
|
|||
|
}
|
|||
|
|
|||
|
// At this point the path should be resolved to a full absolute path, but
|
|||
|
// handle relative paths to be safe (might happen when process.cwd() fails)
|
|||
|
|
|||
|
// Normalize the path
|
|||
|
resolvedPath = normalizeArray(
|
|||
|
filter(resolvedPath.split("/"), function (p) {
|
|||
|
return !!p;
|
|||
|
}),
|
|||
|
!resolvedAbsolute
|
|||
|
).join("/");
|
|||
|
|
|||
|
return (resolvedAbsolute ? "/" : "") + resolvedPath || ".";
|
|||
|
};
|
|||
|
|
|||
|
// path.normalize(path)
|
|||
|
// posix version
|
|||
|
exports.normalize = function (path) {
|
|||
|
var isAbsolute = exports.isAbsolute(path),
|
|||
|
trailingSlash = substr(path, -1) === "/";
|
|||
|
|
|||
|
// Normalize the path
|
|||
|
path = normalizeArray(
|
|||
|
filter(path.split("/"), function (p) {
|
|||
|
return !!p;
|
|||
|
}),
|
|||
|
!isAbsolute
|
|||
|
).join("/");
|
|||
|
|
|||
|
if (!path && !isAbsolute) {
|
|||
|
path = ".";
|
|||
|
}
|
|||
|
if (path && trailingSlash) {
|
|||
|
path += "/";
|
|||
|
}
|
|||
|
|
|||
|
return (isAbsolute ? "/" : "") + path;
|
|||
|
};
|
|||
|
|
|||
|
// posix version
|
|||
|
exports.isAbsolute = function (path) {
|
|||
|
return path.charAt(0) === "/";
|
|||
|
};
|
|||
|
|
|||
|
// posix version
|
|||
|
exports.join = function () {
|
|||
|
var paths = Array.prototype.slice.call(arguments, 0);
|
|||
|
return exports.normalize(
|
|||
|
filter(paths, function (p, index) {
|
|||
|
if (typeof p !== "string") {
|
|||
|
throw new TypeError(
|
|||
|
"Arguments to path.join must be strings"
|
|||
|
);
|
|||
|
}
|
|||
|
return p;
|
|||
|
}).join("/")
|
|||
|
);
|
|||
|
};
|
|||
|
|
|||
|
// path.relative(from, to)
|
|||
|
// posix version
|
|||
|
exports.relative = function (from, to) {
|
|||
|
from = exports.resolve(from).substr(1);
|
|||
|
to = exports.resolve(to).substr(1);
|
|||
|
|
|||
|
function trim(arr) {
|
|||
|
var start = 0;
|
|||
|
for (; start < arr.length; start++) {
|
|||
|
if (arr[start] !== "") break;
|
|||
|
}
|
|||
|
|
|||
|
var end = arr.length - 1;
|
|||
|
for (; end >= 0; end--) {
|
|||
|
if (arr[end] !== "") break;
|
|||
|
}
|
|||
|
|
|||
|
if (start > end) return [];
|
|||
|
return arr.slice(start, end - start + 1);
|
|||
|
}
|
|||
|
|
|||
|
var fromParts = trim(from.split("/"));
|
|||
|
var toParts = trim(to.split("/"));
|
|||
|
|
|||
|
var length = Math.min(fromParts.length, toParts.length);
|
|||
|
var samePartsLength = length;
|
|||
|
for (var i = 0; i < length; i++) {
|
|||
|
if (fromParts[i] !== toParts[i]) {
|
|||
|
samePartsLength = i;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var outputParts = [];
|
|||
|
for (var i = samePartsLength; i < fromParts.length; i++) {
|
|||
|
outputParts.push("..");
|
|||
|
}
|
|||
|
|
|||
|
outputParts = outputParts.concat(toParts.slice(samePartsLength));
|
|||
|
|
|||
|
return outputParts.join("/");
|
|||
|
};
|
|||
|
|
|||
|
exports.sep = "/";
|
|||
|
exports.delimiter = ":";
|
|||
|
|
|||
|
exports.dirname = function (path) {
|
|||
|
var result = splitPath(path),
|
|||
|
root = result[0],
|
|||
|
dir = result[1];
|
|||
|
|
|||
|
if (!root && !dir) {
|
|||
|
// No dirname whatsoever
|
|||
|
return ".";
|
|||
|
}
|
|||
|
|
|||
|
if (dir) {
|
|||
|
// It has a dirname, strip trailing slash
|
|||
|
dir = dir.substr(0, dir.length - 1);
|
|||
|
}
|
|||
|
|
|||
|
return root + dir;
|
|||
|
};
|
|||
|
|
|||
|
exports.basename = function (path, ext) {
|
|||
|
var f = splitPath(path)[2];
|
|||
|
// TODO: make this comparison case-insensitive on windows?
|
|||
|
if (ext && f.substr(-1 * ext.length) === ext) {
|
|||
|
f = f.substr(0, f.length - ext.length);
|
|||
|
}
|
|||
|
return f;
|
|||
|
};
|
|||
|
|
|||
|
exports.extname = function (path) {
|
|||
|
return splitPath(path)[3];
|
|||
|
};
|
|||
|
|
|||
|
function filter(xs, f) {
|
|||
|
if (xs.filter) return xs.filter(f);
|
|||
|
var res = [];
|
|||
|
for (var i = 0; i < xs.length; i++) {
|
|||
|
if (f(xs[i], i, xs)) res.push(xs[i]);
|
|||
|
}
|
|||
|
return res;
|
|||
|
}
|
|||
|
|
|||
|
// String.prototype.substr - negative index don't work in IE8
|
|||
|
var substr =
|
|||
|
"ab".substr(-1) === "b"
|
|||
|
? function (str, start, len) {
|
|||
|
return str.substr(start, len);
|
|||
|
}
|
|||
|
: function (str, start, len) {
|
|||
|
if (start < 0) start = str.length + start;
|
|||
|
return str.substr(start, len);
|
|||
|
};
|
|||
|
}.call(this, require("_process")));
|
|||
|
},
|
|||
|
{ _process: 24 },
|
|||
|
],
|
|||
|
23: [
|
|||
|
function (require, module, exports) {
|
|||
|
(function (process) {
|
|||
|
"use strict";
|
|||
|
|
|||
|
function posix(path) {
|
|||
|
return path.charAt(0) === "/";
|
|||
|
}
|
|||
|
|
|||
|
function win32(path) {
|
|||
|
// https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56
|
|||
|
var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
|
|||
|
var result = splitDeviceRe.exec(path);
|
|||
|
var device = result[1] || "";
|
|||
|
var isUnc = Boolean(device && device.charAt(1) !== ":");
|
|||
|
|
|||
|
// UNC paths are always absolute
|
|||
|
return Boolean(result[2] || isUnc);
|
|||
|
}
|
|||
|
|
|||
|
module.exports = process.platform === "win32" ? win32 : posix;
|
|||
|
module.exports.posix = posix;
|
|||
|
module.exports.win32 = win32;
|
|||
|
}.call(this, require("_process")));
|
|||
|
},
|
|||
|
{ _process: 24 },
|
|||
|
],
|
|||
|
24: [
|
|||
|
function (require, module, exports) {
|
|||
|
// shim for using process in browser
|
|||
|
var process = (module.exports = {});
|
|||
|
|
|||
|
// cached from whatever global is present so that test runners that stub it
|
|||
|
// don't break things. But we need to wrap it in a try catch in case it is
|
|||
|
// wrapped in strict mode code which doesn't define any globals. It's inside a
|
|||
|
// function because try/catches deoptimize in certain engines.
|
|||
|
|
|||
|
var cachedSetTimeout;
|
|||
|
var cachedClearTimeout;
|
|||
|
|
|||
|
function defaultSetTimout() {
|
|||
|
throw new Error("setTimeout has not been defined");
|
|||
|
}
|
|||
|
function defaultClearTimeout() {
|
|||
|
throw new Error("clearTimeout has not been defined");
|
|||
|
}
|
|||
|
(function () {
|
|||
|
try {
|
|||
|
if (typeof setTimeout === "function") {
|
|||
|
cachedSetTimeout = setTimeout;
|
|||
|
} else {
|
|||
|
cachedSetTimeout = defaultSetTimout;
|
|||
|
}
|
|||
|
} catch (e) {
|
|||
|
cachedSetTimeout = defaultSetTimout;
|
|||
|
}
|
|||
|
try {
|
|||
|
if (typeof clearTimeout === "function") {
|
|||
|
cachedClearTimeout = clearTimeout;
|
|||
|
} else {
|
|||
|
cachedClearTimeout = defaultClearTimeout;
|
|||
|
}
|
|||
|
} catch (e) {
|
|||
|
cachedClearTimeout = defaultClearTimeout;
|
|||
|
}
|
|||
|
})();
|
|||
|
function runTimeout(fun) {
|
|||
|
if (cachedSetTimeout === setTimeout) {
|
|||
|
//normal enviroments in sane situations
|
|||
|
return setTimeout(fun, 0);
|
|||
|
}
|
|||
|
// if setTimeout wasn't available but was latter defined
|
|||
|
if (
|
|||
|
(cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) &&
|
|||
|
setTimeout
|
|||
|
) {
|
|||
|
cachedSetTimeout = setTimeout;
|
|||
|
return setTimeout(fun, 0);
|
|||
|
}
|
|||
|
try {
|
|||
|
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|||
|
return cachedSetTimeout(fun, 0);
|
|||
|
} catch (e) {
|
|||
|
try {
|
|||
|
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|||
|
return cachedSetTimeout.call(null, fun, 0);
|
|||
|
} catch (e) {
|
|||
|
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
|
|||
|
return cachedSetTimeout.call(this, fun, 0);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
function runClearTimeout(marker) {
|
|||
|
if (cachedClearTimeout === clearTimeout) {
|
|||
|
//normal enviroments in sane situations
|
|||
|
return clearTimeout(marker);
|
|||
|
}
|
|||
|
// if clearTimeout wasn't available but was latter defined
|
|||
|
if (
|
|||
|
(cachedClearTimeout === defaultClearTimeout ||
|
|||
|
!cachedClearTimeout) &&
|
|||
|
clearTimeout
|
|||
|
) {
|
|||
|
cachedClearTimeout = clearTimeout;
|
|||
|
return clearTimeout(marker);
|
|||
|
}
|
|||
|
try {
|
|||
|
// when when somebody has screwed with setTimeout but no I.E. maddness
|
|||
|
return cachedClearTimeout(marker);
|
|||
|
} catch (e) {
|
|||
|
try {
|
|||
|
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|||
|
return cachedClearTimeout.call(null, marker);
|
|||
|
} catch (e) {
|
|||
|
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
|
|||
|
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
|
|||
|
return cachedClearTimeout.call(this, marker);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
var queue = [];
|
|||
|
var draining = false;
|
|||
|
var currentQueue;
|
|||
|
var queueIndex = -1;
|
|||
|
|
|||
|
function cleanUpNextTick() {
|
|||
|
if (!draining || !currentQueue) {
|
|||
|
return;
|
|||
|
}
|
|||
|
draining = false;
|
|||
|
if (currentQueue.length) {
|
|||
|
queue = currentQueue.concat(queue);
|
|||
|
} else {
|
|||
|
queueIndex = -1;
|
|||
|
}
|
|||
|
if (queue.length) {
|
|||
|
drainQueue();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function drainQueue() {
|
|||
|
if (draining) {
|
|||
|
return;
|
|||
|
}
|
|||
|
var timeout = runTimeout(cleanUpNextTick);
|
|||
|
draining = true;
|
|||
|
|
|||
|
var len = queue.length;
|
|||
|
while (len) {
|
|||
|
currentQueue = queue;
|
|||
|
queue = [];
|
|||
|
while (++queueIndex < len) {
|
|||
|
if (currentQueue) {
|
|||
|
currentQueue[queueIndex].run();
|
|||
|
}
|
|||
|
}
|
|||
|
queueIndex = -1;
|
|||
|
len = queue.length;
|
|||
|
}
|
|||
|
currentQueue = null;
|
|||
|
draining = false;
|
|||
|
runClearTimeout(timeout);
|
|||
|
}
|
|||
|
|
|||
|
process.nextTick = function (fun) {
|
|||
|
var args = new Array(arguments.length - 1);
|
|||
|
if (arguments.length > 1) {
|
|||
|
for (var i = 1; i < arguments.length; i++) {
|
|||
|
args[i - 1] = arguments[i];
|
|||
|
}
|
|||
|
}
|
|||
|
queue.push(new Item(fun, args));
|
|||
|
if (queue.length === 1 && !draining) {
|
|||
|
runTimeout(drainQueue);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// v8 likes predictible objects
|
|||
|
function Item(fun, array) {
|
|||
|
this.fun = fun;
|
|||
|
this.array = array;
|
|||
|
}
|
|||
|
Item.prototype.run = function () {
|
|||
|
this.fun.apply(null, this.array);
|
|||
|
};
|
|||
|
process.title = "browser";
|
|||
|
process.browser = true;
|
|||
|
process.env = {};
|
|||
|
process.argv = [];
|
|||
|
process.version = ""; // empty string to avoid regexp issues
|
|||
|
process.versions = {};
|
|||
|
|
|||
|
function noop() {}
|
|||
|
|
|||
|
process.on = noop;
|
|||
|
process.addListener = noop;
|
|||
|
process.once = noop;
|
|||
|
process.off = noop;
|
|||
|
process.removeListener = noop;
|
|||
|
process.removeAllListeners = noop;
|
|||
|
process.emit = noop;
|
|||
|
process.prependListener = noop;
|
|||
|
process.prependOnceListener = noop;
|
|||
|
|
|||
|
process.listeners = function (name) {
|
|||
|
return [];
|
|||
|
};
|
|||
|
|
|||
|
process.binding = function (name) {
|
|||
|
throw new Error("process.binding is not supported");
|
|||
|
};
|
|||
|
|
|||
|
process.cwd = function () {
|
|||
|
return "/";
|
|||
|
};
|
|||
|
process.chdir = function (dir) {
|
|||
|
throw new Error("process.chdir is not supported");
|
|||
|
};
|
|||
|
process.umask = function () {
|
|||
|
return 0;
|
|||
|
};
|
|||
|
},
|
|||
|
{},
|
|||
|
],
|
|||
|
25: [
|
|||
|
function (require, module, exports) {
|
|||
|
// Underscore.js 1.8.3
|
|||
|
// http://underscorejs.org
|
|||
|
// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|||
|
// Underscore may be freely distributed under the MIT license.
|
|||
|
|
|||
|
(function () {
|
|||
|
// Baseline setup
|
|||
|
// --------------
|
|||
|
|
|||
|
// Establish the root object, `window` in the browser, or `exports` on the server.
|
|||
|
var root = this;
|
|||
|
|
|||
|
// Save the previous value of the `_` variable.
|
|||
|
var previousUnderscore = root._;
|
|||
|
|
|||
|
// Save bytes in the minified (but not gzipped) version:
|
|||
|
var ArrayProto = Array.prototype,
|
|||
|
ObjProto = Object.prototype,
|
|||
|
FuncProto = Function.prototype;
|
|||
|
|
|||
|
// Create quick reference variables for speed access to core prototypes.
|
|||
|
var push = ArrayProto.push,
|
|||
|
slice = ArrayProto.slice,
|
|||
|
toString = ObjProto.toString,
|
|||
|
hasOwnProperty = ObjProto.hasOwnProperty;
|
|||
|
|
|||
|
// All **ECMAScript 5** native function implementations that we hope to use
|
|||
|
// are declared here.
|
|||
|
var nativeIsArray = Array.isArray,
|
|||
|
nativeKeys = Object.keys,
|
|||
|
nativeBind = FuncProto.bind,
|
|||
|
nativeCreate = Object.create;
|
|||
|
|
|||
|
// Naked function reference for surrogate-prototype-swapping.
|
|||
|
var Ctor = function () {};
|
|||
|
|
|||
|
// Create a safe reference to the Underscore object for use below.
|
|||
|
var _ = function (obj) {
|
|||
|
if (obj instanceof _) return obj;
|
|||
|
if (!(this instanceof _)) return new _(obj);
|
|||
|
this._wrapped = obj;
|
|||
|
};
|
|||
|
|
|||
|
// Export the Underscore object for **Node.js**, with
|
|||
|
// backwards-compatibility for the old `require()` API. If we're in
|
|||
|
// the browser, add `_` as a global object.
|
|||
|
if (typeof exports !== "undefined") {
|
|||
|
if (typeof module !== "undefined" && module.exports) {
|
|||
|
exports = module.exports = _;
|
|||
|
}
|
|||
|
exports._ = _;
|
|||
|
} else {
|
|||
|
root._ = _;
|
|||
|
}
|
|||
|
|
|||
|
// Current version.
|
|||
|
_.VERSION = "1.8.3";
|
|||
|
|
|||
|
// Internal function that returns an efficient (for current engines) version
|
|||
|
// of the passed-in callback, to be repeatedly applied in other Underscore
|
|||
|
// functions.
|
|||
|
var optimizeCb = function (func, context, argCount) {
|
|||
|
if (context === void 0) return func;
|
|||
|
switch (argCount == null ? 3 : argCount) {
|
|||
|
case 1:
|
|||
|
return function (value) {
|
|||
|
return func.call(context, value);
|
|||
|
};
|
|||
|
case 2:
|
|||
|
return function (value, other) {
|
|||
|
return func.call(context, value, other);
|
|||
|
};
|
|||
|
case 3:
|
|||
|
return function (value, index, collection) {
|
|||
|
return func.call(context, value, index, collection);
|
|||
|
};
|
|||
|
case 4:
|
|||
|
return function (accumulator, value, index, collection) {
|
|||
|
return func.call(
|
|||
|
context,
|
|||
|
accumulator,
|
|||
|
value,
|
|||
|
index,
|
|||
|
collection
|
|||
|
);
|
|||
|
};
|
|||
|
}
|
|||
|
return function () {
|
|||
|
return func.apply(context, arguments);
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// A mostly-internal function to generate callbacks that can be applied
|
|||
|
// to each element in a collection, returning the desired result — either
|
|||
|
// identity, an arbitrary callback, a property matcher, or a property accessor.
|
|||
|
var cb = function (value, context, argCount) {
|
|||
|
if (value == null) return _.identity;
|
|||
|
if (_.isFunction(value))
|
|||
|
return optimizeCb(value, context, argCount);
|
|||
|
if (_.isObject(value)) return _.matcher(value);
|
|||
|
return _.property(value);
|
|||
|
};
|
|||
|
_.iteratee = function (value, context) {
|
|||
|
return cb(value, context, Infinity);
|
|||
|
};
|
|||
|
|
|||
|
// An internal function for creating assigner functions.
|
|||
|
var createAssigner = function (keysFunc, undefinedOnly) {
|
|||
|
return function (obj) {
|
|||
|
var length = arguments.length;
|
|||
|
if (length < 2 || obj == null) return obj;
|
|||
|
for (var index = 1; index < length; index++) {
|
|||
|
var source = arguments[index],
|
|||
|
keys = keysFunc(source),
|
|||
|
l = keys.length;
|
|||
|
for (var i = 0; i < l; i++) {
|
|||
|
var key = keys[i];
|
|||
|
if (!undefinedOnly || obj[key] === void 0)
|
|||
|
obj[key] = source[key];
|
|||
|
}
|
|||
|
}
|
|||
|
return obj;
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// An internal function for creating a new object that inherits from another.
|
|||
|
var baseCreate = function (prototype) {
|
|||
|
if (!_.isObject(prototype)) return {};
|
|||
|
if (nativeCreate) return nativeCreate(prototype);
|
|||
|
Ctor.prototype = prototype;
|
|||
|
var result = new Ctor();
|
|||
|
Ctor.prototype = null;
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
var property = function (key) {
|
|||
|
return function (obj) {
|
|||
|
return obj == null ? void 0 : obj[key];
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// Helper for collection methods to determine whether a collection
|
|||
|
// should be iterated as an array or as an object
|
|||
|
// Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
|
|||
|
// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
|
|||
|
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
|
|||
|
var getLength = property("length");
|
|||
|
var isArrayLike = function (collection) {
|
|||
|
var length = getLength(collection);
|
|||
|
return (
|
|||
|
typeof length == "number" &&
|
|||
|
length >= 0 &&
|
|||
|
length <= MAX_ARRAY_INDEX
|
|||
|
);
|
|||
|
};
|
|||
|
|
|||
|
// Collection Functions
|
|||
|
// --------------------
|
|||
|
|
|||
|
// The cornerstone, an `each` implementation, aka `forEach`.
|
|||
|
// Handles raw objects in addition to array-likes. Treats all
|
|||
|
// sparse array-likes as if they were dense.
|
|||
|
_.each = _.forEach = function (obj, iteratee, context) {
|
|||
|
iteratee = optimizeCb(iteratee, context);
|
|||
|
var i, length;
|
|||
|
if (isArrayLike(obj)) {
|
|||
|
for (i = 0, length = obj.length; i < length; i++) {
|
|||
|
iteratee(obj[i], i, obj);
|
|||
|
}
|
|||
|
} else {
|
|||
|
var keys = _.keys(obj);
|
|||
|
for (i = 0, length = keys.length; i < length; i++) {
|
|||
|
iteratee(obj[keys[i]], keys[i], obj);
|
|||
|
}
|
|||
|
}
|
|||
|
return obj;
|
|||
|
};
|
|||
|
|
|||
|
// Return the results of applying the iteratee to each element.
|
|||
|
_.map = _.collect = function (obj, iteratee, context) {
|
|||
|
iteratee = cb(iteratee, context);
|
|||
|
var keys = !isArrayLike(obj) && _.keys(obj),
|
|||
|
length = (keys || obj).length,
|
|||
|
results = Array(length);
|
|||
|
for (var index = 0; index < length; index++) {
|
|||
|
var currentKey = keys ? keys[index] : index;
|
|||
|
results[index] = iteratee(obj[currentKey], currentKey, obj);
|
|||
|
}
|
|||
|
return results;
|
|||
|
};
|
|||
|
|
|||
|
// Create a reducing function iterating left or right.
|
|||
|
function createReduce(dir) {
|
|||
|
// Optimized iterator function as using arguments.length
|
|||
|
// in the main function will deoptimize the, see #1991.
|
|||
|
function iterator(obj, iteratee, memo, keys, index, length) {
|
|||
|
for (; index >= 0 && index < length; index += dir) {
|
|||
|
var currentKey = keys ? keys[index] : index;
|
|||
|
memo = iteratee(memo, obj[currentKey], currentKey, obj);
|
|||
|
}
|
|||
|
return memo;
|
|||
|
}
|
|||
|
|
|||
|
return function (obj, iteratee, memo, context) {
|
|||
|
iteratee = optimizeCb(iteratee, context, 4);
|
|||
|
var keys = !isArrayLike(obj) && _.keys(obj),
|
|||
|
length = (keys || obj).length,
|
|||
|
index = dir > 0 ? 0 : length - 1;
|
|||
|
// Determine the initial value if none is provided.
|
|||
|
if (arguments.length < 3) {
|
|||
|
memo = obj[keys ? keys[index] : index];
|
|||
|
index += dir;
|
|||
|
}
|
|||
|
return iterator(obj, iteratee, memo, keys, index, length);
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
|||
|
// or `foldl`.
|
|||
|
_.reduce = _.foldl = _.inject = createReduce(1);
|
|||
|
|
|||
|
// The right-associative version of reduce, also known as `foldr`.
|
|||
|
_.reduceRight = _.foldr = createReduce(-1);
|
|||
|
|
|||
|
// Return the first value which passes a truth test. Aliased as `detect`.
|
|||
|
_.find = _.detect = function (obj, predicate, context) {
|
|||
|
var key;
|
|||
|
if (isArrayLike(obj)) {
|
|||
|
key = _.findIndex(obj, predicate, context);
|
|||
|
} else {
|
|||
|
key = _.findKey(obj, predicate, context);
|
|||
|
}
|
|||
|
if (key !== void 0 && key !== -1) return obj[key];
|
|||
|
};
|
|||
|
|
|||
|
// Return all the elements that pass a truth test.
|
|||
|
// Aliased as `select`.
|
|||
|
_.filter = _.select = function (obj, predicate, context) {
|
|||
|
var results = [];
|
|||
|
predicate = cb(predicate, context);
|
|||
|
_.each(obj, function (value, index, list) {
|
|||
|
if (predicate(value, index, list)) results.push(value);
|
|||
|
});
|
|||
|
return results;
|
|||
|
};
|
|||
|
|
|||
|
// Return all the elements for which a truth test fails.
|
|||
|
_.reject = function (obj, predicate, context) {
|
|||
|
return _.filter(obj, _.negate(cb(predicate)), context);
|
|||
|
};
|
|||
|
|
|||
|
// Determine whether all of the elements match a truth test.
|
|||
|
// Aliased as `all`.
|
|||
|
_.every = _.all = function (obj, predicate, context) {
|
|||
|
predicate = cb(predicate, context);
|
|||
|
var keys = !isArrayLike(obj) && _.keys(obj),
|
|||
|
length = (keys || obj).length;
|
|||
|
for (var index = 0; index < length; index++) {
|
|||
|
var currentKey = keys ? keys[index] : index;
|
|||
|
if (!predicate(obj[currentKey], currentKey, obj)) return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
// Determine if at least one element in the object matches a truth test.
|
|||
|
// Aliased as `any`.
|
|||
|
_.some = _.any = function (obj, predicate, context) {
|
|||
|
predicate = cb(predicate, context);
|
|||
|
var keys = !isArrayLike(obj) && _.keys(obj),
|
|||
|
length = (keys || obj).length;
|
|||
|
for (var index = 0; index < length; index++) {
|
|||
|
var currentKey = keys ? keys[index] : index;
|
|||
|
if (predicate(obj[currentKey], currentKey, obj)) return true;
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
// Determine if the array or object contains a given item (using `===`).
|
|||
|
// Aliased as `includes` and `include`.
|
|||
|
_.contains = _.includes = _.include = function (
|
|||
|
obj,
|
|||
|
item,
|
|||
|
fromIndex,
|
|||
|
guard
|
|||
|
) {
|
|||
|
if (!isArrayLike(obj)) obj = _.values(obj);
|
|||
|
if (typeof fromIndex != "number" || guard) fromIndex = 0;
|
|||
|
return _.indexOf(obj, item, fromIndex) >= 0;
|
|||
|
};
|
|||
|
|
|||
|
// Invoke a method (with arguments) on every item in a collection.
|
|||
|
_.invoke = function (obj, method) {
|
|||
|
var args = slice.call(arguments, 2);
|
|||
|
var isFunc = _.isFunction(method);
|
|||
|
return _.map(obj, function (value) {
|
|||
|
var func = isFunc ? method : value[method];
|
|||
|
return func == null ? func : func.apply(value, args);
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
// Convenience version of a common use case of `map`: fetching a property.
|
|||
|
_.pluck = function (obj, key) {
|
|||
|
return _.map(obj, _.property(key));
|
|||
|
};
|
|||
|
|
|||
|
// Convenience version of a common use case of `filter`: selecting only objects
|
|||
|
// containing specific `key:value` pairs.
|
|||
|
_.where = function (obj, attrs) {
|
|||
|
return _.filter(obj, _.matcher(attrs));
|
|||
|
};
|
|||
|
|
|||
|
// Convenience version of a common use case of `find`: getting the first object
|
|||
|
// containing specific `key:value` pairs.
|
|||
|
_.findWhere = function (obj, attrs) {
|
|||
|
return _.find(obj, _.matcher(attrs));
|
|||
|
};
|
|||
|
|
|||
|
// Return the maximum element (or element-based computation).
|
|||
|
_.max = function (obj, iteratee, context) {
|
|||
|
var result = -Infinity,
|
|||
|
lastComputed = -Infinity,
|
|||
|
value,
|
|||
|
computed;
|
|||
|
if (iteratee == null && obj != null) {
|
|||
|
obj = isArrayLike(obj) ? obj : _.values(obj);
|
|||
|
for (var i = 0, length = obj.length; i < length; i++) {
|
|||
|
value = obj[i];
|
|||
|
if (value > result) {
|
|||
|
result = value;
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
iteratee = cb(iteratee, context);
|
|||
|
_.each(obj, function (value, index, list) {
|
|||
|
computed = iteratee(value, index, list);
|
|||
|
if (
|
|||
|
computed > lastComputed ||
|
|||
|
(computed === -Infinity && result === -Infinity)
|
|||
|
) {
|
|||
|
result = value;
|
|||
|
lastComputed = computed;
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
// Return the minimum element (or element-based computation).
|
|||
|
_.min = function (obj, iteratee, context) {
|
|||
|
var result = Infinity,
|
|||
|
lastComputed = Infinity,
|
|||
|
value,
|
|||
|
computed;
|
|||
|
if (iteratee == null && obj != null) {
|
|||
|
obj = isArrayLike(obj) ? obj : _.values(obj);
|
|||
|
for (var i = 0, length = obj.length; i < length; i++) {
|
|||
|
value = obj[i];
|
|||
|
if (value < result) {
|
|||
|
result = value;
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
iteratee = cb(iteratee, context);
|
|||
|
_.each(obj, function (value, index, list) {
|
|||
|
computed = iteratee(value, index, list);
|
|||
|
if (
|
|||
|
computed < lastComputed ||
|
|||
|
(computed === Infinity && result === Infinity)
|
|||
|
) {
|
|||
|
result = value;
|
|||
|
lastComputed = computed;
|
|||
|
}
|
|||
|
});
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
// Shuffle a collection, using the modern version of the
|
|||
|
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
|
|||
|
_.shuffle = function (obj) {
|
|||
|
var set = isArrayLike(obj) ? obj : _.values(obj);
|
|||
|
var length = set.length;
|
|||
|
var shuffled = Array(length);
|
|||
|
for (var index = 0, rand; index < length; index++) {
|
|||
|
rand = _.random(0, index);
|
|||
|
if (rand !== index) shuffled[index] = shuffled[rand];
|
|||
|
shuffled[rand] = set[index];
|
|||
|
}
|
|||
|
return shuffled;
|
|||
|
};
|
|||
|
|
|||
|
// Sample **n** random values from a collection.
|
|||
|
// If **n** is not specified, returns a single random element.
|
|||
|
// The internal `guard` argument allows it to work with `map`.
|
|||
|
_.sample = function (obj, n, guard) {
|
|||
|
if (n == null || guard) {
|
|||
|
if (!isArrayLike(obj)) obj = _.values(obj);
|
|||
|
return obj[_.random(obj.length - 1)];
|
|||
|
}
|
|||
|
return _.shuffle(obj).slice(0, Math.max(0, n));
|
|||
|
};
|
|||
|
|
|||
|
// Sort the object's values by a criterion produced by an iteratee.
|
|||
|
_.sortBy = function (obj, iteratee, context) {
|
|||
|
iteratee = cb(iteratee, context);
|
|||
|
return _.pluck(
|
|||
|
_.map(obj, function (value, index, list) {
|
|||
|
return {
|
|||
|
value: value,
|
|||
|
index: index,
|
|||
|
criteria: iteratee(value, index, list),
|
|||
|
};
|
|||
|
}).sort(function (left, right) {
|
|||
|
var a = left.criteria;
|
|||
|
var b = right.criteria;
|
|||
|
if (a !== b) {
|
|||
|
if (a > b || a === void 0) return 1;
|
|||
|
if (a < b || b === void 0) return -1;
|
|||
|
}
|
|||
|
return left.index - right.index;
|
|||
|
}),
|
|||
|
"value"
|
|||
|
);
|
|||
|
};
|
|||
|
|
|||
|
// An internal function used for aggregate "group by" operations.
|
|||
|
var group = function (behavior) {
|
|||
|
return function (obj, iteratee, context) {
|
|||
|
var result = {};
|
|||
|
iteratee = cb(iteratee, context);
|
|||
|
_.each(obj, function (value, index) {
|
|||
|
var key = iteratee(value, index, obj);
|
|||
|
behavior(result, value, key);
|
|||
|
});
|
|||
|
return result;
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// Groups the object's values by a criterion. Pass either a string attribute
|
|||
|
// to group by, or a function that returns the criterion.
|
|||
|
_.groupBy = group(function (result, value, key) {
|
|||
|
if (_.has(result, key)) result[key].push(value);
|
|||
|
else result[key] = [value];
|
|||
|
});
|
|||
|
|
|||
|
// Indexes the object's values by a criterion, similar to `groupBy`, but for
|
|||
|
// when you know that your index values will be unique.
|
|||
|
_.indexBy = group(function (result, value, key) {
|
|||
|
result[key] = value;
|
|||
|
});
|
|||
|
|
|||
|
// Counts instances of an object that group by a certain criterion. Pass
|
|||
|
// either a string attribute to count by, or a function that returns the
|
|||
|
// criterion.
|
|||
|
_.countBy = group(function (result, value, key) {
|
|||
|
if (_.has(result, key)) result[key]++;
|
|||
|
else result[key] = 1;
|
|||
|
});
|
|||
|
|
|||
|
// Safely create a real, live array from anything iterable.
|
|||
|
_.toArray = function (obj) {
|
|||
|
if (!obj) return [];
|
|||
|
if (_.isArray(obj)) return slice.call(obj);
|
|||
|
if (isArrayLike(obj)) return _.map(obj, _.identity);
|
|||
|
return _.values(obj);
|
|||
|
};
|
|||
|
|
|||
|
// Return the number of elements in an object.
|
|||
|
_.size = function (obj) {
|
|||
|
if (obj == null) return 0;
|
|||
|
return isArrayLike(obj) ? obj.length : _.keys(obj).length;
|
|||
|
};
|
|||
|
|
|||
|
// Split a collection into two arrays: one whose elements all satisfy the given
|
|||
|
// predicate, and one whose elements all do not satisfy the predicate.
|
|||
|
_.partition = function (obj, predicate, context) {
|
|||
|
predicate = cb(predicate, context);
|
|||
|
var pass = [],
|
|||
|
fail = [];
|
|||
|
_.each(obj, function (value, key, obj) {
|
|||
|
(predicate(value, key, obj) ? pass : fail).push(value);
|
|||
|
});
|
|||
|
return [pass, fail];
|
|||
|
};
|
|||
|
|
|||
|
// Array Functions
|
|||
|
// ---------------
|
|||
|
|
|||
|
// Get the first element of an array. Passing **n** will return the first N
|
|||
|
// values in the array. Aliased as `head` and `take`. The **guard** check
|
|||
|
// allows it to work with `_.map`.
|
|||
|
_.first = _.head = _.take = function (array, n, guard) {
|
|||
|
if (array == null) return void 0;
|
|||
|
if (n == null || guard) return array[0];
|
|||
|
return _.initial(array, array.length - n);
|
|||
|
};
|
|||
|
|
|||
|
// Returns everything but the last entry of the array. Especially useful on
|
|||
|
// the arguments object. Passing **n** will return all the values in
|
|||
|
// the array, excluding the last N.
|
|||
|
_.initial = function (array, n, guard) {
|
|||
|
return slice.call(
|
|||
|
array,
|
|||
|
0,
|
|||
|
Math.max(0, array.length - (n == null || guard ? 1 : n))
|
|||
|
);
|
|||
|
};
|
|||
|
|
|||
|
// Get the last element of an array. Passing **n** will return the last N
|
|||
|
// values in the array.
|
|||
|
_.last = function (array, n, guard) {
|
|||
|
if (array == null) return void 0;
|
|||
|
if (n == null || guard) return array[array.length - 1];
|
|||
|
return _.rest(array, Math.max(0, array.length - n));
|
|||
|
};
|
|||
|
|
|||
|
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
|
|||
|
// Especially useful on the arguments object. Passing an **n** will return
|
|||
|
// the rest N values in the array.
|
|||
|
_.rest = _.tail = _.drop = function (array, n, guard) {
|
|||
|
return slice.call(array, n == null || guard ? 1 : n);
|
|||
|
};
|
|||
|
|
|||
|
// Trim out all falsy values from an array.
|
|||
|
_.compact = function (array) {
|
|||
|
return _.filter(array, _.identity);
|
|||
|
};
|
|||
|
|
|||
|
// Internal implementation of a recursive `flatten` function.
|
|||
|
var flatten = function (input, shallow, strict, startIndex) {
|
|||
|
var output = [],
|
|||
|
idx = 0;
|
|||
|
for (
|
|||
|
var i = startIndex || 0, length = getLength(input);
|
|||
|
i < length;
|
|||
|
i++
|
|||
|
) {
|
|||
|
var value = input[i];
|
|||
|
if (
|
|||
|
isArrayLike(value) &&
|
|||
|
(_.isArray(value) || _.isArguments(value))
|
|||
|
) {
|
|||
|
//flatten current level of array or arguments object
|
|||
|
if (!shallow) value = flatten(value, shallow, strict);
|
|||
|
var j = 0,
|
|||
|
len = value.length;
|
|||
|
output.length += len;
|
|||
|
while (j < len) {
|
|||
|
output[idx++] = value[j++];
|
|||
|
}
|
|||
|
} else if (!strict) {
|
|||
|
output[idx++] = value;
|
|||
|
}
|
|||
|
}
|
|||
|
return output;
|
|||
|
};
|
|||
|
|
|||
|
// Flatten out an array, either recursively (by default), or just one level.
|
|||
|
_.flatten = function (array, shallow) {
|
|||
|
return flatten(array, shallow, false);
|
|||
|
};
|
|||
|
|
|||
|
// Return a version of the array that does not contain the specified value(s).
|
|||
|
_.without = function (array) {
|
|||
|
return _.difference(array, slice.call(arguments, 1));
|
|||
|
};
|
|||
|
|
|||
|
// Produce a duplicate-free version of the array. If the array has already
|
|||
|
// been sorted, you have the option of using a faster algorithm.
|
|||
|
// Aliased as `unique`.
|
|||
|
_.uniq = _.unique = function (array, isSorted, iteratee, context) {
|
|||
|
if (!_.isBoolean(isSorted)) {
|
|||
|
context = iteratee;
|
|||
|
iteratee = isSorted;
|
|||
|
isSorted = false;
|
|||
|
}
|
|||
|
if (iteratee != null) iteratee = cb(iteratee, context);
|
|||
|
var result = [];
|
|||
|
var seen = [];
|
|||
|
for (var i = 0, length = getLength(array); i < length; i++) {
|
|||
|
var value = array[i],
|
|||
|
computed = iteratee ? iteratee(value, i, array) : value;
|
|||
|
if (isSorted) {
|
|||
|
if (!i || seen !== computed) result.push(value);
|
|||
|
seen = computed;
|
|||
|
} else if (iteratee) {
|
|||
|
if (!_.contains(seen, computed)) {
|
|||
|
seen.push(computed);
|
|||
|
result.push(value);
|
|||
|
}
|
|||
|
} else if (!_.contains(result, value)) {
|
|||
|
result.push(value);
|
|||
|
}
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
// Produce an array that contains the union: each distinct element from all of
|
|||
|
// the passed-in arrays.
|
|||
|
_.union = function () {
|
|||
|
return _.uniq(flatten(arguments, true, true));
|
|||
|
};
|
|||
|
|
|||
|
// Produce an array that contains every item shared between all the
|
|||
|
// passed-in arrays.
|
|||
|
_.intersection = function (array) {
|
|||
|
var result = [];
|
|||
|
var argsLength = arguments.length;
|
|||
|
for (var i = 0, length = getLength(array); i < length; i++) {
|
|||
|
var item = array[i];
|
|||
|
if (_.contains(result, item)) continue;
|
|||
|
for (var j = 1; j < argsLength; j++) {
|
|||
|
if (!_.contains(arguments[j], item)) break;
|
|||
|
}
|
|||
|
if (j === argsLength) result.push(item);
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
// Take the difference between one array and a number of other arrays.
|
|||
|
// Only the elements present in just the first array will remain.
|
|||
|
_.difference = function (array) {
|
|||
|
var rest = flatten(arguments, true, true, 1);
|
|||
|
return _.filter(array, function (value) {
|
|||
|
return !_.contains(rest, value);
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
// Zip together multiple lists into a single array -- elements that share
|
|||
|
// an index go together.
|
|||
|
_.zip = function () {
|
|||
|
return _.unzip(arguments);
|
|||
|
};
|
|||
|
|
|||
|
// Complement of _.zip. Unzip accepts an array of arrays and groups
|
|||
|
// each array's elements on shared indices
|
|||
|
_.unzip = function (array) {
|
|||
|
var length = (array && _.max(array, getLength).length) || 0;
|
|||
|
var result = Array(length);
|
|||
|
|
|||
|
for (var index = 0; index < length; index++) {
|
|||
|
result[index] = _.pluck(array, index);
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
// Converts lists into objects. Pass either a single array of `[key, value]`
|
|||
|
// pairs, or two parallel arrays of the same length -- one of keys, and one of
|
|||
|
// the corresponding values.
|
|||
|
_.object = function (list, values) {
|
|||
|
var result = {};
|
|||
|
for (var i = 0, length = getLength(list); i < length; i++) {
|
|||
|
if (values) {
|
|||
|
result[list[i]] = values[i];
|
|||
|
} else {
|
|||
|
result[list[i][0]] = list[i][1];
|
|||
|
}
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
// Generator function to create the findIndex and findLastIndex functions
|
|||
|
function createPredicateIndexFinder(dir) {
|
|||
|
return function (array, predicate, context) {
|
|||
|
predicate = cb(predicate, context);
|
|||
|
var length = getLength(array);
|
|||
|
var index = dir > 0 ? 0 : length - 1;
|
|||
|
for (; index >= 0 && index < length; index += dir) {
|
|||
|
if (predicate(array[index], index, array)) return index;
|
|||
|
}
|
|||
|
return -1;
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
// Returns the first index on an array-like that passes a predicate test
|
|||
|
_.findIndex = createPredicateIndexFinder(1);
|
|||
|
_.findLastIndex = createPredicateIndexFinder(-1);
|
|||
|
|
|||
|
// Use a comparator function to figure out the smallest index at which
|
|||
|
// an object should be inserted so as to maintain order. Uses binary search.
|
|||
|
_.sortedIndex = function (array, obj, iteratee, context) {
|
|||
|
iteratee = cb(iteratee, context, 1);
|
|||
|
var value = iteratee(obj);
|
|||
|
var low = 0,
|
|||
|
high = getLength(array);
|
|||
|
while (low < high) {
|
|||
|
var mid = Math.floor((low + high) / 2);
|
|||
|
if (iteratee(array[mid]) < value) low = mid + 1;
|
|||
|
else high = mid;
|
|||
|
}
|
|||
|
return low;
|
|||
|
};
|
|||
|
|
|||
|
// Generator function to create the indexOf and lastIndexOf functions
|
|||
|
function createIndexFinder(dir, predicateFind, sortedIndex) {
|
|||
|
return function (array, item, idx) {
|
|||
|
var i = 0,
|
|||
|
length = getLength(array);
|
|||
|
if (typeof idx == "number") {
|
|||
|
if (dir > 0) {
|
|||
|
i = idx >= 0 ? idx : Math.max(idx + length, i);
|
|||
|
} else {
|
|||
|
length =
|
|||
|
idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
|
|||
|
}
|
|||
|
} else if (sortedIndex && idx && length) {
|
|||
|
idx = sortedIndex(array, item);
|
|||
|
return array[idx] === item ? idx : -1;
|
|||
|
}
|
|||
|
if (item !== item) {
|
|||
|
idx = predicateFind(slice.call(array, i, length), _.isNaN);
|
|||
|
return idx >= 0 ? idx + i : -1;
|
|||
|
}
|
|||
|
for (
|
|||
|
idx = dir > 0 ? i : length - 1;
|
|||
|
idx >= 0 && idx < length;
|
|||
|
idx += dir
|
|||
|
) {
|
|||
|
if (array[idx] === item) return idx;
|
|||
|
}
|
|||
|
return -1;
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
// Return the position of the first occurrence of an item in an array,
|
|||
|
// or -1 if the item is not included in the array.
|
|||
|
// If the array is large and already in sort order, pass `true`
|
|||
|
// for **isSorted** to use binary search.
|
|||
|
_.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
|
|||
|
_.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
|
|||
|
|
|||
|
// Generate an integer Array containing an arithmetic progression. A port of
|
|||
|
// the native Python `range()` function. See
|
|||
|
// [the Python documentation](http://docs.python.org/library/functions.html#range).
|
|||
|
_.range = function (start, stop, step) {
|
|||
|
if (stop == null) {
|
|||
|
stop = start || 0;
|
|||
|
start = 0;
|
|||
|
}
|
|||
|
step = step || 1;
|
|||
|
|
|||
|
var length = Math.max(Math.ceil((stop - start) / step), 0);
|
|||
|
var range = Array(length);
|
|||
|
|
|||
|
for (var idx = 0; idx < length; idx++, start += step) {
|
|||
|
range[idx] = start;
|
|||
|
}
|
|||
|
|
|||
|
return range;
|
|||
|
};
|
|||
|
|
|||
|
// Function (ahem) Functions
|
|||
|
// ------------------
|
|||
|
|
|||
|
// Determines whether to execute a function as a constructor
|
|||
|
// or a normal function with the provided arguments
|
|||
|
var executeBound = function (
|
|||
|
sourceFunc,
|
|||
|
boundFunc,
|
|||
|
context,
|
|||
|
callingContext,
|
|||
|
args
|
|||
|
) {
|
|||
|
if (!(callingContext instanceof boundFunc))
|
|||
|
return sourceFunc.apply(context, args);
|
|||
|
var self = baseCreate(sourceFunc.prototype);
|
|||
|
var result = sourceFunc.apply(self, args);
|
|||
|
if (_.isObject(result)) return result;
|
|||
|
return self;
|
|||
|
};
|
|||
|
|
|||
|
// Create a function bound to a given object (assigning `this`, and arguments,
|
|||
|
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
|
|||
|
// available.
|
|||
|
_.bind = function (func, context) {
|
|||
|
if (nativeBind && func.bind === nativeBind)
|
|||
|
return nativeBind.apply(func, slice.call(arguments, 1));
|
|||
|
if (!_.isFunction(func))
|
|||
|
throw new TypeError("Bind must be called on a function");
|
|||
|
var args = slice.call(arguments, 2);
|
|||
|
var bound = function () {
|
|||
|
return executeBound(
|
|||
|
func,
|
|||
|
bound,
|
|||
|
context,
|
|||
|
this,
|
|||
|
args.concat(slice.call(arguments))
|
|||
|
);
|
|||
|
};
|
|||
|
return bound;
|
|||
|
};
|
|||
|
|
|||
|
// Partially apply a function by creating a version that has had some of its
|
|||
|
// arguments pre-filled, without changing its dynamic `this` context. _ acts
|
|||
|
// as a placeholder, allowing any combination of arguments to be pre-filled.
|
|||
|
_.partial = function (func) {
|
|||
|
var boundArgs = slice.call(arguments, 1);
|
|||
|
var bound = function () {
|
|||
|
var position = 0,
|
|||
|
length = boundArgs.length;
|
|||
|
var args = Array(length);
|
|||
|
for (var i = 0; i < length; i++) {
|
|||
|
args[i] =
|
|||
|
boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
|
|||
|
}
|
|||
|
while (position < arguments.length)
|
|||
|
args.push(arguments[position++]);
|
|||
|
return executeBound(func, bound, this, this, args);
|
|||
|
};
|
|||
|
return bound;
|
|||
|
};
|
|||
|
|
|||
|
// Bind a number of an object's methods to that object. Remaining arguments
|
|||
|
// are the method names to be bound. Useful for ensuring that all callbacks
|
|||
|
// defined on an object belong to it.
|
|||
|
_.bindAll = function (obj) {
|
|||
|
var i,
|
|||
|
length = arguments.length,
|
|||
|
key;
|
|||
|
if (length <= 1)
|
|||
|
throw new Error("bindAll must be passed function names");
|
|||
|
for (i = 1; i < length; i++) {
|
|||
|
key = arguments[i];
|
|||
|
obj[key] = _.bind(obj[key], obj);
|
|||
|
}
|
|||
|
return obj;
|
|||
|
};
|
|||
|
|
|||
|
// Memoize an expensive function by storing its results.
|
|||
|
_.memoize = function (func, hasher) {
|
|||
|
var memoize = function (key) {
|
|||
|
var cache = memoize.cache;
|
|||
|
var address =
|
|||
|
"" + (hasher ? hasher.apply(this, arguments) : key);
|
|||
|
if (!_.has(cache, address))
|
|||
|
cache[address] = func.apply(this, arguments);
|
|||
|
return cache[address];
|
|||
|
};
|
|||
|
memoize.cache = {};
|
|||
|
return memoize;
|
|||
|
};
|
|||
|
|
|||
|
// Delays a function for the given number of milliseconds, and then calls
|
|||
|
// it with the arguments supplied.
|
|||
|
_.delay = function (func, wait) {
|
|||
|
var args = slice.call(arguments, 2);
|
|||
|
return setTimeout(function () {
|
|||
|
return func.apply(null, args);
|
|||
|
}, wait);
|
|||
|
};
|
|||
|
|
|||
|
// Defers a function, scheduling it to run after the current call stack has
|
|||
|
// cleared.
|
|||
|
_.defer = _.partial(_.delay, _, 1);
|
|||
|
|
|||
|
// Returns a function, that, when invoked, will only be triggered at most once
|
|||
|
// during a given window of time. Normally, the throttled function will run
|
|||
|
// as much as it can, without ever going more than once per `wait` duration;
|
|||
|
// but if you'd like to disable the execution on the leading edge, pass
|
|||
|
// `{leading: false}`. To disable execution on the trailing edge, ditto.
|
|||
|
_.throttle = function (func, wait, options) {
|
|||
|
var context, args, result;
|
|||
|
var timeout = null;
|
|||
|
var previous = 0;
|
|||
|
if (!options) options = {};
|
|||
|
var later = function () {
|
|||
|
previous = options.leading === false ? 0 : _.now();
|
|||
|
timeout = null;
|
|||
|
result = func.apply(context, args);
|
|||
|
if (!timeout) context = args = null;
|
|||
|
};
|
|||
|
return function () {
|
|||
|
var now = _.now();
|
|||
|
if (!previous && options.leading === false) previous = now;
|
|||
|
var remaining = wait - (now - previous);
|
|||
|
context = this;
|
|||
|
args = arguments;
|
|||
|
if (remaining <= 0 || remaining > wait) {
|
|||
|
if (timeout) {
|
|||
|
clearTimeout(timeout);
|
|||
|
timeout = null;
|
|||
|
}
|
|||
|
previous = now;
|
|||
|
result = func.apply(context, args);
|
|||
|
if (!timeout) context = args = null;
|
|||
|
} else if (!timeout && options.trailing !== false) {
|
|||
|
timeout = setTimeout(later, remaining);
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// Returns a function, that, as long as it continues to be invoked, will not
|
|||
|
// be triggered. The function will be called after it stops being called for
|
|||
|
// N milliseconds. If `immediate` is passed, trigger the function on the
|
|||
|
// leading edge, instead of the trailing.
|
|||
|
_.debounce = function (func, wait, immediate) {
|
|||
|
var timeout, args, context, timestamp, result;
|
|||
|
|
|||
|
var later = function () {
|
|||
|
var last = _.now() - timestamp;
|
|||
|
|
|||
|
if (last < wait && last >= 0) {
|
|||
|
timeout = setTimeout(later, wait - last);
|
|||
|
} else {
|
|||
|
timeout = null;
|
|||
|
if (!immediate) {
|
|||
|
result = func.apply(context, args);
|
|||
|
if (!timeout) context = args = null;
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
return function () {
|
|||
|
context = this;
|
|||
|
args = arguments;
|
|||
|
timestamp = _.now();
|
|||
|
var callNow = immediate && !timeout;
|
|||
|
if (!timeout) timeout = setTimeout(later, wait);
|
|||
|
if (callNow) {
|
|||
|
result = func.apply(context, args);
|
|||
|
context = args = null;
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// Returns the first function passed as an argument to the second,
|
|||
|
// allowing you to adjust arguments, run code before and after, and
|
|||
|
// conditionally execute the original function.
|
|||
|
_.wrap = function (func, wrapper) {
|
|||
|
return _.partial(wrapper, func);
|
|||
|
};
|
|||
|
|
|||
|
// Returns a negated version of the passed-in predicate.
|
|||
|
_.negate = function (predicate) {
|
|||
|
return function () {
|
|||
|
return !predicate.apply(this, arguments);
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// Returns a function that is the composition of a list of functions, each
|
|||
|
// consuming the return value of the function that follows.
|
|||
|
_.compose = function () {
|
|||
|
var args = arguments;
|
|||
|
var start = args.length - 1;
|
|||
|
return function () {
|
|||
|
var i = start;
|
|||
|
var result = args[start].apply(this, arguments);
|
|||
|
while (i--) result = args[i].call(this, result);
|
|||
|
return result;
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// Returns a function that will only be executed on and after the Nth call.
|
|||
|
_.after = function (times, func) {
|
|||
|
return function () {
|
|||
|
if (--times < 1) {
|
|||
|
return func.apply(this, arguments);
|
|||
|
}
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// Returns a function that will only be executed up to (but not including) the Nth call.
|
|||
|
_.before = function (times, func) {
|
|||
|
var memo;
|
|||
|
return function () {
|
|||
|
if (--times > 0) {
|
|||
|
memo = func.apply(this, arguments);
|
|||
|
}
|
|||
|
if (times <= 1) func = null;
|
|||
|
return memo;
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// Returns a function that will be executed at most one time, no matter how
|
|||
|
// often you call it. Useful for lazy initialization.
|
|||
|
_.once = _.partial(_.before, 2);
|
|||
|
|
|||
|
// Object Functions
|
|||
|
// ----------------
|
|||
|
|
|||
|
// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
|
|||
|
var hasEnumBug = !{ toString: null }.propertyIsEnumerable(
|
|||
|
"toString"
|
|||
|
);
|
|||
|
var nonEnumerableProps = [
|
|||
|
"valueOf",
|
|||
|
"isPrototypeOf",
|
|||
|
"toString",
|
|||
|
"propertyIsEnumerable",
|
|||
|
"hasOwnProperty",
|
|||
|
"toLocaleString",
|
|||
|
];
|
|||
|
|
|||
|
function collectNonEnumProps(obj, keys) {
|
|||
|
var nonEnumIdx = nonEnumerableProps.length;
|
|||
|
var constructor = obj.constructor;
|
|||
|
var proto =
|
|||
|
(_.isFunction(constructor) && constructor.prototype) ||
|
|||
|
ObjProto;
|
|||
|
|
|||
|
// Constructor is a special case.
|
|||
|
var prop = "constructor";
|
|||
|
if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
|
|||
|
|
|||
|
while (nonEnumIdx--) {
|
|||
|
prop = nonEnumerableProps[nonEnumIdx];
|
|||
|
if (
|
|||
|
prop in obj &&
|
|||
|
obj[prop] !== proto[prop] &&
|
|||
|
!_.contains(keys, prop)
|
|||
|
) {
|
|||
|
keys.push(prop);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Retrieve the names of an object's own properties.
|
|||
|
// Delegates to **ECMAScript 5**'s native `Object.keys`
|
|||
|
_.keys = function (obj) {
|
|||
|
if (!_.isObject(obj)) return [];
|
|||
|
if (nativeKeys) return nativeKeys(obj);
|
|||
|
var keys = [];
|
|||
|
for (var key in obj) if (_.has(obj, key)) keys.push(key);
|
|||
|
// Ahem, IE < 9.
|
|||
|
if (hasEnumBug) collectNonEnumProps(obj, keys);
|
|||
|
return keys;
|
|||
|
};
|
|||
|
|
|||
|
// Retrieve all the property names of an object.
|
|||
|
_.allKeys = function (obj) {
|
|||
|
if (!_.isObject(obj)) return [];
|
|||
|
var keys = [];
|
|||
|
for (var key in obj) keys.push(key);
|
|||
|
// Ahem, IE < 9.
|
|||
|
if (hasEnumBug) collectNonEnumProps(obj, keys);
|
|||
|
return keys;
|
|||
|
};
|
|||
|
|
|||
|
// Retrieve the values of an object's properties.
|
|||
|
_.values = function (obj) {
|
|||
|
var keys = _.keys(obj);
|
|||
|
var length = keys.length;
|
|||
|
var values = Array(length);
|
|||
|
for (var i = 0; i < length; i++) {
|
|||
|
values[i] = obj[keys[i]];
|
|||
|
}
|
|||
|
return values;
|
|||
|
};
|
|||
|
|
|||
|
// Returns the results of applying the iteratee to each element of the object
|
|||
|
// In contrast to _.map it returns an object
|
|||
|
_.mapObject = function (obj, iteratee, context) {
|
|||
|
iteratee = cb(iteratee, context);
|
|||
|
var keys = _.keys(obj),
|
|||
|
length = keys.length,
|
|||
|
results = {},
|
|||
|
currentKey;
|
|||
|
for (var index = 0; index < length; index++) {
|
|||
|
currentKey = keys[index];
|
|||
|
results[currentKey] = iteratee(
|
|||
|
obj[currentKey],
|
|||
|
currentKey,
|
|||
|
obj
|
|||
|
);
|
|||
|
}
|
|||
|
return results;
|
|||
|
};
|
|||
|
|
|||
|
// Convert an object into a list of `[key, value]` pairs.
|
|||
|
_.pairs = function (obj) {
|
|||
|
var keys = _.keys(obj);
|
|||
|
var length = keys.length;
|
|||
|
var pairs = Array(length);
|
|||
|
for (var i = 0; i < length; i++) {
|
|||
|
pairs[i] = [keys[i], obj[keys[i]]];
|
|||
|
}
|
|||
|
return pairs;
|
|||
|
};
|
|||
|
|
|||
|
// Invert the keys and values of an object. The values must be serializable.
|
|||
|
_.invert = function (obj) {
|
|||
|
var result = {};
|
|||
|
var keys = _.keys(obj);
|
|||
|
for (var i = 0, length = keys.length; i < length; i++) {
|
|||
|
result[obj[keys[i]]] = keys[i];
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
// Return a sorted list of the function names available on the object.
|
|||
|
// Aliased as `methods`
|
|||
|
_.functions = _.methods = function (obj) {
|
|||
|
var names = [];
|
|||
|
for (var key in obj) {
|
|||
|
if (_.isFunction(obj[key])) names.push(key);
|
|||
|
}
|
|||
|
return names.sort();
|
|||
|
};
|
|||
|
|
|||
|
// Extend a given object with all the properties in passed-in object(s).
|
|||
|
_.extend = createAssigner(_.allKeys);
|
|||
|
|
|||
|
// Assigns a given object with all the own properties in the passed-in object(s)
|
|||
|
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
|
|||
|
_.extendOwn = _.assign = createAssigner(_.keys);
|
|||
|
|
|||
|
// Returns the first key on an object that passes a predicate test
|
|||
|
_.findKey = function (obj, predicate, context) {
|
|||
|
predicate = cb(predicate, context);
|
|||
|
var keys = _.keys(obj),
|
|||
|
key;
|
|||
|
for (var i = 0, length = keys.length; i < length; i++) {
|
|||
|
key = keys[i];
|
|||
|
if (predicate(obj[key], key, obj)) return key;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// Return a copy of the object only containing the whitelisted properties.
|
|||
|
_.pick = function (object, oiteratee, context) {
|
|||
|
var result = {},
|
|||
|
obj = object,
|
|||
|
iteratee,
|
|||
|
keys;
|
|||
|
if (obj == null) return result;
|
|||
|
if (_.isFunction(oiteratee)) {
|
|||
|
keys = _.allKeys(obj);
|
|||
|
iteratee = optimizeCb(oiteratee, context);
|
|||
|
} else {
|
|||
|
keys = flatten(arguments, false, false, 1);
|
|||
|
iteratee = function (value, key, obj) {
|
|||
|
return key in obj;
|
|||
|
};
|
|||
|
obj = Object(obj);
|
|||
|
}
|
|||
|
for (var i = 0, length = keys.length; i < length; i++) {
|
|||
|
var key = keys[i];
|
|||
|
var value = obj[key];
|
|||
|
if (iteratee(value, key, obj)) result[key] = value;
|
|||
|
}
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
// Return a copy of the object without the blacklisted properties.
|
|||
|
_.omit = function (obj, iteratee, context) {
|
|||
|
if (_.isFunction(iteratee)) {
|
|||
|
iteratee = _.negate(iteratee);
|
|||
|
} else {
|
|||
|
var keys = _.map(flatten(arguments, false, false, 1), String);
|
|||
|
iteratee = function (value, key) {
|
|||
|
return !_.contains(keys, key);
|
|||
|
};
|
|||
|
}
|
|||
|
return _.pick(obj, iteratee, context);
|
|||
|
};
|
|||
|
|
|||
|
// Fill in a given object with default properties.
|
|||
|
_.defaults = createAssigner(_.allKeys, true);
|
|||
|
|
|||
|
// Creates an object that inherits from the given prototype object.
|
|||
|
// If additional properties are provided then they will be added to the
|
|||
|
// created object.
|
|||
|
_.create = function (prototype, props) {
|
|||
|
var result = baseCreate(prototype);
|
|||
|
if (props) _.extendOwn(result, props);
|
|||
|
return result;
|
|||
|
};
|
|||
|
|
|||
|
// Create a (shallow-cloned) duplicate of an object.
|
|||
|
_.clone = function (obj) {
|
|||
|
if (!_.isObject(obj)) return obj;
|
|||
|
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
|
|||
|
};
|
|||
|
|
|||
|
// Invokes interceptor with the obj, and then returns obj.
|
|||
|
// The primary purpose of this method is to "tap into" a method chain, in
|
|||
|
// order to perform operations on intermediate results within the chain.
|
|||
|
_.tap = function (obj, interceptor) {
|
|||
|
interceptor(obj);
|
|||
|
return obj;
|
|||
|
};
|
|||
|
|
|||
|
// Returns whether an object has a given set of `key:value` pairs.
|
|||
|
_.isMatch = function (object, attrs) {
|
|||
|
var keys = _.keys(attrs),
|
|||
|
length = keys.length;
|
|||
|
if (object == null) return !length;
|
|||
|
var obj = Object(object);
|
|||
|
for (var i = 0; i < length; i++) {
|
|||
|
var key = keys[i];
|
|||
|
if (attrs[key] !== obj[key] || !(key in obj)) return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
// Internal recursive comparison function for `isEqual`.
|
|||
|
var eq = function (a, b, aStack, bStack) {
|
|||
|
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
|||
|
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
|
|||
|
if (a === b) return a !== 0 || 1 / a === 1 / b;
|
|||
|
// A strict comparison is necessary because `null == undefined`.
|
|||
|
if (a == null || b == null) return a === b;
|
|||
|
// Unwrap any wrapped objects.
|
|||
|
if (a instanceof _) a = a._wrapped;
|
|||
|
if (b instanceof _) b = b._wrapped;
|
|||
|
// Compare `[[Class]]` names.
|
|||
|
var className = toString.call(a);
|
|||
|
if (className !== toString.call(b)) return false;
|
|||
|
switch (className) {
|
|||
|
// Strings, numbers, regular expressions, dates, and booleans are compared by value.
|
|||
|
case "[object RegExp]":
|
|||
|
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
|
|||
|
case "[object String]":
|
|||
|
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
|
|||
|
// equivalent to `new String("5")`.
|
|||
|
return "" + a === "" + b;
|
|||
|
case "[object Number]":
|
|||
|
// `NaN`s are equivalent, but non-reflexive.
|
|||
|
// Object(NaN) is equivalent to NaN
|
|||
|
if (+a !== +a) return +b !== +b;
|
|||
|
// An `egal` comparison is performed for other numeric values.
|
|||
|
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
|
|||
|
case "[object Date]":
|
|||
|
case "[object Boolean]":
|
|||
|
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
|
|||
|
// millisecond representations. Note that invalid dates with millisecond representations
|
|||
|
// of `NaN` are not equivalent.
|
|||
|
return +a === +b;
|
|||
|
}
|
|||
|
|
|||
|
var areArrays = className === "[object Array]";
|
|||
|
if (!areArrays) {
|
|||
|
if (typeof a != "object" || typeof b != "object") return false;
|
|||
|
|
|||
|
// Objects with different constructors are not equivalent, but `Object`s or `Array`s
|
|||
|
// from different frames are.
|
|||
|
var aCtor = a.constructor,
|
|||
|
bCtor = b.constructor;
|
|||
|
if (
|
|||
|
aCtor !== bCtor &&
|
|||
|
!(
|
|||
|
_.isFunction(aCtor) &&
|
|||
|
aCtor instanceof aCtor &&
|
|||
|
_.isFunction(bCtor) &&
|
|||
|
bCtor instanceof bCtor
|
|||
|
) &&
|
|||
|
"constructor" in a &&
|
|||
|
"constructor" in b
|
|||
|
) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
|||
|
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
|||
|
|
|||
|
// Initializing stack of traversed objects.
|
|||
|
// It's done here since we only need them for objects and arrays comparison.
|
|||
|
aStack = aStack || [];
|
|||
|
bStack = bStack || [];
|
|||
|
var length = aStack.length;
|
|||
|
while (length--) {
|
|||
|
// Linear search. Performance is inversely proportional to the number of
|
|||
|
// unique nested structures.
|
|||
|
if (aStack[length] === a) return bStack[length] === b;
|
|||
|
}
|
|||
|
|
|||
|
// Add the first object to the stack of traversed objects.
|
|||
|
aStack.push(a);
|
|||
|
bStack.push(b);
|
|||
|
|
|||
|
// Recursively compare objects and arrays.
|
|||
|
if (areArrays) {
|
|||
|
// Compare array lengths to determine if a deep comparison is necessary.
|
|||
|
length = a.length;
|
|||
|
if (length !== b.length) return false;
|
|||
|
// Deep compare the contents, ignoring non-numeric properties.
|
|||
|
while (length--) {
|
|||
|
if (!eq(a[length], b[length], aStack, bStack)) return false;
|
|||
|
}
|
|||
|
} else {
|
|||
|
// Deep compare objects.
|
|||
|
var keys = _.keys(a),
|
|||
|
key;
|
|||
|
length = keys.length;
|
|||
|
// Ensure that both objects contain the same number of properties before comparing deep equality.
|
|||
|
if (_.keys(b).length !== length) return false;
|
|||
|
while (length--) {
|
|||
|
// Deep compare each member
|
|||
|
key = keys[length];
|
|||
|
if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack)))
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
// Remove the first object from the stack of traversed objects.
|
|||
|
aStack.pop();
|
|||
|
bStack.pop();
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
// Perform a deep comparison to check if two objects are equal.
|
|||
|
_.isEqual = function (a, b) {
|
|||
|
return eq(a, b);
|
|||
|
};
|
|||
|
|
|||
|
// Is a given array, string, or object empty?
|
|||
|
// An "empty" object has no enumerable own-properties.
|
|||
|
_.isEmpty = function (obj) {
|
|||
|
if (obj == null) return true;
|
|||
|
if (
|
|||
|
isArrayLike(obj) &&
|
|||
|
(_.isArray(obj) || _.isString(obj) || _.isArguments(obj))
|
|||
|
)
|
|||
|
return obj.length === 0;
|
|||
|
return _.keys(obj).length === 0;
|
|||
|
};
|
|||
|
|
|||
|
// Is a given value a DOM element?
|
|||
|
_.isElement = function (obj) {
|
|||
|
return !!(obj && obj.nodeType === 1);
|
|||
|
};
|
|||
|
|
|||
|
// Is a given value an array?
|
|||
|
// Delegates to ECMA5's native Array.isArray
|
|||
|
_.isArray =
|
|||
|
nativeIsArray ||
|
|||
|
function (obj) {
|
|||
|
return toString.call(obj) === "[object Array]";
|
|||
|
};
|
|||
|
|
|||
|
// Is a given variable an object?
|
|||
|
_.isObject = function (obj) {
|
|||
|
var type = typeof obj;
|
|||
|
return type === "function" || (type === "object" && !!obj);
|
|||
|
};
|
|||
|
|
|||
|
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
|
|||
|
_.each(
|
|||
|
[
|
|||
|
"Arguments",
|
|||
|
"Function",
|
|||
|
"String",
|
|||
|
"Number",
|
|||
|
"Date",
|
|||
|
"RegExp",
|
|||
|
"Error",
|
|||
|
],
|
|||
|
function (name) {
|
|||
|
_["is" + name] = function (obj) {
|
|||
|
return toString.call(obj) === "[object " + name + "]";
|
|||
|
};
|
|||
|
}
|
|||
|
);
|
|||
|
|
|||
|
// Define a fallback version of the method in browsers (ahem, IE < 9), where
|
|||
|
// there isn't any inspectable "Arguments" type.
|
|||
|
if (!_.isArguments(arguments)) {
|
|||
|
_.isArguments = function (obj) {
|
|||
|
return _.has(obj, "callee");
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
// Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
|
|||
|
// IE 11 (#1621), and in Safari 8 (#1929).
|
|||
|
if (typeof /./ != "function" && typeof Int8Array != "object") {
|
|||
|
_.isFunction = function (obj) {
|
|||
|
return typeof obj == "function" || false;
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
// Is a given object a finite number?
|
|||
|
_.isFinite = function (obj) {
|
|||
|
return isFinite(obj) && !isNaN(parseFloat(obj));
|
|||
|
};
|
|||
|
|
|||
|
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
|
|||
|
_.isNaN = function (obj) {
|
|||
|
return _.isNumber(obj) && obj !== +obj;
|
|||
|
};
|
|||
|
|
|||
|
// Is a given value a boolean?
|
|||
|
_.isBoolean = function (obj) {
|
|||
|
return (
|
|||
|
obj === true ||
|
|||
|
obj === false ||
|
|||
|
toString.call(obj) === "[object Boolean]"
|
|||
|
);
|
|||
|
};
|
|||
|
|
|||
|
// Is a given value equal to null?
|
|||
|
_.isNull = function (obj) {
|
|||
|
return obj === null;
|
|||
|
};
|
|||
|
|
|||
|
// Is a given variable undefined?
|
|||
|
_.isUndefined = function (obj) {
|
|||
|
return obj === void 0;
|
|||
|
};
|
|||
|
|
|||
|
// Shortcut function for checking if an object has a given property directly
|
|||
|
// on itself (in other words, not on a prototype).
|
|||
|
_.has = function (obj, key) {
|
|||
|
return obj != null && hasOwnProperty.call(obj, key);
|
|||
|
};
|
|||
|
|
|||
|
// Utility Functions
|
|||
|
// -----------------
|
|||
|
|
|||
|
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
|
|||
|
// previous owner. Returns a reference to the Underscore object.
|
|||
|
_.noConflict = function () {
|
|||
|
root._ = previousUnderscore;
|
|||
|
return this;
|
|||
|
};
|
|||
|
|
|||
|
// Keep the identity function around for default iteratees.
|
|||
|
_.identity = function (value) {
|
|||
|
return value;
|
|||
|
};
|
|||
|
|
|||
|
// Predicate-generating functions. Often useful outside of Underscore.
|
|||
|
_.constant = function (value) {
|
|||
|
return function () {
|
|||
|
return value;
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
_.noop = function () {};
|
|||
|
|
|||
|
_.property = property;
|
|||
|
|
|||
|
// Generates a function for a given object that returns a given property.
|
|||
|
_.propertyOf = function (obj) {
|
|||
|
return obj == null
|
|||
|
? function () {}
|
|||
|
: function (key) {
|
|||
|
return obj[key];
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// Returns a predicate for checking whether an object has a given set of
|
|||
|
// `key:value` pairs.
|
|||
|
_.matcher = _.matches = function (attrs) {
|
|||
|
attrs = _.extendOwn({}, attrs);
|
|||
|
return function (obj) {
|
|||
|
return _.isMatch(obj, attrs);
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// Run a function **n** times.
|
|||
|
_.times = function (n, iteratee, context) {
|
|||
|
var accum = Array(Math.max(0, n));
|
|||
|
iteratee = optimizeCb(iteratee, context, 1);
|
|||
|
for (var i = 0; i < n; i++) accum[i] = iteratee(i);
|
|||
|
return accum;
|
|||
|
};
|
|||
|
|
|||
|
// Return a random integer between min and max (inclusive).
|
|||
|
_.random = function (min, max) {
|
|||
|
if (max == null) {
|
|||
|
max = min;
|
|||
|
min = 0;
|
|||
|
}
|
|||
|
return min + Math.floor(Math.random() * (max - min + 1));
|
|||
|
};
|
|||
|
|
|||
|
// A (possibly faster) way to get the current timestamp as an integer.
|
|||
|
_.now =
|
|||
|
Date.now ||
|
|||
|
function () {
|
|||
|
return new Date().getTime();
|
|||
|
};
|
|||
|
|
|||
|
// List of HTML entities for escaping.
|
|||
|
var escapeMap = {
|
|||
|
"&": "&",
|
|||
|
"<": "<",
|
|||
|
">": ">",
|
|||
|
'"': """,
|
|||
|
"'": "'",
|
|||
|
"`": "`",
|
|||
|
};
|
|||
|
var unescapeMap = _.invert(escapeMap);
|
|||
|
|
|||
|
// Functions for escaping and unescaping strings to/from HTML interpolation.
|
|||
|
var createEscaper = function (map) {
|
|||
|
var escaper = function (match) {
|
|||
|
return map[match];
|
|||
|
};
|
|||
|
// Regexes for identifying a key that needs to be escaped
|
|||
|
var source = "(?:" + _.keys(map).join("|") + ")";
|
|||
|
var testRegexp = RegExp(source);
|
|||
|
var replaceRegexp = RegExp(source, "g");
|
|||
|
return function (string) {
|
|||
|
string = string == null ? "" : "" + string;
|
|||
|
return testRegexp.test(string)
|
|||
|
? string.replace(replaceRegexp, escaper)
|
|||
|
: string;
|
|||
|
};
|
|||
|
};
|
|||
|
_.escape = createEscaper(escapeMap);
|
|||
|
_.unescape = createEscaper(unescapeMap);
|
|||
|
|
|||
|
// If the value of the named `property` is a function then invoke it with the
|
|||
|
// `object` as context; otherwise, return it.
|
|||
|
_.result = function (object, property, fallback) {
|
|||
|
var value = object == null ? void 0 : object[property];
|
|||
|
if (value === void 0) {
|
|||
|
value = fallback;
|
|||
|
}
|
|||
|
return _.isFunction(value) ? value.call(object) : value;
|
|||
|
};
|
|||
|
|
|||
|
// Generate a unique integer id (unique within the entire client session).
|
|||
|
// Useful for temporary DOM ids.
|
|||
|
var idCounter = 0;
|
|||
|
_.uniqueId = function (prefix) {
|
|||
|
var id = ++idCounter + "";
|
|||
|
return prefix ? prefix + id : id;
|
|||
|
};
|
|||
|
|
|||
|
// By default, Underscore uses ERB-style template delimiters, change the
|
|||
|
// following template settings to use alternative delimiters.
|
|||
|
_.templateSettings = {
|
|||
|
evaluate: /<%([\s\S]+?)%>/g,
|
|||
|
interpolate: /<%=([\s\S]+?)%>/g,
|
|||
|
escape: /<%-([\s\S]+?)%>/g,
|
|||
|
};
|
|||
|
|
|||
|
// When customizing `templateSettings`, if you don't want to define an
|
|||
|
// interpolation, evaluation or escaping regex, we need one that is
|
|||
|
// guaranteed not to match.
|
|||
|
var noMatch = /(.)^/;
|
|||
|
|
|||
|
// Certain characters need to be escaped so that they can be put into a
|
|||
|
// string literal.
|
|||
|
var escapes = {
|
|||
|
"'": "'",
|
|||
|
"\\": "\\",
|
|||
|
"\r": "r",
|
|||
|
"\n": "n",
|
|||
|
"\u2028": "u2028",
|
|||
|
"\u2029": "u2029",
|
|||
|
};
|
|||
|
|
|||
|
var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
|
|||
|
|
|||
|
var escapeChar = function (match) {
|
|||
|
return "\\" + escapes[match];
|
|||
|
};
|
|||
|
|
|||
|
// JavaScript micro-templating, similar to John Resig's implementation.
|
|||
|
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
|||
|
// and correctly escapes quotes within interpolated code.
|
|||
|
// NB: `oldSettings` only exists for backwards compatibility.
|
|||
|
_.template = function (text, settings, oldSettings) {
|
|||
|
if (!settings && oldSettings) settings = oldSettings;
|
|||
|
settings = _.defaults({}, settings, _.templateSettings);
|
|||
|
|
|||
|
// Combine delimiters into one regular expression via alternation.
|
|||
|
var matcher = RegExp(
|
|||
|
[
|
|||
|
(settings.escape || noMatch).source,
|
|||
|
(settings.interpolate || noMatch).source,
|
|||
|
(settings.evaluate || noMatch).source,
|
|||
|
].join("|") + "|$",
|
|||
|
"g"
|
|||
|
);
|
|||
|
|
|||
|
// Compile the template source, escaping string literals appropriately.
|
|||
|
var index = 0;
|
|||
|
var source = "__p+='";
|
|||
|
text.replace(
|
|||
|
matcher,
|
|||
|
function (match, escape, interpolate, evaluate, offset) {
|
|||
|
source += text
|
|||
|
.slice(index, offset)
|
|||
|
.replace(escaper, escapeChar);
|
|||
|
index = offset + match.length;
|
|||
|
|
|||
|
if (escape) {
|
|||
|
source +=
|
|||
|
"'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
|
|||
|
} else if (interpolate) {
|
|||
|
source +=
|
|||
|
"'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
|
|||
|
} else if (evaluate) {
|
|||
|
source += "';\n" + evaluate + "\n__p+='";
|
|||
|
}
|
|||
|
|
|||
|
// Adobe VMs need the match returned to produce the correct offest.
|
|||
|
return match;
|
|||
|
}
|
|||
|
);
|
|||
|
source += "';\n";
|
|||
|
|
|||
|
// If a variable is not specified, place data values in local scope.
|
|||
|
if (!settings.variable)
|
|||
|
source = "with(obj||{}){\n" + source + "}\n";
|
|||
|
|
|||
|
source =
|
|||
|
"var __t,__p='',__j=Array.prototype.join," +
|
|||
|
"print=function(){__p+=__j.call(arguments,'');};\n" +
|
|||
|
source +
|
|||
|
"return __p;\n";
|
|||
|
|
|||
|
try {
|
|||
|
var render = new Function(
|
|||
|
settings.variable || "obj",
|
|||
|
"_",
|
|||
|
source
|
|||
|
);
|
|||
|
} catch (e) {
|
|||
|
e.source = source;
|
|||
|
throw e;
|
|||
|
}
|
|||
|
|
|||
|
var template = function (data) {
|
|||
|
return render.call(this, data, _);
|
|||
|
};
|
|||
|
|
|||
|
// Provide the compiled source as a convenience for precompilation.
|
|||
|
var argument = settings.variable || "obj";
|
|||
|
template.source = "function(" + argument + "){\n" + source + "}";
|
|||
|
|
|||
|
return template;
|
|||
|
};
|
|||
|
|
|||
|
// Add a "chain" function. Start chaining a wrapped Underscore object.
|
|||
|
_.chain = function (obj) {
|
|||
|
var instance = _(obj);
|
|||
|
instance._chain = true;
|
|||
|
return instance;
|
|||
|
};
|
|||
|
|
|||
|
// OOP
|
|||
|
// ---------------
|
|||
|
// If Underscore is called as a function, it returns a wrapped object that
|
|||
|
// can be used OO-style. This wrapper holds altered versions of all the
|
|||
|
// underscore functions. Wrapped objects may be chained.
|
|||
|
|
|||
|
// Helper function to continue chaining intermediate results.
|
|||
|
var result = function (instance, obj) {
|
|||
|
return instance._chain ? _(obj).chain() : obj;
|
|||
|
};
|
|||
|
|
|||
|
// Add your own custom functions to the Underscore object.
|
|||
|
_.mixin = function (obj) {
|
|||
|
_.each(_.functions(obj), function (name) {
|
|||
|
var func = (_[name] = obj[name]);
|
|||
|
_.prototype[name] = function () {
|
|||
|
var args = [this._wrapped];
|
|||
|
push.apply(args, arguments);
|
|||
|
return result(this, func.apply(_, args));
|
|||
|
};
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
// Add all of the Underscore functions to the wrapper object.
|
|||
|
_.mixin(_);
|
|||
|
|
|||
|
// Add all mutator Array functions to the wrapper.
|
|||
|
_.each(
|
|||
|
["pop", "push", "reverse", "shift", "sort", "splice", "unshift"],
|
|||
|
function (name) {
|
|||
|
var method = ArrayProto[name];
|
|||
|
_.prototype[name] = function () {
|
|||
|
var obj = this._wrapped;
|
|||
|
method.apply(obj, arguments);
|
|||
|
if (
|
|||
|
(name === "shift" || name === "splice") &&
|
|||
|
obj.length === 0
|
|||
|
)
|
|||
|
delete obj[0];
|
|||
|
return result(this, obj);
|
|||
|
};
|
|||
|
}
|
|||
|
);
|
|||
|
|
|||
|
// Add all accessor Array functions to the wrapper.
|
|||
|
_.each(["concat", "join", "slice"], function (name) {
|
|||
|
var method = ArrayProto[name];
|
|||
|
_.prototype[name] = function () {
|
|||
|
return result(this, method.apply(this._wrapped, arguments));
|
|||
|
};
|
|||
|
});
|
|||
|
|
|||
|
// Extracts the result from a wrapped and chained object.
|
|||
|
_.prototype.value = function () {
|
|||
|
return this._wrapped;
|
|||
|
};
|
|||
|
|
|||
|
// Provide unwrapping proxy for some methods used in engine operations
|
|||
|
// such as arithmetic and JSON stringification.
|
|||
|
_.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
|
|||
|
|
|||
|
_.prototype.toString = function () {
|
|||
|
return "" + this._wrapped;
|
|||
|
};
|
|||
|
|
|||
|
// AMD registration happens at the end for compatibility with AMD loaders
|
|||
|
// that may not enforce next-turn semantics on modules. Even though general
|
|||
|
// practice for AMD registration is to be anonymous, underscore registers
|
|||
|
// as a named module because, like jQuery, it is a base library that is
|
|||
|
// popular enough to be bundled in a third party lib, but not be part of
|
|||
|
// an AMD load request. Those cases could generate an error when an
|
|||
|
// anonymous define() is called outside of a loader request.
|
|||
|
if (typeof define === "function" && define.amd) {
|
|||
|
define("underscore", [], function () {
|
|||
|
return _;
|
|||
|
});
|
|||
|
}
|
|||
|
}.call(this));
|
|||
|
},
|
|||
|
{},
|
|||
|
],
|
|||
|
26: [
|
|||
|
function (require, module, exports) {
|
|||
|
arguments[4][19][0].apply(exports, arguments);
|
|||
|
},
|
|||
|
{ dup: 19 },
|
|||
|
],
|
|||
|
27: [
|
|||
|
function (require, module, exports) {
|
|||
|
module.exports = function isBuffer(arg) {
|
|||
|
return (
|
|||
|
arg &&
|
|||
|
typeof arg === "object" &&
|
|||
|
typeof arg.copy === "function" &&
|
|||
|
typeof arg.fill === "function" &&
|
|||
|
typeof arg.readUInt8 === "function"
|
|||
|
);
|
|||
|
};
|
|||
|
},
|
|||
|
{},
|
|||
|
],
|
|||
|
28: [
|
|||
|
function (require, module, exports) {
|
|||
|
(function (process, global) {
|
|||
|
// Copyright Joyent, Inc. and other Node contributors.
|
|||
|
//
|
|||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|||
|
// copy of this software and associated documentation files (the
|
|||
|
// "Software"), to deal in the Software without restriction, including
|
|||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|||
|
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|||
|
// persons to whom the Software is furnished to do so, subject to the
|
|||
|
// following conditions:
|
|||
|
//
|
|||
|
// The above copyright notice and this permission notice shall be included
|
|||
|
// in all copies or substantial portions of the Software.
|
|||
|
//
|
|||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|||
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|||
|
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|||
|
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|||
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|||
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
|
|||
|
var formatRegExp = /%[sdj%]/g;
|
|||
|
exports.format = function (f) {
|
|||
|
if (!isString(f)) {
|
|||
|
var objects = [];
|
|||
|
for (var i = 0; i < arguments.length; i++) {
|
|||
|
objects.push(inspect(arguments[i]));
|
|||
|
}
|
|||
|
return objects.join(" ");
|
|||
|
}
|
|||
|
|
|||
|
var i = 1;
|
|||
|
var args = arguments;
|
|||
|
var len = args.length;
|
|||
|
var str = String(f).replace(formatRegExp, function (x) {
|
|||
|
if (x === "%%") return "%";
|
|||
|
if (i >= len) return x;
|
|||
|
switch (x) {
|
|||
|
case "%s":
|
|||
|
return String(args[i++]);
|
|||
|
case "%d":
|
|||
|
return Number(args[i++]);
|
|||
|
case "%j":
|
|||
|
try {
|
|||
|
return JSON.stringify(args[i++]);
|
|||
|
} catch (_) {
|
|||
|
return "[Circular]";
|
|||
|
}
|
|||
|
default:
|
|||
|
return x;
|
|||
|
}
|
|||
|
});
|
|||
|
for (var x = args[i]; i < len; x = args[++i]) {
|
|||
|
if (isNull(x) || !isObject(x)) {
|
|||
|
str += " " + x;
|
|||
|
} else {
|
|||
|
str += " " + inspect(x);
|
|||
|
}
|
|||
|
}
|
|||
|
return str;
|
|||
|
};
|
|||
|
|
|||
|
// Mark that a method should not be used.
|
|||
|
// Returns a modified function which warns once by default.
|
|||
|
// If --no-deprecation is set, then it is a no-op.
|
|||
|
exports.deprecate = function (fn, msg) {
|
|||
|
// Allow for deprecating things in the process of starting up.
|
|||
|
if (isUndefined(global.process)) {
|
|||
|
return function () {
|
|||
|
return exports.deprecate(fn, msg).apply(this, arguments);
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
if (process.noDeprecation === true) {
|
|||
|
return fn;
|
|||
|
}
|
|||
|
|
|||
|
var warned = false;
|
|||
|
function deprecated() {
|
|||
|
if (!warned) {
|
|||
|
if (process.throwDeprecation) {
|
|||
|
throw new Error(msg);
|
|||
|
} else if (process.traceDeprecation) {
|
|||
|
console.trace(msg);
|
|||
|
} else {
|
|||
|
console.error(msg);
|
|||
|
}
|
|||
|
warned = true;
|
|||
|
}
|
|||
|
return fn.apply(this, arguments);
|
|||
|
}
|
|||
|
|
|||
|
return deprecated;
|
|||
|
};
|
|||
|
|
|||
|
var debugs = {};
|
|||
|
var debugEnviron;
|
|||
|
exports.debuglog = function (set) {
|
|||
|
if (isUndefined(debugEnviron))
|
|||
|
debugEnviron = process.env.NODE_DEBUG || "";
|
|||
|
set = set.toUpperCase();
|
|||
|
if (!debugs[set]) {
|
|||
|
if (new RegExp("\\b" + set + "\\b", "i").test(debugEnviron)) {
|
|||
|
var pid = process.pid;
|
|||
|
debugs[set] = function () {
|
|||
|
var msg = exports.format.apply(exports, arguments);
|
|||
|
console.error("%s %d: %s", set, pid, msg);
|
|||
|
};
|
|||
|
} else {
|
|||
|
debugs[set] = function () {};
|
|||
|
}
|
|||
|
}
|
|||
|
return debugs[set];
|
|||
|
};
|
|||
|
|
|||
|
/**
|
|||
|
* Echos the value of a value. Trys to print the value out
|
|||
|
* in the best way possible given the different types.
|
|||
|
*
|
|||
|
* @param {Object} obj The object to print out.
|
|||
|
* @param {Object} opts Optional options object that alters the output.
|
|||
|
*/
|
|||
|
/* legacy: obj, showHidden, depth, colors*/
|
|||
|
function inspect(obj, opts) {
|
|||
|
// default options
|
|||
|
var ctx = {
|
|||
|
seen: [],
|
|||
|
stylize: stylizeNoColor,
|
|||
|
};
|
|||
|
// legacy...
|
|||
|
if (arguments.length >= 3) ctx.depth = arguments[2];
|
|||
|
if (arguments.length >= 4) ctx.colors = arguments[3];
|
|||
|
if (isBoolean(opts)) {
|
|||
|
// legacy...
|
|||
|
ctx.showHidden = opts;
|
|||
|
} else if (opts) {
|
|||
|
// got an "options" object
|
|||
|
exports._extend(ctx, opts);
|
|||
|
}
|
|||
|
// set default options
|
|||
|
if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
|
|||
|
if (isUndefined(ctx.depth)) ctx.depth = 2;
|
|||
|
if (isUndefined(ctx.colors)) ctx.colors = false;
|
|||
|
if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
|
|||
|
if (ctx.colors) ctx.stylize = stylizeWithColor;
|
|||
|
return formatValue(ctx, obj, ctx.depth);
|
|||
|
}
|
|||
|
exports.inspect = inspect;
|
|||
|
|
|||
|
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
|
|||
|
inspect.colors = {
|
|||
|
bold: [1, 22],
|
|||
|
italic: [3, 23],
|
|||
|
underline: [4, 24],
|
|||
|
inverse: [7, 27],
|
|||
|
white: [37, 39],
|
|||
|
grey: [90, 39],
|
|||
|
black: [30, 39],
|
|||
|
blue: [34, 39],
|
|||
|
cyan: [36, 39],
|
|||
|
green: [32, 39],
|
|||
|
magenta: [35, 39],
|
|||
|
red: [31, 39],
|
|||
|
yellow: [33, 39],
|
|||
|
};
|
|||
|
|
|||
|
// Don't use 'blue' not visible on cmd.exe
|
|||
|
inspect.styles = {
|
|||
|
special: "cyan",
|
|||
|
number: "yellow",
|
|||
|
boolean: "yellow",
|
|||
|
undefined: "grey",
|
|||
|
null: "bold",
|
|||
|
string: "green",
|
|||
|
date: "magenta",
|
|||
|
// "name": intentionally not styling
|
|||
|
regexp: "red",
|
|||
|
};
|
|||
|
|
|||
|
function stylizeWithColor(str, styleType) {
|
|||
|
var style = inspect.styles[styleType];
|
|||
|
|
|||
|
if (style) {
|
|||
|
return (
|
|||
|
"\u001b[" +
|
|||
|
inspect.colors[style][0] +
|
|||
|
"m" +
|
|||
|
str +
|
|||
|
"\u001b[" +
|
|||
|
inspect.colors[style][1] +
|
|||
|
"m"
|
|||
|
);
|
|||
|
} else {
|
|||
|
return str;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function stylizeNoColor(str, styleType) {
|
|||
|
return str;
|
|||
|
}
|
|||
|
|
|||
|
function arrayToHash(array) {
|
|||
|
var hash = {};
|
|||
|
|
|||
|
array.forEach(function (val, idx) {
|
|||
|
hash[val] = true;
|
|||
|
});
|
|||
|
|
|||
|
return hash;
|
|||
|
}
|
|||
|
|
|||
|
function formatValue(ctx, value, recurseTimes) {
|
|||
|
// Provide a hook for user-specified inspect functions.
|
|||
|
// Check that value is an object with an inspect function on it
|
|||
|
if (
|
|||
|
ctx.customInspect &&
|
|||
|
value &&
|
|||
|
isFunction(value.inspect) &&
|
|||
|
// Filter out the util module, it's inspect function is special
|
|||
|
value.inspect !== exports.inspect &&
|
|||
|
// Also filter out any prototype objects using the circular check.
|
|||
|
!(value.constructor && value.constructor.prototype === value)
|
|||
|
) {
|
|||
|
var ret = value.inspect(recurseTimes, ctx);
|
|||
|
if (!isString(ret)) {
|
|||
|
ret = formatValue(ctx, ret, recurseTimes);
|
|||
|
}
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
// Primitive types cannot have properties
|
|||
|
var primitive = formatPrimitive(ctx, value);
|
|||
|
if (primitive) {
|
|||
|
return primitive;
|
|||
|
}
|
|||
|
|
|||
|
// Look up the keys of the object.
|
|||
|
var keys = Object.keys(value);
|
|||
|
var visibleKeys = arrayToHash(keys);
|
|||
|
|
|||
|
if (ctx.showHidden) {
|
|||
|
keys = Object.getOwnPropertyNames(value);
|
|||
|
}
|
|||
|
|
|||
|
// IE doesn't make error fields non-enumerable
|
|||
|
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
|
|||
|
if (
|
|||
|
isError(value) &&
|
|||
|
(keys.indexOf("message") >= 0 ||
|
|||
|
keys.indexOf("description") >= 0)
|
|||
|
) {
|
|||
|
return formatError(value);
|
|||
|
}
|
|||
|
|
|||
|
// Some type of object without properties can be shortcutted.
|
|||
|
if (keys.length === 0) {
|
|||
|
if (isFunction(value)) {
|
|||
|
var name = value.name ? ": " + value.name : "";
|
|||
|
return ctx.stylize("[Function" + name + "]", "special");
|
|||
|
}
|
|||
|
if (isRegExp(value)) {
|
|||
|
return ctx.stylize(
|
|||
|
RegExp.prototype.toString.call(value),
|
|||
|
"regexp"
|
|||
|
);
|
|||
|
}
|
|||
|
if (isDate(value)) {
|
|||
|
return ctx.stylize(
|
|||
|
Date.prototype.toString.call(value),
|
|||
|
"date"
|
|||
|
);
|
|||
|
}
|
|||
|
if (isError(value)) {
|
|||
|
return formatError(value);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var base = "",
|
|||
|
array = false,
|
|||
|
braces = ["{", "}"];
|
|||
|
|
|||
|
// Make Array say that they are Array
|
|||
|
if (isArray(value)) {
|
|||
|
array = true;
|
|||
|
braces = ["[", "]"];
|
|||
|
}
|
|||
|
|
|||
|
// Make functions say that they are functions
|
|||
|
if (isFunction(value)) {
|
|||
|
var n = value.name ? ": " + value.name : "";
|
|||
|
base = " [Function" + n + "]";
|
|||
|
}
|
|||
|
|
|||
|
// Make RegExps say that they are RegExps
|
|||
|
if (isRegExp(value)) {
|
|||
|
base = " " + RegExp.prototype.toString.call(value);
|
|||
|
}
|
|||
|
|
|||
|
// Make dates with properties first say the date
|
|||
|
if (isDate(value)) {
|
|||
|
base = " " + Date.prototype.toUTCString.call(value);
|
|||
|
}
|
|||
|
|
|||
|
// Make error with message first say the error
|
|||
|
if (isError(value)) {
|
|||
|
base = " " + formatError(value);
|
|||
|
}
|
|||
|
|
|||
|
if (keys.length === 0 && (!array || value.length == 0)) {
|
|||
|
return braces[0] + base + braces[1];
|
|||
|
}
|
|||
|
|
|||
|
if (recurseTimes < 0) {
|
|||
|
if (isRegExp(value)) {
|
|||
|
return ctx.stylize(
|
|||
|
RegExp.prototype.toString.call(value),
|
|||
|
"regexp"
|
|||
|
);
|
|||
|
} else {
|
|||
|
return ctx.stylize("[Object]", "special");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
ctx.seen.push(value);
|
|||
|
|
|||
|
var output;
|
|||
|
if (array) {
|
|||
|
output = formatArray(
|
|||
|
ctx,
|
|||
|
value,
|
|||
|
recurseTimes,
|
|||
|
visibleKeys,
|
|||
|
keys
|
|||
|
);
|
|||
|
} else {
|
|||
|
output = keys.map(function (key) {
|
|||
|
return formatProperty(
|
|||
|
ctx,
|
|||
|
value,
|
|||
|
recurseTimes,
|
|||
|
visibleKeys,
|
|||
|
key,
|
|||
|
array
|
|||
|
);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
ctx.seen.pop();
|
|||
|
|
|||
|
return reduceToSingleString(output, base, braces);
|
|||
|
}
|
|||
|
|
|||
|
function formatPrimitive(ctx, value) {
|
|||
|
if (isUndefined(value))
|
|||
|
return ctx.stylize("undefined", "undefined");
|
|||
|
if (isString(value)) {
|
|||
|
var simple =
|
|||
|
"'" +
|
|||
|
JSON.stringify(value)
|
|||
|
.replace(/^"|"$/g, "")
|
|||
|
.replace(/'/g, "\\'")
|
|||
|
.replace(/\\"/g, '"') +
|
|||
|
"'";
|
|||
|
return ctx.stylize(simple, "string");
|
|||
|
}
|
|||
|
if (isNumber(value)) return ctx.stylize("" + value, "number");
|
|||
|
if (isBoolean(value)) return ctx.stylize("" + value, "boolean");
|
|||
|
// For some reason typeof null is "object", so special case here.
|
|||
|
if (isNull(value)) return ctx.stylize("null", "null");
|
|||
|
}
|
|||
|
|
|||
|
function formatError(value) {
|
|||
|
return "[" + Error.prototype.toString.call(value) + "]";
|
|||
|
}
|
|||
|
|
|||
|
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
|
|||
|
var output = [];
|
|||
|
for (var i = 0, l = value.length; i < l; ++i) {
|
|||
|
if (hasOwnProperty(value, String(i))) {
|
|||
|
output.push(
|
|||
|
formatProperty(
|
|||
|
ctx,
|
|||
|
value,
|
|||
|
recurseTimes,
|
|||
|
visibleKeys,
|
|||
|
String(i),
|
|||
|
true
|
|||
|
)
|
|||
|
);
|
|||
|
} else {
|
|||
|
output.push("");
|
|||
|
}
|
|||
|
}
|
|||
|
keys.forEach(function (key) {
|
|||
|
if (!key.match(/^\d+$/)) {
|
|||
|
output.push(
|
|||
|
formatProperty(
|
|||
|
ctx,
|
|||
|
value,
|
|||
|
recurseTimes,
|
|||
|
visibleKeys,
|
|||
|
key,
|
|||
|
true
|
|||
|
)
|
|||
|
);
|
|||
|
}
|
|||
|
});
|
|||
|
return output;
|
|||
|
}
|
|||
|
|
|||
|
function formatProperty(
|
|||
|
ctx,
|
|||
|
value,
|
|||
|
recurseTimes,
|
|||
|
visibleKeys,
|
|||
|
key,
|
|||
|
array
|
|||
|
) {
|
|||
|
var name, str, desc;
|
|||
|
desc = Object.getOwnPropertyDescriptor(value, key) || {
|
|||
|
value: value[key],
|
|||
|
};
|
|||
|
if (desc.get) {
|
|||
|
if (desc.set) {
|
|||
|
str = ctx.stylize("[Getter/Setter]", "special");
|
|||
|
} else {
|
|||
|
str = ctx.stylize("[Getter]", "special");
|
|||
|
}
|
|||
|
} else {
|
|||
|
if (desc.set) {
|
|||
|
str = ctx.stylize("[Setter]", "special");
|
|||
|
}
|
|||
|
}
|
|||
|
if (!hasOwnProperty(visibleKeys, key)) {
|
|||
|
name = "[" + key + "]";
|
|||
|
}
|
|||
|
if (!str) {
|
|||
|
if (ctx.seen.indexOf(desc.value) < 0) {
|
|||
|
if (isNull(recurseTimes)) {
|
|||
|
str = formatValue(ctx, desc.value, null);
|
|||
|
} else {
|
|||
|
str = formatValue(ctx, desc.value, recurseTimes - 1);
|
|||
|
}
|
|||
|
if (str.indexOf("\n") > -1) {
|
|||
|
if (array) {
|
|||
|
str = str
|
|||
|
.split("\n")
|
|||
|
.map(function (line) {
|
|||
|
return " " + line;
|
|||
|
})
|
|||
|
.join("\n")
|
|||
|
.substr(2);
|
|||
|
} else {
|
|||
|
str =
|
|||
|
"\n" +
|
|||
|
str
|
|||
|
.split("\n")
|
|||
|
.map(function (line) {
|
|||
|
return " " + line;
|
|||
|
})
|
|||
|
.join("\n");
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
str = ctx.stylize("[Circular]", "special");
|
|||
|
}
|
|||
|
}
|
|||
|
if (isUndefined(name)) {
|
|||
|
if (array && key.match(/^\d+$/)) {
|
|||
|
return str;
|
|||
|
}
|
|||
|
name = JSON.stringify("" + key);
|
|||
|
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
|
|||
|
name = name.substr(1, name.length - 2);
|
|||
|
name = ctx.stylize(name, "name");
|
|||
|
} else {
|
|||
|
name = name
|
|||
|
.replace(/'/g, "\\'")
|
|||
|
.replace(/\\"/g, '"')
|
|||
|
.replace(/(^"|"$)/g, "'");
|
|||
|
name = ctx.stylize(name, "string");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return name + ": " + str;
|
|||
|
}
|
|||
|
|
|||
|
function reduceToSingleString(output, base, braces) {
|
|||
|
var numLinesEst = 0;
|
|||
|
var length = output.reduce(function (prev, cur) {
|
|||
|
numLinesEst++;
|
|||
|
if (cur.indexOf("\n") >= 0) numLinesEst++;
|
|||
|
return prev + cur.replace(/\u001b\[\d\d?m/g, "").length + 1;
|
|||
|
}, 0);
|
|||
|
|
|||
|
if (length > 60) {
|
|||
|
return (
|
|||
|
braces[0] +
|
|||
|
(base === "" ? "" : base + "\n ") +
|
|||
|
" " +
|
|||
|
output.join(",\n ") +
|
|||
|
" " +
|
|||
|
braces[1]
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
return (
|
|||
|
braces[0] + base + " " + output.join(", ") + " " + braces[1]
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
// NOTE: These type checking functions intentionally don't use `instanceof`
|
|||
|
// because it is fragile and can be easily faked with `Object.create()`.
|
|||
|
function isArray(ar) {
|
|||
|
return Array.isArray(ar);
|
|||
|
}
|
|||
|
exports.isArray = isArray;
|
|||
|
|
|||
|
function isBoolean(arg) {
|
|||
|
return typeof arg === "boolean";
|
|||
|
}
|
|||
|
exports.isBoolean = isBoolean;
|
|||
|
|
|||
|
function isNull(arg) {
|
|||
|
return arg === null;
|
|||
|
}
|
|||
|
exports.isNull = isNull;
|
|||
|
|
|||
|
function isNullOrUndefined(arg) {
|
|||
|
return arg == null;
|
|||
|
}
|
|||
|
exports.isNullOrUndefined = isNullOrUndefined;
|
|||
|
|
|||
|
function isNumber(arg) {
|
|||
|
return typeof arg === "number";
|
|||
|
}
|
|||
|
exports.isNumber = isNumber;
|
|||
|
|
|||
|
function isString(arg) {
|
|||
|
return typeof arg === "string";
|
|||
|
}
|
|||
|
exports.isString = isString;
|
|||
|
|
|||
|
function isSymbol(arg) {
|
|||
|
return typeof arg === "symbol";
|
|||
|
}
|
|||
|
exports.isSymbol = isSymbol;
|
|||
|
|
|||
|
function isUndefined(arg) {
|
|||
|
return arg === void 0;
|
|||
|
}
|
|||
|
exports.isUndefined = isUndefined;
|
|||
|
|
|||
|
function isRegExp(re) {
|
|||
|
return isObject(re) && objectToString(re) === "[object RegExp]";
|
|||
|
}
|
|||
|
exports.isRegExp = isRegExp;
|
|||
|
|
|||
|
function isObject(arg) {
|
|||
|
return typeof arg === "object" && arg !== null;
|
|||
|
}
|
|||
|
exports.isObject = isObject;
|
|||
|
|
|||
|
function isDate(d) {
|
|||
|
return isObject(d) && objectToString(d) === "[object Date]";
|
|||
|
}
|
|||
|
exports.isDate = isDate;
|
|||
|
|
|||
|
function isError(e) {
|
|||
|
return (
|
|||
|
isObject(e) &&
|
|||
|
(objectToString(e) === "[object Error]" || e instanceof Error)
|
|||
|
);
|
|||
|
}
|
|||
|
exports.isError = isError;
|
|||
|
|
|||
|
function isFunction(arg) {
|
|||
|
return typeof arg === "function";
|
|||
|
}
|
|||
|
exports.isFunction = isFunction;
|
|||
|
|
|||
|
function isPrimitive(arg) {
|
|||
|
return (
|
|||
|
arg === null ||
|
|||
|
typeof arg === "boolean" ||
|
|||
|
typeof arg === "number" ||
|
|||
|
typeof arg === "string" ||
|
|||
|
typeof arg === "symbol" || // ES6 symbol
|
|||
|
typeof arg === "undefined"
|
|||
|
);
|
|||
|
}
|
|||
|
exports.isPrimitive = isPrimitive;
|
|||
|
|
|||
|
exports.isBuffer = require("./support/isBuffer");
|
|||
|
|
|||
|
function objectToString(o) {
|
|||
|
return Object.prototype.toString.call(o);
|
|||
|
}
|
|||
|
|
|||
|
function pad(n) {
|
|||
|
return n < 10 ? "0" + n.toString(10) : n.toString(10);
|
|||
|
}
|
|||
|
|
|||
|
var months = [
|
|||
|
"Jan",
|
|||
|
"Feb",
|
|||
|
"Mar",
|
|||
|
"Apr",
|
|||
|
"May",
|
|||
|
"Jun",
|
|||
|
"Jul",
|
|||
|
"Aug",
|
|||
|
"Sep",
|
|||
|
"Oct",
|
|||
|
"Nov",
|
|||
|
"Dec",
|
|||
|
];
|
|||
|
|
|||
|
// 26 Feb 16:19:34
|
|||
|
function timestamp() {
|
|||
|
var d = new Date();
|
|||
|
var time = [
|
|||
|
pad(d.getHours()),
|
|||
|
pad(d.getMinutes()),
|
|||
|
pad(d.getSeconds()),
|
|||
|
].join(":");
|
|||
|
return [d.getDate(), months[d.getMonth()], time].join(" ");
|
|||
|
}
|
|||
|
|
|||
|
// log is just a thin wrapper to console.log that prepends a timestamp
|
|||
|
exports.log = function () {
|
|||
|
console.log(
|
|||
|
"%s - %s",
|
|||
|
timestamp(),
|
|||
|
exports.format.apply(exports, arguments)
|
|||
|
);
|
|||
|
};
|
|||
|
|
|||
|
/**
|
|||
|
* Inherit the prototype methods from one constructor into another.
|
|||
|
*
|
|||
|
* The Function.prototype.inherits from lang.js rewritten as a standalone
|
|||
|
* function (not on Function.prototype). NOTE: If this file is to be loaded
|
|||
|
* during bootstrapping this function needs to be rewritten using some native
|
|||
|
* functions as prototype setup using normal JavaScript does not work as
|
|||
|
* expected during bootstrapping (see mirror.js in r114903).
|
|||
|
*
|
|||
|
* @param {function} ctor Constructor function which needs to inherit the
|
|||
|
* prototype.
|
|||
|
* @param {function} superCtor Constructor function to inherit prototype from.
|
|||
|
*/
|
|||
|
exports.inherits = require("inherits");
|
|||
|
|
|||
|
exports._extend = function (origin, add) {
|
|||
|
// Don't do anything if add isn't an object
|
|||
|
if (!add || !isObject(add)) return origin;
|
|||
|
|
|||
|
var keys = Object.keys(add);
|
|||
|
var i = keys.length;
|
|||
|
while (i--) {
|
|||
|
origin[keys[i]] = add[keys[i]];
|
|||
|
}
|
|||
|
return origin;
|
|||
|
};
|
|||
|
|
|||
|
function hasOwnProperty(obj, prop) {
|
|||
|
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|||
|
}
|
|||
|
}.call(
|
|||
|
this,
|
|||
|
require("_process"),
|
|||
|
typeof global !== "undefined"
|
|||
|
? global
|
|||
|
: typeof self !== "undefined"
|
|||
|
? self
|
|||
|
: typeof window !== "undefined"
|
|||
|
? window
|
|||
|
: {}
|
|||
|
));
|
|||
|
},
|
|||
|
{ "./support/isBuffer": 27, _process: 24, inherits: 26 },
|
|||
|
],
|
|||
|
29: [
|
|||
|
function (require, module, exports) {
|
|||
|
// Returns a wrapper function that returns a wrapped callback
|
|||
|
// The wrapper function should do some stuff, and return a
|
|||
|
// presumably different callback function.
|
|||
|
// This makes sure that own properties are retained, so that
|
|||
|
// decorations and such are not lost along the way.
|
|||
|
module.exports = wrappy;
|
|||
|
function wrappy(fn, cb) {
|
|||
|
if (fn && cb) return wrappy(fn)(cb);
|
|||
|
|
|||
|
if (typeof fn !== "function")
|
|||
|
throw new TypeError("need wrapper function");
|
|||
|
|
|||
|
Object.keys(fn).forEach(function (k) {
|
|||
|
wrapper[k] = fn[k];
|
|||
|
});
|
|||
|
|
|||
|
return wrapper;
|
|||
|
|
|||
|
function wrapper() {
|
|||
|
var args = new Array(arguments.length);
|
|||
|
for (var i = 0; i < args.length; i++) {
|
|||
|
args[i] = arguments[i];
|
|||
|
}
|
|||
|
var ret = fn.apply(this, args);
|
|||
|
var cb = args[args.length - 1];
|
|||
|
if (typeof ret === "function" && ret !== cb) {
|
|||
|
Object.keys(cb).forEach(function (k) {
|
|||
|
ret[k] = cb[k];
|
|||
|
});
|
|||
|
}
|
|||
|
return ret;
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
{},
|
|||
|
],
|
|||
|
},
|
|||
|
{},
|
|||
|
[7]
|
|||
|
)(7);
|
|||
|
});
|