版博士V2.0程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

471 line
14 KiB

  1. const n = /[^\0-\x7E]/;
  2. const t = /[\x2E\u3002\uFF0E\uFF61]/g;
  3. const o = {
  4. overflow: "Overflow Error",
  5. "not-basic": "Illegal Input",
  6. "invalid-input": "Invalid Input"
  7. };
  8. const e = Math.floor;
  9. const r = String.fromCharCode;
  10. function s(n2) {
  11. throw new RangeError(o[n2]);
  12. }
  13. const c = function(n2, t2) {
  14. return n2 + 22 + 75 * (n2 < 26) - ((t2 != 0) << 5);
  15. };
  16. const u = function(n2, t2, o2) {
  17. let r2 = 0;
  18. for (n2 = o2 ? e(n2 / 700) : n2 >> 1, n2 += e(n2 / t2); n2 > 455; r2 += 36) {
  19. n2 = e(n2 / 35);
  20. }
  21. return e(r2 + 36 * n2 / (n2 + 38));
  22. };
  23. function toASCII(o2) {
  24. return function(n2, o3) {
  25. const e2 = n2.split("@");
  26. let r2 = "";
  27. e2.length > 1 && (r2 = e2[0] + "@", n2 = e2[1]);
  28. const s2 = function(n3, t2) {
  29. const o4 = [];
  30. let e3 = n3.length;
  31. for (; e3--; ) {
  32. o4[e3] = t2(n3[e3]);
  33. }
  34. return o4;
  35. }((n2 = n2.replace(t, ".")).split("."), o3).join(".");
  36. return r2 + s2;
  37. }(o2, function(t2) {
  38. return n.test(t2) ? "xn--" + function(n2) {
  39. const t3 = [];
  40. const o3 = (n2 = function(n3) {
  41. const t4 = [];
  42. let o4 = 0;
  43. const e2 = n3.length;
  44. for (; o4 < e2; ) {
  45. const r2 = n3.charCodeAt(o4++);
  46. if (r2 >= 55296 && r2 <= 56319 && o4 < e2) {
  47. const e3 = n3.charCodeAt(o4++);
  48. (64512 & e3) == 56320 ? t4.push(((1023 & r2) << 10) + (1023 & e3) + 65536) : (t4.push(r2), o4--);
  49. } else {
  50. t4.push(r2);
  51. }
  52. }
  53. return t4;
  54. }(n2)).length;
  55. let f = 128;
  56. let i = 0;
  57. let l = 72;
  58. for (const o4 of n2) {
  59. o4 < 128 && t3.push(r(o4));
  60. }
  61. const h = t3.length;
  62. let p = h;
  63. for (h && t3.push("-"); p < o3; ) {
  64. let o4 = 2147483647;
  65. for (const t4 of n2) {
  66. t4 >= f && t4 < o4 && (o4 = t4);
  67. }
  68. const a = p + 1;
  69. o4 - f > e((2147483647 - i) / a) && s("overflow"), i += (o4 - f) * a, f = o4;
  70. for (const o5 of n2) {
  71. if (o5 < f && ++i > 2147483647 && s("overflow"), o5 == f) {
  72. let n3 = i;
  73. for (let o6 = 36; ; o6 += 36) {
  74. const s2 = o6 <= l ? 1 : o6 >= l + 26 ? 26 : o6 - l;
  75. if (n3 < s2) {
  76. break;
  77. }
  78. const u2 = n3 - s2;
  79. const f2 = 36 - s2;
  80. t3.push(r(c(s2 + u2 % f2, 0))), n3 = e(u2 / f2);
  81. }
  82. t3.push(r(c(n3, 0))), l = u(i, a, p == h), i = 0, ++p;
  83. }
  84. }
  85. ++i, ++f;
  86. }
  87. return t3.join("");
  88. }(t2) : t2;
  89. });
  90. }
  91. const HASH_RE = /#/g;
  92. const AMPERSAND_RE = /&/g;
  93. const SLASH_RE = /\//g;
  94. const EQUAL_RE = /=/g;
  95. const IM_RE = /\?/g;
  96. const PLUS_RE = /\+/g;
  97. const ENC_CARET_RE = /%5e/gi;
  98. const ENC_BACKTICK_RE = /%60/gi;
  99. const ENC_CURLY_OPEN_RE = /%7b/gi;
  100. const ENC_PIPE_RE = /%7c/gi;
  101. const ENC_CURLY_CLOSE_RE = /%7d/gi;
  102. const ENC_SPACE_RE = /%20/gi;
  103. const ENC_SLASH_RE = /%2f/gi;
  104. const ENC_ENC_SLASH_RE = /%252f/gi;
  105. function encode(text) {
  106. return encodeURI("" + text).replace(ENC_PIPE_RE, "|");
  107. }
  108. function encodeHash(text) {
  109. return encode(text).replace(ENC_CURLY_OPEN_RE, "{").replace(ENC_CURLY_CLOSE_RE, "}").replace(ENC_CARET_RE, "^");
  110. }
  111. function encodeQueryValue(input) {
  112. return encode(typeof input === "string" ? input : JSON.stringify(input)).replace(PLUS_RE, "%2B").replace(ENC_SPACE_RE, "+").replace(HASH_RE, "%23").replace(AMPERSAND_RE, "%26").replace(ENC_BACKTICK_RE, "`").replace(ENC_CARET_RE, "^");
  113. }
  114. function encodeQueryKey(text) {
  115. return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
  116. }
  117. function encodePath(text) {
  118. return encode(text).replace(HASH_RE, "%23").replace(IM_RE, "%3F").replace(ENC_ENC_SLASH_RE, "%2F").replace(AMPERSAND_RE, "%26").replace(PLUS_RE, "%2B");
  119. }
  120. function encodeParam(text) {
  121. return encodePath(text).replace(SLASH_RE, "%2F");
  122. }
  123. function decode(text = "") {
  124. try {
  125. return decodeURIComponent("" + text);
  126. } catch {
  127. return "" + text;
  128. }
  129. }
  130. function decodePath(text) {
  131. return decode(text.replace(ENC_SLASH_RE, "%252F"));
  132. }
  133. function decodeQueryValue(text) {
  134. return decode(text.replace(PLUS_RE, " "));
  135. }
  136. function encodeHost(name = "") {
  137. return toASCII(name);
  138. }
  139. function parseQuery(parametersString = "") {
  140. const object = {};
  141. if (parametersString[0] === "?") {
  142. parametersString = parametersString.slice(1);
  143. }
  144. for (const parameter of parametersString.split("&")) {
  145. const s = parameter.match(/([^=]+)=?(.*)/) || [];
  146. if (s.length < 2) {
  147. continue;
  148. }
  149. const key = decode(s[1]);
  150. if (key === "__proto__" || key === "constructor") {
  151. continue;
  152. }
  153. const value = decodeQueryValue(s[2] || "");
  154. if (typeof object[key] !== "undefined") {
  155. if (Array.isArray(object[key])) {
  156. object[key].push(value);
  157. } else {
  158. object[key] = [object[key], value];
  159. }
  160. } else {
  161. object[key] = value;
  162. }
  163. }
  164. return object;
  165. }
  166. function encodeQueryItem(key, value) {
  167. if (typeof value === "number" || typeof value === "boolean") {
  168. value = String(value);
  169. }
  170. if (!value) {
  171. return encodeQueryKey(key);
  172. }
  173. if (Array.isArray(value)) {
  174. return value.map((_value) => `${encodeQueryKey(key)}=${encodeQueryValue(_value)}`).join("&");
  175. }
  176. return `${encodeQueryKey(key)}=${encodeQueryValue(value)}`;
  177. }
  178. function stringifyQuery(query) {
  179. return Object.keys(query).filter((k) => query[k] !== void 0).map((k) => encodeQueryItem(k, query[k])).join("&");
  180. }
  181. class $URL {
  182. constructor(input = "") {
  183. this.query = {};
  184. if (typeof input !== "string") {
  185. throw new TypeError(
  186. `URL input should be string received ${typeof input} (${input})`
  187. );
  188. }
  189. const parsed = parseURL(input);
  190. this.protocol = decode(parsed.protocol);
  191. this.host = decode(parsed.host);
  192. this.auth = decode(parsed.auth);
  193. this.pathname = decodePath(parsed.pathname);
  194. this.query = parseQuery(parsed.search);
  195. this.hash = decode(parsed.hash);
  196. }
  197. get hostname() {
  198. return parseHost(this.host).hostname;
  199. }
  200. get port() {
  201. return parseHost(this.host).port || "";
  202. }
  203. get username() {
  204. return parseAuth(this.auth).username;
  205. }
  206. get password() {
  207. return parseAuth(this.auth).password || "";
  208. }
  209. get hasProtocol() {
  210. return this.protocol.length;
  211. }
  212. get isAbsolute() {
  213. return this.hasProtocol || this.pathname[0] === "/";
  214. }
  215. get search() {
  216. const q = stringifyQuery(this.query);
  217. return q.length > 0 ? "?" + q : "";
  218. }
  219. get searchParams() {
  220. const p = new URLSearchParams();
  221. for (const name in this.query) {
  222. const value = this.query[name];
  223. if (Array.isArray(value)) {
  224. for (const v of value) {
  225. p.append(name, v);
  226. }
  227. } else {
  228. p.append(
  229. name,
  230. typeof value === "string" ? value : JSON.stringify(value)
  231. );
  232. }
  233. }
  234. return p;
  235. }
  236. get origin() {
  237. return (this.protocol ? this.protocol + "//" : "") + encodeHost(this.host);
  238. }
  239. get fullpath() {
  240. return encodePath(this.pathname) + this.search + encodeHash(this.hash);
  241. }
  242. get encodedAuth() {
  243. if (!this.auth) {
  244. return "";
  245. }
  246. const { username, password } = parseAuth(this.auth);
  247. return encodeURIComponent(username) + (password ? ":" + encodeURIComponent(password) : "");
  248. }
  249. get href() {
  250. const auth = this.encodedAuth;
  251. const originWithAuth = (this.protocol ? this.protocol + "//" : "") + (auth ? auth + "@" : "") + encodeHost(this.host);
  252. return this.hasProtocol && this.isAbsolute ? originWithAuth + this.fullpath : this.fullpath;
  253. }
  254. append(url) {
  255. if (url.hasProtocol) {
  256. throw new Error("Cannot append a URL with protocol");
  257. }
  258. Object.assign(this.query, url.query);
  259. if (url.pathname) {
  260. this.pathname = withTrailingSlash(this.pathname) + withoutLeadingSlash(url.pathname);
  261. }
  262. if (url.hash) {
  263. this.hash = url.hash;
  264. }
  265. }
  266. toJSON() {
  267. return this.href;
  268. }
  269. toString() {
  270. return this.href;
  271. }
  272. }
  273. function isRelative(inputString) {
  274. return ["./", "../"].some((string_) => inputString.startsWith(string_));
  275. }
  276. const PROTOCOL_STRICT_REGEX = /^\w{2,}:([/\\]{1,2})/;
  277. const PROTOCOL_REGEX = /^\w{2,}:([/\\]{2})?/;
  278. const PROTOCOL_RELATIVE_REGEX = /^([/\\]\s*){2,}[^/\\]/;
  279. function hasProtocol(inputString, opts = {}) {
  280. if (typeof opts === "boolean") {
  281. opts = { acceptRelative: opts };
  282. }
  283. if (opts.strict) {
  284. return PROTOCOL_STRICT_REGEX.test(inputString);
  285. }
  286. return PROTOCOL_REGEX.test(inputString) || (opts.acceptRelative ? PROTOCOL_RELATIVE_REGEX.test(inputString) : false);
  287. }
  288. const TRAILING_SLASH_RE = /\/$|\/\?/;
  289. function hasTrailingSlash(input = "", queryParameters = false) {
  290. if (!queryParameters) {
  291. return input.endsWith("/");
  292. }
  293. return TRAILING_SLASH_RE.test(input);
  294. }
  295. function withoutTrailingSlash(input = "", queryParameters = false) {
  296. if (!queryParameters) {
  297. return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || "/";
  298. }
  299. if (!hasTrailingSlash(input, true)) {
  300. return input || "/";
  301. }
  302. const [s0, ...s] = input.split("?");
  303. return (s0.slice(0, -1) || "/") + (s.length > 0 ? `?${s.join("?")}` : "");
  304. }
  305. function withTrailingSlash(input = "", queryParameters = false) {
  306. if (!queryParameters) {
  307. return input.endsWith("/") ? input : input + "/";
  308. }
  309. if (hasTrailingSlash(input, true)) {
  310. return input || "/";
  311. }
  312. const [s0, ...s] = input.split("?");
  313. return s0 + "/" + (s.length > 0 ? `?${s.join("?")}` : "");
  314. }
  315. function hasLeadingSlash(input = "") {
  316. return input.startsWith("/");
  317. }
  318. function withoutLeadingSlash(input = "") {
  319. return (hasLeadingSlash(input) ? input.slice(1) : input) || "/";
  320. }
  321. function withLeadingSlash(input = "") {
  322. return hasLeadingSlash(input) ? input : "/" + input;
  323. }
  324. function cleanDoubleSlashes(input = "") {
  325. return input.split("://").map((string_) => string_.replace(/\/{2,}/g, "/")).join("://");
  326. }
  327. function withBase(input, base) {
  328. if (isEmptyURL(base) || hasProtocol(input)) {
  329. return input;
  330. }
  331. const _base = withoutTrailingSlash(base);
  332. if (input.startsWith(_base)) {
  333. return input;
  334. }
  335. return joinURL(_base, input);
  336. }
  337. function withoutBase(input, base) {
  338. if (isEmptyURL(base)) {
  339. return input;
  340. }
  341. const _base = withoutTrailingSlash(base);
  342. if (!input.startsWith(_base)) {
  343. return input;
  344. }
  345. const trimmed = input.slice(_base.length);
  346. return trimmed[0] === "/" ? trimmed : "/" + trimmed;
  347. }
  348. function withQuery(input, query) {
  349. const parsed = parseURL(input);
  350. const mergedQuery = { ...parseQuery(parsed.search), ...query };
  351. parsed.search = stringifyQuery(mergedQuery);
  352. return stringifyParsedURL(parsed);
  353. }
  354. function getQuery(input) {
  355. return parseQuery(parseURL(input).search);
  356. }
  357. function isEmptyURL(url) {
  358. return !url || url === "/";
  359. }
  360. function isNonEmptyURL(url) {
  361. return url && url !== "/";
  362. }
  363. function joinURL(base, ...input) {
  364. let url = base || "";
  365. for (const index of input.filter((url2) => isNonEmptyURL(url2))) {
  366. url = url ? withTrailingSlash(url) + withoutLeadingSlash(index) : index;
  367. }
  368. return url;
  369. }
  370. function withHttp(input) {
  371. return withProtocol(input, "http://");
  372. }
  373. function withHttps(input) {
  374. return withProtocol(input, "https://");
  375. }
  376. function withoutProtocol(input) {
  377. return withProtocol(input, "");
  378. }
  379. function withProtocol(input, protocol) {
  380. const match = input.match(PROTOCOL_REGEX);
  381. if (!match) {
  382. return protocol + input;
  383. }
  384. return protocol + input.slice(match[0].length);
  385. }
  386. function createURL(input) {
  387. return new $URL(input);
  388. }
  389. function normalizeURL(input) {
  390. return createURL(input).toString();
  391. }
  392. function resolveURL(base, ...input) {
  393. const url = createURL(base);
  394. for (const index of input.filter((url2) => isNonEmptyURL(url2))) {
  395. url.append(createURL(index));
  396. }
  397. return url.toString();
  398. }
  399. function isSamePath(p1, p2) {
  400. return decode(withoutTrailingSlash(p1)) === decode(withoutTrailingSlash(p2));
  401. }
  402. function isEqual(a, b, options = {}) {
  403. if (!options.trailingSlash) {
  404. a = withTrailingSlash(a);
  405. b = withTrailingSlash(b);
  406. }
  407. if (!options.leadingSlash) {
  408. a = withLeadingSlash(a);
  409. b = withLeadingSlash(b);
  410. }
  411. if (!options.encoding) {
  412. a = decode(a);
  413. b = decode(b);
  414. }
  415. return a === b;
  416. }
  417. function parseURL(input = "", defaultProto) {
  418. if (!hasProtocol(input, { acceptRelative: true })) {
  419. return defaultProto ? parseURL(defaultProto + input) : parsePath(input);
  420. }
  421. const [protocol = "", auth, hostAndPath = ""] = (input.replace(/\\/g, "/").match(/([^/:]+:)?\/\/([^/@]+@)?(.*)/) || []).splice(1);
  422. const [host = "", path = ""] = (hostAndPath.match(/([^#/?]*)(.*)?/) || []).splice(1);
  423. const { pathname, search, hash } = parsePath(
  424. path.replace(/\/(?=[A-Za-z]:)/, "")
  425. );
  426. return {
  427. protocol,
  428. auth: auth ? auth.slice(0, Math.max(0, auth.length - 1)) : "",
  429. host,
  430. pathname,
  431. search,
  432. hash
  433. };
  434. }
  435. function parsePath(input = "") {
  436. const [pathname = "", search = "", hash = ""] = (input.match(/([^#?]*)(\?[^#]*)?(#.*)?/) || []).splice(1);
  437. return {
  438. pathname,
  439. search,
  440. hash
  441. };
  442. }
  443. function parseAuth(input = "") {
  444. const [username, password] = input.split(":");
  445. return {
  446. username: decode(username),
  447. password: decode(password)
  448. };
  449. }
  450. function parseHost(input = "") {
  451. const [hostname, port] = (input.match(/([^/:]*):?(\d+)?/) || []).splice(1);
  452. return {
  453. hostname: decode(hostname),
  454. port
  455. };
  456. }
  457. function stringifyParsedURL(parsed) {
  458. const fullpath = parsed.pathname + (parsed.search ? (parsed.search.startsWith("?") ? "" : "?") + parsed.search : "") + parsed.hash;
  459. if (!parsed.protocol) {
  460. return fullpath;
  461. }
  462. return parsed.protocol + "//" + (parsed.auth ? parsed.auth + "@" : "") + parsed.host + fullpath;
  463. }
  464. export { $URL, cleanDoubleSlashes, createURL, decode, decodePath, decodeQueryValue, encode, encodeHash, encodeHost, encodeParam, encodePath, encodeQueryItem, encodeQueryKey, encodeQueryValue, getQuery, hasLeadingSlash, hasProtocol, hasTrailingSlash, isEmptyURL, isEqual, isNonEmptyURL, isRelative, isSamePath, joinURL, normalizeURL, parseAuth, parseHost, parsePath, parseQuery, parseURL, resolveURL, stringifyParsedURL, stringifyQuery, withBase, withHttp, withHttps, withLeadingSlash, withProtocol, withQuery, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutProtocol, withoutTrailingSlash };