版博士V2.0程序
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

680 строки
19 KiB

  1. // src/atRandom.ts
  2. function atRandom(things, excluding = []) {
  3. things = things.filter(
  4. (i) => typeof excluding === "function" ? excluding(i) : !excluding.includes(i)
  5. );
  6. const random = Math.floor(Math.random() * things.length);
  7. return things[random];
  8. }
  9. // src/base64.ts
  10. function toBase64(input) {
  11. const buffer = Buffer.from(input, "utf-8");
  12. return buffer.toString("base64");
  13. }
  14. function fromBase64(input, isJson = false) {
  15. const buffer = Buffer.from(input, "base64");
  16. return isJson ? JSON.parse(buffer.toString("utf-8")) : buffer.toString("utf-8");
  17. }
  18. // src/between.ts
  19. function between(start, end) {
  20. const diff = Math.abs(end - start) + 1;
  21. const random = Math.floor(Math.random() * diff);
  22. return start + random;
  23. }
  24. // src/capitalize.ts
  25. function capitalize(input) {
  26. return input.slice(0, 1).toUpperCase() + input.slice(1);
  27. }
  28. // src/pascalize.ts
  29. function pascalize(input, preserveWhitespace = void 0) {
  30. const [_, preWhite, focus, postWhite] = /^(\s*)(.*?)(\s*)$/.exec(
  31. input
  32. );
  33. const convertInteriorToCap = (i) => i.replace(/[ |_|-]+([0-9]*?[a-z|A-Z]{1})/gs, (_2, p1) => p1.toUpperCase());
  34. const startingToCap = (i) => i.replace(/^[_|-]*?([0-9]*?[a-z]{1})/gs, (_2, p1) => p1.toUpperCase());
  35. const replaceLeadingTrash = (i) => i.replace(/^[-_]/s, "");
  36. const replaceTrailingTrash = (i) => i.replace(/[-_]$/s, "");
  37. const pascal = `${preserveWhitespace ? preWhite : ""}${capitalize(
  38. replaceTrailingTrash(replaceLeadingTrash(convertInteriorToCap(startingToCap(focus))))
  39. )}${preserveWhitespace ? postWhite : ""}`;
  40. return pascal;
  41. }
  42. // src/camelize.ts
  43. function camelize(input, preserveWhitespace) {
  44. const pascal = preserveWhitespace ? pascalize(input, preserveWhitespace) : pascalize(input);
  45. const [_, preWhite, focus, postWhite] = /^(\s*)(.*?)(\s*)$/.exec(
  46. pascal
  47. );
  48. const camel = (preserveWhitespace ? preWhite : "") + focus.replace(/^.*?([0-9]*?[a-z|A-Z]{1})/s, (_2, p1) => p1.toLowerCase()) + (preserveWhitespace ? postWhite : "");
  49. return camel;
  50. ;
  51. }
  52. // src/createLookup.ts
  53. var defaultMiss = (missed) => {
  54. throw new Error(`Failure in lookup searching for "${missed}"`);
  55. };
  56. function createLookup(known, miss = defaultMiss) {
  57. return (v) => {
  58. const value = v === true ? "true" : v === false ? "false" : v;
  59. return value in known ? known[value] : miss(value);
  60. };
  61. }
  62. // src/dasherize.ts
  63. function dasherize(input, preserveWhitespace) {
  64. const [_, preWhite, focus, postWhite] = /^(\s*)(.*?)(\s*)$/.exec(input);
  65. const replaceWhitespace = (i) => i.replace(/\s/gs, "-");
  66. const replaceUppercase = (i) => i.replace(/[A-Z]/g, (c) => `-${c[0].toLowerCase()}`);
  67. const replaceLeadingDash = (i) => i.replace(/^-/s, "");
  68. const replaceTrailingDash = (i) => i.replace(/-$/s, "");
  69. const replaceUnderscore = (i) => i.replace(/_/g, "-");
  70. const removeDupDashes = (i) => i.replace(/-+/g, "-");
  71. return `${preWhite}${replaceUnderscore(
  72. replaceTrailingDash(
  73. replaceLeadingDash(removeDupDashes(replaceWhitespace(replaceUppercase(focus))))
  74. )
  75. )}${postWhite}`;
  76. }
  77. // src/types/other-types.ts
  78. var DataType = /* @__PURE__ */ ((DataType2) => {
  79. DataType2["null"] = "null";
  80. DataType2["string"] = "string";
  81. DataType2["number"] = "number";
  82. DataType2["bigint"] = "bigint";
  83. DataType2["symbol"] = "symbol";
  84. DataType2["boolean"] = "boolean";
  85. DataType2["function"] = "function";
  86. DataType2["undefined"] = "undefined";
  87. DataType2["dictionary"] = "dictionary";
  88. DataType2["object"] = "object";
  89. DataType2["array"] = "array";
  90. DataType2["stringArray"] = "string[]";
  91. DataType2["numberArray"] = "number[]";
  92. DataType2["booleanArray"] = "boolean[]";
  93. DataType2["symbolArray"] = "symbol[]";
  94. DataType2["functionArray"] = "function[]";
  95. DataType2["undefinedArray"] = "undefined[]";
  96. DataType2["nullArray"] = "null[]";
  97. DataType2["objectArray"] = "object[]";
  98. DataType2["dictionaryArray"] = "dictionary[]";
  99. return DataType2;
  100. })(DataType || {});
  101. function isNonNullObject(thingy) {
  102. return typeof thingy === "object" && thingy !== null;
  103. }
  104. // src/describe.ts
  105. function describe(data) {
  106. if (!isNonNullObject(data)) {
  107. return data === null ? "null" /* null */ : DataType[typeof data];
  108. }
  109. if (Array.isArray(data)) {
  110. if (data.length === 0) {
  111. return "array" /* array */;
  112. }
  113. const SAMPLE_SIZE = 5;
  114. const partial = data.slice(0, SAMPLE_SIZE);
  115. const elements = partial.map((p) => describe(p));
  116. return elements;
  117. }
  118. if (Object.keys(data).length === 0) {
  119. return "object" /* object */;
  120. }
  121. const dictionary = data;
  122. const dataStruct = Object.keys(dictionary).reduce((agg, key) => {
  123. return {
  124. ...agg,
  125. ...isNonNullObject(dictionary[key]) ? { [key]: describe(dictionary[key]) } : { [key]: typeof dictionary[key] }
  126. };
  127. }, {});
  128. return dataStruct;
  129. }
  130. // src/deserialize.ts
  131. function deserialize(arr) {
  132. return arr.split("\n").map((i) => JSON.parse(i));
  133. }
  134. // src/errors.ts
  135. import { createError } from "brilliant-errors";
  136. var [KnownError, isKnownError] = createError("KnownError", "NativeDash")("cardinality", "network", "invalid-type", "missing-resource", "not-allowed")()()();
  137. var [UnknownError, isUnknownError] = createError("KnownError", "NativeDash")()()()();
  138. // src/equal.ts
  139. import { dictToKv } from "inferred-types";
  140. function type(v) {
  141. return Array.isArray(v) ? "array" /* array */ : v === null ? "null" /* null */ : typeof v;
  142. }
  143. function equal(a, b, depth = 1) {
  144. const ta = type(a);
  145. const tb = type(b);
  146. if (ta !== tb) {
  147. return false;
  148. }
  149. switch (ta) {
  150. case "null" /* null */:
  151. case void 0:
  152. return true;
  153. case "boolean":
  154. case "string":
  155. case "symbol":
  156. case "number":
  157. case "bigint":
  158. return a === b;
  159. case "array" /* array */:
  160. if (a.length !== b.length) {
  161. return false;
  162. }
  163. return a.every((v, idx) => equal(v, b[idx]));
  164. case "object":
  165. const ka = dictToKv(a);
  166. const kb = dictToKv(b);
  167. if (ka.length !== kb.length) {
  168. return false;
  169. }
  170. return ka.every(
  171. (i) => type(i.value) === "object" ? depth > 0 ? equal(i.value, b[i.key], depth - 1) : false : i.value === b[i.key]
  172. );
  173. default:
  174. return a === b;
  175. }
  176. }
  177. // src/find.ts
  178. var find = (pattern, ...names) => (content) => {
  179. let re;
  180. try {
  181. re = new RegExp(pattern);
  182. } catch {
  183. throw new KnownError(
  184. `Invalid RegExp pattern passed into find(): ${pattern}`,
  185. "invalid-type/RegExp"
  186. );
  187. }
  188. if (names && names.includes("all")) {
  189. throw new KnownError(
  190. `The name "all" can not be used in find() because an "all" value will always be passed back!`,
  191. "not-allowed/named-property"
  192. );
  193. }
  194. const found = content.match(re);
  195. const arr = [];
  196. const obj = {};
  197. if (found) {
  198. for (let idx = 0; idx < found.length; idx++) {
  199. arr.push(found[idx]);
  200. if (names.length > 0) {
  201. const key = idx === 0 ? "all" : idx - 1 < names.length ? names[idx - 1] : `unknown_${idx}`;
  202. obj[key] = found[idx];
  203. }
  204. }
  205. }
  206. return found ? names.length > 0 ? {
  207. ...obj,
  208. found: true,
  209. next: () => {
  210. const nextContent = content.replace(obj.all, "");
  211. return find(pattern, ...names)(nextContent);
  212. }
  213. } : arr : names.length > 0 ? { found: false } : false;
  214. };
  215. // src/findAll.ts
  216. function reduceToFindAllResult(result) {
  217. const blob = { ...result };
  218. delete blob.found;
  219. delete blob.next;
  220. return blob;
  221. }
  222. function isNamedFind(result) {
  223. return typeof result === "object" && !Array.isArray(result);
  224. }
  225. function isUnnamedFind(result) {
  226. return !isNamedFind(result);
  227. }
  228. var findAll = (pattern, ...names) => (content) => {
  229. let re;
  230. try {
  231. re = new RegExp(pattern);
  232. } catch {
  233. throw new KnownError(
  234. `Invalid RegExp pattern passed into findAll(): ${pattern}`,
  235. "invalid-type/RegExp"
  236. );
  237. }
  238. let result = find(pattern, ...names)(content);
  239. let output = [];
  240. if (isNamedFind(result)) {
  241. const results = [];
  242. while (result.found) {
  243. results.push(reduceToFindAllResult(result));
  244. result = result.next();
  245. }
  246. output = results;
  247. }
  248. if (isUnnamedFind(result)) {
  249. const results = [];
  250. while (result) {
  251. results.push(result);
  252. const newContent = content.replace(result[0], "");
  253. result = find(pattern, ...names)(newContent);
  254. }
  255. output = results;
  256. }
  257. return output;
  258. };
  259. // src/first.ts
  260. function first(arr) {
  261. return arr.slice(0, 1)[0];
  262. }
  263. // src/firstKey.ts
  264. function firstKey(dict) {
  265. const key = Object.keys(dict).slice(0, 1).pop();
  266. return key ? key : false;
  267. }
  268. // src/flatten.ts
  269. function flatten(arr) {
  270. return arr.flat ? arr.flat() : arr.reduce((acc, val) => acc.concat(val), []);
  271. }
  272. // src/get.ts
  273. function get(obj, dotPath, defaultValue) {
  274. const parts = dotPath.split(".");
  275. let value = obj;
  276. parts.forEach((p) => {
  277. value = typeof value === "object" && Object.keys(value).includes(p) ? value[p] : void 0;
  278. });
  279. return value ? value : defaultValue;
  280. }
  281. // src/omit.ts
  282. function omit(obj, ...removals) {
  283. const untyped = removals;
  284. return Object.fromEntries(
  285. Object.entries(obj).filter(([key]) => !untyped.includes(key))
  286. );
  287. }
  288. // src/groupBy.ts
  289. function isFunction(thingy) {
  290. return typeof thingy === "function";
  291. }
  292. function groupBy(propOrFn, data) {
  293. return data.reduce((acc, i) => {
  294. if (isFunction(propOrFn)) {
  295. const [key, val] = propOrFn(i);
  296. const current = acc[key] || [];
  297. return {
  298. ...acc,
  299. [key]: current.concat(val)
  300. };
  301. } else {
  302. const key = i[propOrFn];
  303. const current = acc[key] || [];
  304. if (Array.isArray(current)) {
  305. return { ...acc, [key]: current.concat(omit(i, propOrFn)) };
  306. }
  307. }
  308. }, {});
  309. }
  310. // src/randomString.ts
  311. function randomString() {
  312. return ((1 + Math.random()) * 65536 | 0).toString(16).substring(1);
  313. }
  314. // src/uuid.ts
  315. function uuid(dasherized = true) {
  316. return dasherized ? randomString() + randomString() + "-" + randomString() + "-" + randomString() + "-" + randomString() + "-" + randomString() + randomString() + randomString() : randomString() + randomString() + randomString() + randomString() + randomString() + randomString() + randomString() + randomString();
  317. }
  318. // src/guid.ts
  319. function guid() {
  320. return uuid();
  321. }
  322. // src/hash.ts
  323. function hash(digest) {
  324. let hash2 = 0, i, chr;
  325. for (i = 0; i < digest.length; i++) {
  326. chr = digest.charCodeAt(i);
  327. hash2 = (hash2 << 5) - hash2 + chr;
  328. hash2 |= 0;
  329. }
  330. return hash2;
  331. }
  332. // src/initials.ts
  333. function initials(input, strategy = "all") {
  334. let re;
  335. let takeFirst = false;
  336. switch (strategy) {
  337. case "all":
  338. re = /(\s+|[A-Z]{1}|-[a-zA-Z]{1}|_[a-zA-Z]{1}|\.[a-zA-Z]{1}|[0-9]+)/g;
  339. takeFirst = true;
  340. break;
  341. default:
  342. throw new Error("only the 'all' strategy is implemented currently");
  343. }
  344. const trimmed = input.trim();
  345. const first2 = takeFirst ? trimmed.slice(0, 1).toUpperCase() : "";
  346. const rest = takeFirst ? trimmed.slice(1) : trimmed;
  347. const parts = rest.split(re).filter((i) => i.trim() && i.match(re));
  348. const breakChars = ["_", "-"];
  349. const remaining = parts.map((i) => {
  350. const atBreak = i.slice(0, 1);
  351. return breakChars.includes(atBreak) ? i.slice(1).toUpperCase() : atBreak.toUpperCase();
  352. });
  353. return [first2, ...remaining].join("");
  354. }
  355. // src/isEven.ts
  356. function isEven(value) {
  357. return value % 2 ? false : true;
  358. }
  359. // src/isLeapYear.ts
  360. function isLeapYear(year) {
  361. const y = typeof year === "number" ? year : year.getFullYear();
  362. return new Date(y, 1, 29).getDate() === 29;
  363. }
  364. // src/isOdd.ts
  365. function isOdd(value) {
  366. return value % 2 ? true : false;
  367. }
  368. // src/isUuid.ts
  369. function isUuid(candidate, allowNonDashedForm) {
  370. const dasherizedGuid = /^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$/;
  371. const plainGuid = /^(\{{0,1}([0-9a-fA-F]){32}\}{0,1})$/;
  372. return allowNonDashedForm === true ? plainGuid.test(candidate) || dasherizedGuid.test(candidate) : dasherizedGuid.test(candidate);
  373. }
  374. // src/keys.ts
  375. function keys(obj) {
  376. return Object.keys(obj);
  377. }
  378. // src/last.ts
  379. function last(arr) {
  380. return arr.slice(-1)[0];
  381. }
  382. // src/lastKey.ts
  383. function lastKey(dict) {
  384. const key = Object.keys(dict).slice(-1).pop();
  385. return key ? key : false;
  386. }
  387. // src/pathJoin.ts
  388. function pathJoin(...args) {
  389. const leadingSlash = args[0] && (args[0].startsWith("/") || args[0].startsWith("\\"));
  390. const parts = args.filter((i) => i).map((i) => removeSlashAtFrontAndBack(makeForwardSlashBeBackward(i)));
  391. if (parts.slice(1).some((i) => i.includes(".."))) {
  392. throw new Error(
  393. `pathJoin() only accepts the ".." notation at the beginning of the first string and no where else. Input was invalid: ${JSON.stringify(
  394. args
  395. )}`
  396. );
  397. }
  398. return `${leadingSlash ? "/" : ""}${parts.join("/")}`;
  399. }
  400. function removeSlashAtFrontAndBack(input) {
  401. input = input.startsWith("/") ? input.slice(1) : input;
  402. input = input.endsWith("/") ? input.slice(0, input.length - 1) : input;
  403. return input;
  404. }
  405. function makeForwardSlashBeBackward(input) {
  406. return input.replace(/\\/gs, "/");
  407. }
  408. // src/pluralize.ts
  409. var defaultRules = [
  410. [/(us)$/i, (i) => `${i.replace(/us$/, "")}i`, ["bus", "us"]],
  411. [/(is)$/i, (i, r) => `${i.replace(r, "")}es`],
  412. [/(s|sh|ch|x|z|o)$/, (i) => `${i}es`],
  413. [/fe{0,1}$/i, (i, r) => `${i.replace(r, "")}ves`],
  414. [
  415. /[b|c|d|f|g|h|j|k|l|m|n|p|q|r|s|t|v|w|x|z|y]y$/i,
  416. (i) => `${i.slice(0, i.length - 1)}ies`
  417. ]
  418. ];
  419. function pluralize(input, options = {}) {
  420. if (input === "") {
  421. if (options.ignoreEmptyStrings)
  422. return "";
  423. throw new Error("Attempt to pluralize an empty string");
  424. }
  425. const defaultExceptions = [
  426. [/(.*)(photo)$/i, "$1$2s"],
  427. [/(.*)(piano)$/i, "$1$2s"],
  428. [/(.*)(halo)$/i, "$1$2s"],
  429. [/(.*)(foot)$/i, "$1feet"],
  430. [/(.*)(man)$/i, "$1men"],
  431. [/(.*)(pe)rson$/i, "$1$2ople"],
  432. [/(.*)(mouse)$/i, "$1mice"],
  433. [/(.*)(series)$/i, "$1series"],
  434. [/(.*)(sheep)$/i, "$1sheep"],
  435. [/(.*)(deer)$/i, "$1deer"],
  436. [/^(fun)$/i, "$1"]
  437. ];
  438. const exceptions = [
  439. ...defaultExceptions,
  440. ...options.bespokeExceptions ? options.bespokeExceptions : []
  441. ].filter((e) => {
  442. const [re, _] = e;
  443. return re.test(input.toLowerCase());
  444. });
  445. if (exceptions.length > 0) {
  446. const [re, result] = exceptions[0];
  447. return input.replace(re, result);
  448. }
  449. const pRules = options.rules || options.additionalRules ? defaultRules.concat(...options.additionalRules) : defaultRules;
  450. let index = 0;
  451. const rules = pRules.filter(
  452. (r) => r[0 /* regex */].test(input.toLowerCase()) && !(r[2 /* exceptions */] || []).includes(input)
  453. );
  454. if (rules.length > 0) {
  455. const [r, fn, exceptions2] = rules[0];
  456. return fn(input, r, exceptions2 || []);
  457. } else {
  458. return `${input}s`;
  459. }
  460. }
  461. // src/retain.ts
  462. function retain(obj, ...retainedProps) {
  463. const untyped = retainedProps;
  464. return Object.fromEntries(
  465. Object.entries(obj).filter(([key]) => untyped.includes(key))
  466. );
  467. }
  468. // src/serialize.ts
  469. function serialize(arr) {
  470. return arr.map((i) => JSON.stringify(i)).join("\n");
  471. }
  472. // src/set.ts
  473. function set(obj, dotPath, value, createIfNonExistant = true) {
  474. if (!dotPath) {
  475. throw new Error(`Attempt to set value into a dotPath but the dotPath was empty!`);
  476. }
  477. const parts = dotPath.split(/\??\./);
  478. const allButLast = parts.slice(0, parts.length - 1);
  479. const key = parts.pop();
  480. let ref = obj;
  481. allButLast.forEach((p) => {
  482. if (!ref[p]) {
  483. if (createIfNonExistant) {
  484. ref[p] = {};
  485. } else {
  486. throw new Error(
  487. `The dotPath -- ${dotPath} -- does not exist in the passed in object. You must either expressly state that you want the object structure created or this a real error that must be addressed otherwise. The part of the path which this failed on was "${p}".`
  488. );
  489. }
  490. } else if (typeof ref[p] !== "object") {
  491. throw new Error(
  492. `Failed to set the path of "${dotPath}" of the passed in base object because the base object had a scalar value along that path and setting this would have changed the object's data structure in way which is not allowed! The scalar value was found in the "${p}" component of the path.`
  493. );
  494. }
  495. ref = ref[p];
  496. });
  497. ref[key] = value;
  498. }
  499. // src/snakerize.ts
  500. function snakerize(input, preserveWhitespace = false) {
  501. const [_, preWhite, focus, postWhite] = /^(\s*)(.*?)(\s*)$/.exec(input);
  502. const convertInteriorSpace = (input2) => input2.replace(/\s+/gs, "_");
  503. const convertDashes = (input2) => input2.replace(/-/gs, "_");
  504. const injectUnderscoreBeforeCaps = (input2) => input2.replace(/([A-Z])/gs, "_$1");
  505. const removeLeadingUnderscore = (input2) => input2.startsWith("_") ? input2.slice(1) : input2;
  506. return ((preserveWhitespace ? preWhite : "") + removeLeadingUnderscore(
  507. injectUnderscoreBeforeCaps(convertDashes(convertInteriorSpace(focus)))
  508. ).toLowerCase() + (preserveWhitespace ? postWhite : "")).replace(/__/g, "_");
  509. }
  510. // src/unique.ts
  511. function unique(list, property) {
  512. return Array.from(new Set(list.map((i) => i[property])));
  513. }
  514. // src/formatting/private/constants.ts
  515. var RESET_FG = `\x1B[39m`;
  516. var RESET_BG = `\x1B[49m`;
  517. var COLOR = {
  518. black: [30, 40],
  519. red: [31, 41],
  520. magenta: [35, 45],
  521. yellow: [33, 43],
  522. green: [32, 42],
  523. brightRed: [91, 40],
  524. brightGreen: [92, 42],
  525. brightYellow: [93, 43]
  526. };
  527. // src/formatting/private/paint.ts
  528. function paint(text = "", fg, bg) {
  529. const foreground = "\x1B[" + fg(COLOR)[0] + "m";
  530. const bgc = bg ? bg(COLOR)[1] : null;
  531. const background = bgc ? "\x1B[" + bgc + "m" : "";
  532. const reset = background ? `${RESET_FG}${RESET_BG}` : `${RESET_FG}`;
  533. return `${RESET_FG}${foreground}${background}${text}${reset}`;
  534. }
  535. // src/formatting/format.ts
  536. function italicize(text = "") {
  537. return `\x1B[3m${text}\x1B[0m`;
  538. }
  539. function underline(text = "") {
  540. return `\x1B[4m${text}\x1B[0m`;
  541. }
  542. function strikethrough(text = "") {
  543. return `\x1B[9m${text}\x1B[0m`;
  544. }
  545. // src/formatting/private/replace.ts
  546. function replace(find2, corpus, formatting, global = true) {
  547. const re = new RegExp(find2, global ? "gs" : "s");
  548. let replacement = find2;
  549. if (formatting.color)
  550. replacement = paint(replacement, formatting.color, formatting.bg);
  551. if (formatting.italics)
  552. replacement = italicize(replacement);
  553. if (formatting.underline)
  554. replacement = underline(replacement);
  555. if (formatting.strikeThrough)
  556. replacement = strikethrough(replacement);
  557. return corpus.replace(re, replacement);
  558. }
  559. // src/formatting/color.ts
  560. var color = {
  561. red: (text = "", bg) => {
  562. return paint(text, (c) => c.red, bg);
  563. },
  564. magenta: (text = "", bg) => {
  565. return paint(text, (c) => c.magenta, bg);
  566. },
  567. black: (text = "", bg) => {
  568. return paint(text, (c) => c.black, bg);
  569. },
  570. yellow: (text = "", bg) => {
  571. return paint(text, (c) => c.yellow, bg);
  572. },
  573. green: (text = "", bg) => {
  574. return paint(text, (c) => c.green, bg);
  575. },
  576. brightRed: (text = "", bg) => {
  577. return paint(text, (c) => c.brightRed, bg);
  578. }
  579. };
  580. export {
  581. COLOR,
  582. DataType,
  583. KnownError,
  584. RESET_BG,
  585. RESET_FG,
  586. UnknownError,
  587. atRandom,
  588. between,
  589. camelize,
  590. capitalize,
  591. color,
  592. createLookup,
  593. dasherize,
  594. describe,
  595. deserialize,
  596. equal,
  597. find,
  598. findAll,
  599. first,
  600. firstKey,
  601. flatten,
  602. fromBase64,
  603. get,
  604. groupBy,
  605. guid,
  606. hash,
  607. initials,
  608. isEven,
  609. isKnownError,
  610. isLeapYear,
  611. isNonNullObject,
  612. isOdd,
  613. isUnknownError,
  614. isUuid,
  615. italicize,
  616. keys,
  617. last,
  618. lastKey,
  619. omit,
  620. paint,
  621. pascalize,
  622. pathJoin,
  623. pluralize,
  624. randomString,
  625. replace,
  626. retain,
  627. serialize,
  628. set,
  629. snakerize,
  630. strikethrough,
  631. toBase64,
  632. underline,
  633. unique,
  634. uuid
  635. };