ifct2017 2.0.14 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/LICENSE +661 -21
  2. package/README.md +1019 -71
  3. package/abbreviations/index.csv +78 -0
  4. package/abbreviations/index.d.ts +39 -0
  5. package/abbreviations/index.js +103 -0
  6. package/abbreviations/index.txt +12 -0
  7. package/about/build.ts +31 -0
  8. package/about/index.d.ts +47 -0
  9. package/about/index.js +110 -0
  10. package/about/index.txt +174 -0
  11. package/build.ts +115 -0
  12. package/carbohydrates/index.csv +8 -0
  13. package/carbohydrates/index.d.ts +42 -0
  14. package/carbohydrates/index.js +112 -0
  15. package/carbohydrates/index.txt +14 -0
  16. package/codes/index.csv +2904 -0
  17. package/codes/index.d.ts +36 -0
  18. package/codes/index.js +102 -0
  19. package/codes/index.txt +12 -0
  20. package/columndescriptions/build.ts +22 -0
  21. package/columndescriptions/index.csv +215 -0
  22. package/columndescriptions/index.d.ts +44 -0
  23. package/columndescriptions/index.js +119 -0
  24. package/columns/build.ts +23 -0
  25. package/columns/index.csv +215 -0
  26. package/columns/index.d.ts +39 -0
  27. package/columns/index.js +111 -0
  28. package/columns/index.txt +71 -0
  29. package/compositingcentres/index.csv +7 -0
  30. package/compositingcentres/index.d.ts +35 -0
  31. package/compositingcentres/index.js +103 -0
  32. package/compositingcentres/index.txt +13 -0
  33. package/compositions/build.ts +212 -0
  34. package/compositions/index.csv +543 -0
  35. package/compositions/index.d.ts +254 -0
  36. package/compositions/index.js +204 -0
  37. package/compositionstats/build.ts +103 -0
  38. package/compositionstats/index.csv +4 -0
  39. package/compositionstats/index.d.ts +31 -0
  40. package/compositionstats/index.js +97 -0
  41. package/contents/index.csv +21 -0
  42. package/contents/index.d.ts +39 -0
  43. package/contents/index.js +102 -0
  44. package/contents/index.txt +13 -0
  45. package/deno.lock +67 -0
  46. package/descriptions/index.csv +543 -0
  47. package/descriptions/index.d.ts +45 -0
  48. package/descriptions/index.js +124 -0
  49. package/descriptions/index.txt +15 -0
  50. package/energies/index.csv +6 -0
  51. package/energies/index.d.ts +34 -0
  52. package/energies/index.js +101 -0
  53. package/energies/index.txt +13 -0
  54. package/frequencydistribution/index.csv +10 -0
  55. package/frequencydistribution/index.d.ts +36 -0
  56. package/frequencydistribution/index.js +90 -0
  57. package/frequencydistribution/index.txt +14 -0
  58. package/groups/index.csv +21 -0
  59. package/groups/index.d.ts +46 -0
  60. package/groups/index.js +118 -0
  61. package/groups/index.txt +14 -0
  62. package/hierarchy/asset.csv +215 -0
  63. package/hierarchy/asset.txt +70 -0
  64. package/hierarchy/build.ts +73 -0
  65. package/hierarchy/index.csv +215 -0
  66. package/hierarchy/index.d.ts +39 -0
  67. package/hierarchy/index.js +100 -0
  68. package/hierarchy/index.txt +14 -0
  69. package/index.d.ts +24 -28
  70. package/index.js +28 -39
  71. package/index.test.ts +717 -0
  72. package/intakes/build.ts +28 -0
  73. package/intakes/index.csv +42 -0
  74. package/intakes/index.d.ts +66 -0
  75. package/intakes/index.js +113 -0
  76. package/intakes/index.txt +20 -0
  77. package/jonesfactors/index.csv +15 -0
  78. package/jonesfactors/index.d.ts +35 -0
  79. package/jonesfactors/index.js +105 -0
  80. package/jonesfactors/index.txt +12 -0
  81. package/languages/index.csv +22 -0
  82. package/languages/index.d.ts +39 -0
  83. package/languages/index.js +103 -0
  84. package/languages/index.txt +12 -0
  85. package/methods/build.ts +101 -0
  86. package/methods/index.csv +37 -0
  87. package/methods/index.d.ts +39 -0
  88. package/methods/index.js +196 -0
  89. package/methods/index.txt +13 -0
  90. package/package.json +15 -63
  91. package/regions/index.csv +7 -0
  92. package/regions/index.d.ts +36 -0
  93. package/regions/index.js +100 -0
  94. package/regions/index.txt +12 -0
  95. package/representations/build.ts +133 -0
  96. package/representations/index.csv +215 -0
  97. package/representations/index.d.ts +36 -0
  98. package/representations/index.js +91 -0
  99. package/retentionfactors/groups.csv +21 -0
  100. package/retentionfactors/index.csv +215 -0
  101. package/samplingunits/index.csv +36 -0
  102. package/samplingunits/index.d.ts +39 -0
  103. package/samplingunits/index.js +110 -0
  104. package/samplingunits/index.txt +14 -0
  105. package/yieldfactors/index.csv +543 -0
  106. package/yieldfactors/index.d.ts +57 -0
  107. package/yieldfactors/index.js +158 -0
  108. package/yieldfactors/index.txt +294 -0
  109. package/corpus.js +0 -6
  110. package/corpus.min.js +0 -1
  111. package/pictures.d.ts +0 -41
@@ -0,0 +1,28 @@
1
+ // Copyright (C) 2025-26 Subhajit Sahu
2
+ // SPDX-License-Identifier: AGPL-3.0-or-later
3
+ // See LICENSE for full terms
4
+ import * as path from "@std/path";
5
+ import * as csv from "@std/csv";
6
+
7
+
8
+ async function writeCorpus(outfile: string) {
9
+ const map = new Map();
10
+ const data = await Deno.readTextFile(path.join(import.meta.dirname || '', 'index.csv'));
11
+ const records = csv.parse(data, {skipFirstRow: true, comment: '#'}) as Record<string, string | number>[];
12
+ for (const r of records) {
13
+ for (const k in r)
14
+ if (k!=='code') r[k] = parseFloat(r[k] as string);
15
+ map.set(r.code, r);
16
+ }
17
+ let a = `const CORPUS = new Map([\n`;
18
+ for (const [k, v] of map)
19
+ a += ` ["${k}", ${JSON.stringify(v).replace(/\"(\w+)\":/g, '$1:').replace(/null/g, 'NaN')}],\n`;
20
+ a += `]);\n`;
21
+ a += `module.exports = CORPUS;\n`;
22
+ await Deno.writeTextFile(outfile, a);
23
+ }
24
+
25
+
26
+ export async function build(corpus='corpus.js') {
27
+ if (corpus) await writeCorpus(corpus);
28
+ }
@@ -0,0 +1,42 @@
1
+ code,whorda,usear,usrdam,usrdaf,euprim,euprif,ulus,uleu,uljapan
2
+ his,-10e-3,,-14e-3,,,,,,
3
+ ile,-20e-3,,-19e-3,,,,,,
4
+ leu,-39e-3,,-42e-3,,,,,,
5
+ lys,-30e-3,,-38e-3,,,,,,
6
+ met,-15e-3,,-19e-3,,,,,,
7
+ phe,-25e-3,,-33e-3,,,,,,
8
+ thr,-15e-3,,-20e-3,,,,,,
9
+ trp,-4e-3,,-5e-3,,,,,,
10
+ val,-26e-3,,-24e-3,,,,,,
11
+ f18d3n3,,,1.6e-3,1.1e-3,2e-3,,,,
12
+ f18d2cn6,,,17e-3,12e-3,10e-3,,,,
13
+ vita,,625e-6,900e-6,700e-6,,,3000e-6,3000e-6,2700e-6
14
+ thia,,1.0e-3,1.2e-3,1.1e-3,,,,,
15
+ ribf,,1.1e-3,1.3e-3,1.1e-3,,,,,
16
+ nia,,12e-3,16e-3,14e-3,,,35e-3,10e-3,85e-3
17
+ pantac,,,5e-3,5e-3,,,,,
18
+ vitb6c,,1.1e-3,1.5e-3,1.35e-3,,,100e-3,25e-3,60e-3
19
+ biot,,,30e-6,30e-6,,,,,
20
+ folsum,,320e-6,400e-6,400e-6,,,1000e-6,1000e-6,1000e-6
21
+ vitb12,,2.0e-6,2.4e-6,2.4e-6,,,,,
22
+ vitc,,75e-3,90e-3,75e-3,,,2000e-3,,
23
+ vitd,,10e-6,15e-6,15e-6,,,100e-6,100e-6,100e-6
24
+ vite,,12e-3,15e-3,15e-3,,,1000e-3,300e-3,900e-3
25
+ vitk,,,110e-6,120e-6,,,,,
26
+ k,,,4700e-3,,4000e-3,,,,3000e-3
27
+ cl,,,2300e-3,,,,3600e-3,,
28
+ na,,,1500e-3,,,,2300e-3,,3600e-3
29
+ ca,,800e-3,1200e-3,,1000e-3,,2500e-3,2500e-3,2500e-3
30
+ p,,580e-3,700e-3,,640e-3,,4000e-3,4000e-3,3000e-3
31
+ mg,,350e-3,420e-3,,350e-3,,350e-3,250e-3,350e-3
32
+ fe,,6e-3,8e-3,18e-3,11e-3,16e-3,45e-3,,45e-3
33
+ zn,,9.4e-3,11e-3,,16.3e-3,,40e-3,25e-3,45e-3
34
+ mn,,,2.3e-3,,3.0e-3,,11e-3,,11e-3
35
+ cu,,0.7e-3,0.9e-3,,1.6e-3,,10e-3,5e-3,10e-3
36
+ i,,0.095e-3,0.150e-3,,0.200e-3,,1.1e-3,0.6e-3,3e-3
37
+ cr,,,0.035e-3,,,,,,
38
+ mo,,0.034e-3,0.045e-3,,0.065-3,,2e-3,0.6e-3,0.55e-3
39
+ se,,0.045e-3,0.055e-3,,0.070e-3,,0.4e-3,0.3e-3,0.46e-3
40
+ f,,,4e-3,,3.4e-3,,10e-3,7e-3,
41
+ choline,,,550e-3,,520e-3,,3500e-3,,
42
+ fibtg,,,38,25,,,,,
@@ -0,0 +1,66 @@
1
+ import { type SetupTableOptions } from "@nodef/extra-sql";
2
+ /** Recommended daily intakes of nutrient. */ export interface Intake {
3
+ /** Column Code. */ code: string;
4
+ /** WHO Recommended Dietary Allowance. */ whorda: number;
5
+ /** US Estimated Average Requirement. */ usear: number;
6
+ /** US Recommended Dietary Allowance (Male). */ usrdam: number;
7
+ /** US Recommended Dietary Allowance (Female). */ usrdaf: number;
8
+ /** EU Population Reference Intake (Male). */ euprim: number;
9
+ /** EU Population Reference Intake (Female). */ euprif: number;
10
+ /** Tolerable intake Upper Level (US). */ ulus: number;
11
+ /** Tolerable intake Upper Level (EU). */ uleu: number;
12
+ /** Tolerable intake Upper Level (Japan). */ uljapan: number;
13
+ }
14
+ /**
15
+ * Load the intakes corpus from the file.
16
+ * @returns intakes corpus
17
+ */ export declare function loadIntakes(): Promise<Map<string, Intake>>;
18
+ /**
19
+ * Get the path to the intakes CSV file.
20
+ * @returns CSV file URL
21
+ */ export declare function intakesCsv(): string;
22
+ /**
23
+ * Obtain SQL command to create and populate the intakes table.
24
+ * @param tab table name
25
+ * @param opt options for the table
26
+ * @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
27
+ */ export declare function intakesSql(tab?: string, opt?: SetupTableOptions): Promise<string>;
28
+ /**
29
+ * Find matching intakes of an column:code/name/tags query.
30
+ * @param txt column:code/name/tags query
31
+ * @returns matches `[{code, whorda, usear, usrdam, usrdaf, euprim, euprif, ulus, uleu, uljapan}]`
32
+ * @example
33
+ * ```javascript
34
+ * ifct2017.intakes('his');
35
+ * ifct2017.intakes('Histidine');
36
+ * // → [{ code: 'his',
37
+ * // → whorda: -0.01,
38
+ * // → usear: NaN,
39
+ * // → usrdam: -0.014,
40
+ * // → usrdaf: NaN,
41
+ * // → euprim: NaN,
42
+ * // → euprif: NaN,
43
+ * // → ulus: NaN,
44
+ * // → uleu: NaN,
45
+ * // → uljapan: NaN }]
46
+ *
47
+ * ifct2017.intakes('intake of total fibre?');
48
+ * ifct2017.intakes('what is rda of total fiber?');
49
+ * // → [{ code: 'fibtg',
50
+ * // → whorda: NaN,
51
+ * // → usear: NaN,
52
+ * // → usrdam: 38,
53
+ * // → usrdaf: 25,
54
+ * // → euprim: NaN,
55
+ * // → euprif: NaN,
56
+ * // → ulus: NaN,
57
+ * // → uleu: NaN,
58
+ * // → uljapan: NaN }]
59
+ *
60
+ *
61
+ * // Note:
62
+ * // +ve value indicates amount in grams.
63
+ * // -ve value indicates amount in grams per kg of body weight.
64
+ * // NaN indicates no recommentation given.
65
+ * ```
66
+ */ export declare function intakes(txt: string): Intake[];
@@ -0,0 +1,113 @@
1
+ // Copyright (C) 2025-26 Subhajit Sahu
2
+ // SPDX-License-Identifier: AGPL-3.0-or-later
3
+ // See LICENSE for full terms
4
+ import * as csv from "@std/csv";
5
+ import { setupTable } from "@nodef/extra-sql";
6
+ import { loadColumns, columns } from "../columns/index.js";
7
+ //#endregion
8
+ //#region GLOBALS
9
+ let corpus = null;
10
+ //#endregion
11
+ //#region FUNCTIONS
12
+ /**
13
+ * Load the intakes corpus from CSV file.
14
+ * @param file CSV file path
15
+ * @returns intakes corpus
16
+ */ async function loadFromCsv(file) {
17
+ const map = new Map();
18
+ const data = await (await fetch(file)).text();
19
+ const records = csv.parse(data, {
20
+ skipFirstRow: true,
21
+ comment: "#"
22
+ });
23
+ for (const r of records){
24
+ const s = {};
25
+ for(const k in r)s[k] = k === "code" ? r[k] : parseFloat(r[k]);
26
+ map.set(r.code, s);
27
+ }
28
+ return map;
29
+ }
30
+ /**
31
+ * Load the intakes corpus from the file.
32
+ * @returns intakes corpus
33
+ */ export async function loadIntakes() {
34
+ if (corpus) return corpus;
35
+ const p = loadColumns();
36
+ corpus = await loadFromCsv(intakesCsv());
37
+ await p;
38
+ return corpus;
39
+ }
40
+ /**
41
+ * Get the path to the intakes CSV file.
42
+ * @returns CSV file URL
43
+ */ export function intakesCsv() {
44
+ return import.meta.resolve('./index.csv');
45
+ }
46
+ /**
47
+ * Obtain SQL command to create and populate the intakes table.
48
+ * @param tab table name
49
+ * @param opt options for the table
50
+ * @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
51
+ */ export async function intakesSql(tab = "intakes", opt = {}) {
52
+ return setupTable(tab, {
53
+ code: "TEXT",
54
+ whorda: "REAL",
55
+ usear: "REAL",
56
+ usrdam: "REAL",
57
+ usrdaf: "REAL",
58
+ euprim: "REAL",
59
+ euprif: "REAL",
60
+ ulus: "REAL",
61
+ uleu: "REAL",
62
+ uljapan: "REAL"
63
+ }, (await loadIntakes()).values(), Object.assign({
64
+ pk: "code",
65
+ index: true,
66
+ tsvector: {
67
+ code: "A"
68
+ }
69
+ }, opt));
70
+ }
71
+ /**
72
+ * Find matching intakes of an column:code/name/tags query.
73
+ * @param txt column:code/name/tags query
74
+ * @returns matches `[{code, whorda, usear, usrdam, usrdaf, euprim, euprif, ulus, uleu, uljapan}]`
75
+ * @example
76
+ * ```javascript
77
+ * ifct2017.intakes('his');
78
+ * ifct2017.intakes('Histidine');
79
+ * // → [{ code: 'his',
80
+ * // → whorda: -0.01,
81
+ * // → usear: NaN,
82
+ * // → usrdam: -0.014,
83
+ * // → usrdaf: NaN,
84
+ * // → euprim: NaN,
85
+ * // → euprif: NaN,
86
+ * // → ulus: NaN,
87
+ * // → uleu: NaN,
88
+ * // → uljapan: NaN }]
89
+ *
90
+ * ifct2017.intakes('intake of total fibre?');
91
+ * ifct2017.intakes('what is rda of total fiber?');
92
+ * // → [{ code: 'fibtg',
93
+ * // → whorda: NaN,
94
+ * // → usear: NaN,
95
+ * // → usrdam: 38,
96
+ * // → usrdaf: 25,
97
+ * // → euprim: NaN,
98
+ * // → euprif: NaN,
99
+ * // → ulus: NaN,
100
+ * // → uleu: NaN,
101
+ * // → uljapan: NaN }]
102
+ *
103
+ *
104
+ * // Note:
105
+ * // +ve value indicates amount in grams.
106
+ * // -ve value indicates amount in grams per kg of body weight.
107
+ * // NaN indicates no recommentation given.
108
+ * ```
109
+ */ export function intakes(txt) {
110
+ if (corpus == null) return [];
111
+ return columns(txt).map((r)=>corpus?.get(r.code));
112
+ } //#endregion
113
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9pZmN0MjAxNy9pZmN0MjAxNy9pbnRha2VzL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoQykgMjAyNS0yNiBTdWJoYWppdCBTYWh1XG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb3ItbGF0ZXJcbi8vIFNlZSBMSUNFTlNFIGZvciBmdWxsIHRlcm1zXG5pbXBvcnQgKiBhcyBjc3YgIGZyb20gXCJAc3RkL2NzdlwiO1xuaW1wb3J0IHt0eXBlIFJvd0RhdGEsIHR5cGUgU2V0dXBUYWJsZU9wdGlvbnMsIHNldHVwVGFibGV9IGZyb20gXCJAbm9kZWYvZXh0cmEtc3FsXCI7XG5pbXBvcnQge2xvYWRDb2x1bW5zLCBjb2x1bW5zfSBmcm9tIFwiLi4vY29sdW1ucy9pbmRleC5qc1wiO1xuXG5cblxuXG4vLyNyZWdpb24gVFlQRVNcbi8qKiBSZWNvbW1lbmRlZCBkYWlseSBpbnRha2VzIG9mIG51dHJpZW50LiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbnRha2Uge1xuICAvKiogQ29sdW1uIENvZGUuICovXG4gIGNvZGU6IHN0cmluZyxcbiAgLyoqIFdITyBSZWNvbW1lbmRlZCBEaWV0YXJ5IEFsbG93YW5jZS4gKi9cbiAgd2hvcmRhOiBudW1iZXIsXG4gIC8qKiBVUyBFc3RpbWF0ZWQgQXZlcmFnZSBSZXF1aXJlbWVudC4gKi9cbiAgdXNlYXI6IG51bWJlcixcbiAgLyoqIFVTIFJlY29tbWVuZGVkIERpZXRhcnkgQWxsb3dhbmNlIChNYWxlKS4gKi9cbiAgdXNyZGFtOiBudW1iZXIsXG4gIC8qKiBVUyBSZWNvbW1lbmRlZCBEaWV0YXJ5IEFsbG93YW5jZSAoRmVtYWxlKS4gKi9cbiAgdXNyZGFmOiBudW1iZXIsXG4gIC8qKiBFVSBQb3B1bGF0aW9uIFJlZmVyZW5jZSBJbnRha2UgKE1hbGUpLiAqL1xuICBldXByaW06IG51bWJlcixcbiAgLyoqIEVVIFBvcHVsYXRpb24gUmVmZXJlbmNlIEludGFrZSAoRmVtYWxlKS4gKi9cbiAgZXVwcmlmOiBudW1iZXIsXG4gIC8qKiBUb2xlcmFibGUgaW50YWtlIFVwcGVyIExldmVsIChVUykuICovXG4gIHVsdXM6IG51bWJlcixcbiAgLyoqIFRvbGVyYWJsZSBpbnRha2UgVXBwZXIgTGV2ZWwgKEVVKS4gKi9cbiAgdWxldTogbnVtYmVyLFxuICAvKiogVG9sZXJhYmxlIGludGFrZSBVcHBlciBMZXZlbCAoSmFwYW4pLiAqL1xuICB1bGphcGFuOiBudW1iZXJcbn07XG4vLyNlbmRyZWdpb25cblxuXG5cblxuLy8jcmVnaW9uIEdMT0JBTFNcbmxldCBjb3JwdXM6IE1hcDxzdHJpbmcsIEludGFrZT4gfCBudWxsID0gbnVsbDtcbi8vI2VuZHJlZ2lvblxuXG5cblxuXG4vLyNyZWdpb24gRlVOQ1RJT05TXG4vKipcbiAqIExvYWQgdGhlIGludGFrZXMgY29ycHVzIGZyb20gQ1NWIGZpbGUuXG4gKiBAcGFyYW0gZmlsZSBDU1YgZmlsZSBwYXRoXG4gKiBAcmV0dXJucyBpbnRha2VzIGNvcnB1c1xuICovXG5hc3luYyBmdW5jdGlvbiBsb2FkRnJvbUNzdihmaWxlOiBzdHJpbmcpIHtcbiAgY29uc3QgbWFwICA9IG5ldyBNYXA8c3RyaW5nLCBJbnRha2U+KCk7XG4gIGNvbnN0IGRhdGEgPSBhd2FpdCAoYXdhaXQgZmV0Y2goZmlsZSkpLnRleHQoKTtcbiAgY29uc3QgcmVjb3JkcyA9IGNzdi5wYXJzZShkYXRhLCB7c2tpcEZpcnN0Um93OiB0cnVlLCBjb21tZW50OiBcIiNcIn0pO1xuICBmb3IgKGNvbnN0IHIgb2YgcmVjb3Jkcykge1xuICAgIGNvbnN0IHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bWJlcj4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IGsgaW4gcilcbiAgICAgIHNba10gPSBrPT09XCJjb2RlXCI/IHJba10gOiBwYXJzZUZsb2F0KHJba10pO1xuICAgIG1hcC5zZXQoci5jb2RlLCBzIGFzIHVua25vd24gYXMgSW50YWtlKTtcbiAgfVxuICByZXR1cm4gbWFwO1xufVxuXG5cbi8qKlxuICogTG9hZCB0aGUgaW50YWtlcyBjb3JwdXMgZnJvbSB0aGUgZmlsZS5cbiAqIEByZXR1cm5zIGludGFrZXMgY29ycHVzXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2FkSW50YWtlcygpOiBQcm9taXNlPE1hcDxzdHJpbmcsIEludGFrZT4+IHtcbiAgaWYgKGNvcnB1cykgcmV0dXJuIGNvcnB1cztcbiAgY29uc3QgcCA9IGxvYWRDb2x1bW5zKCk7XG4gIGNvcnB1cyA9IGF3YWl0IGxvYWRGcm9tQ3N2KGludGFrZXNDc3YoKSk7IGF3YWl0IHA7XG4gIHJldHVybiBjb3JwdXM7XG59XG5cblxuLyoqXG4gKiBHZXQgdGhlIHBhdGggdG8gdGhlIGludGFrZXMgQ1NWIGZpbGUuXG4gKiBAcmV0dXJucyBDU1YgZmlsZSBVUkxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGludGFrZXNDc3YoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGltcG9ydC5tZXRhLnJlc29sdmUoJy4vaW5kZXguY3N2Jyk7XG59XG5cblxuLyoqXG4gKiBPYnRhaW4gU1FMIGNvbW1hbmQgdG8gY3JlYXRlIGFuZCBwb3B1bGF0ZSB0aGUgaW50YWtlcyB0YWJsZS5cbiAqIEBwYXJhbSB0YWIgdGFibGUgbmFtZVxuICogQHBhcmFtIG9wdCBvcHRpb25zIGZvciB0aGUgdGFibGVcbiAqIEByZXR1cm5zIENSRUFURSBUQUJMRSwgSU5TRVJULCBDUkVBVEUgVklFVywgQ1JFQVRFIElOREVYIHN0YXRlbWVudHNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGludGFrZXNTcWwodGFiOiBzdHJpbmc9XCJpbnRha2VzXCIsIG9wdDogU2V0dXBUYWJsZU9wdGlvbnM9e30pOiBQcm9taXNlPHN0cmluZz4ge1xuICByZXR1cm4gc2V0dXBUYWJsZSh0YWIsIHtjb2RlOiBcIlRFWFRcIiwgd2hvcmRhOiBcIlJFQUxcIiwgdXNlYXI6IFwiUkVBTFwiLCB1c3JkYW06IFwiUkVBTFwiLFxuICAgIHVzcmRhZjogXCJSRUFMXCIsIGV1cHJpbTogXCJSRUFMXCIsIGV1cHJpZjogXCJSRUFMXCIsIHVsdXM6IFwiUkVBTFwiLCB1bGV1OiBcIlJFQUxcIiwgdWxqYXBhbjogXCJSRUFMXCJ9LFxuICAgIChhd2FpdCBsb2FkSW50YWtlcygpKS52YWx1ZXMoKSBhcyBJdGVyYWJsZTxSb3dEYXRhPixcbiAgICBPYmplY3QuYXNzaWduKHtwazogXCJjb2RlXCIsIGluZGV4OiB0cnVlLCB0c3ZlY3Rvcjoge2NvZGU6IFwiQVwifX0sIG9wdCkpO1xufVxuXG5cbi8qKlxuICogRmluZCBtYXRjaGluZyBpbnRha2VzIG9mIGFuIGNvbHVtbjpjb2RlL25hbWUvdGFncyBxdWVyeS5cbiAqIEBwYXJhbSB0eHQgY29sdW1uOmNvZGUvbmFtZS90YWdzIHF1ZXJ5XG4gKiBAcmV0dXJucyBtYXRjaGVzIGBbe2NvZGUsIHdob3JkYSwgdXNlYXIsIHVzcmRhbSwgdXNyZGFmLCBldXByaW0sIGV1cHJpZiwgdWx1cywgdWxldSwgdWxqYXBhbn1dYFxuICogQGV4YW1wbGVcbiAqIGBgYGphdmFzY3JpcHRcbiAqIGlmY3QyMDE3LmludGFrZXMoJ2hpcycpO1xuICogaWZjdDIwMTcuaW50YWtlcygnSGlzdGlkaW5lJyk7XG4gKiAvLyDihpIgW3sgY29kZTogJ2hpcycsXG4gKiAvLyDihpIgICAgd2hvcmRhOiAtMC4wMSxcbiAqIC8vIOKGkiAgICB1c2VhcjogTmFOLFxuICogLy8g4oaSICAgIHVzcmRhbTogLTAuMDE0LFxuICogLy8g4oaSICAgIHVzcmRhZjogTmFOLFxuICogLy8g4oaSICAgIGV1cHJpbTogTmFOLFxuICogLy8g4oaSICAgIGV1cHJpZjogTmFOLFxuICogLy8g4oaSICAgIHVsdXM6IE5hTixcbiAqIC8vIOKGkiAgICB1bGV1OiBOYU4sXG4gKiAvLyDihpIgICAgdWxqYXBhbjogTmFOIH1dXG4gKlxuICogaWZjdDIwMTcuaW50YWtlcygnaW50YWtlIG9mIHRvdGFsIGZpYnJlPycpO1xuICogaWZjdDIwMTcuaW50YWtlcygnd2hhdCBpcyByZGEgb2YgdG90YWwgZmliZXI/Jyk7XG4gKiAvLyDihpIgW3sgY29kZTogJ2ZpYnRnJyxcbiAqIC8vIOKGkiAgICB3aG9yZGE6IE5hTixcbiAqIC8vIOKGkiAgICB1c2VhcjogTmFOLFxuICogLy8g4oaSICAgIHVzcmRhbTogMzgsXG4gKiAvLyDihpIgICAgdXNyZGFmOiAyNSxcbiAqIC8vIOKGkiAgICBldXByaW06IE5hTixcbiAqIC8vIOKGkiAgICBldXByaWY6IE5hTixcbiAqIC8vIOKGkiAgICB1bHVzOiBOYU4sXG4gKiAvLyDihpIgICAgdWxldTogTmFOLFxuICogLy8g4oaSICAgIHVsamFwYW46IE5hTiB9XVxuICpcbiAqXG4gKiAvLyBOb3RlOlxuICogLy8gK3ZlIHZhbHVlIGluZGljYXRlcyBhbW91bnQgaW4gZ3JhbXMuXG4gKiAvLyAtdmUgdmFsdWUgaW5kaWNhdGVzIGFtb3VudCBpbiBncmFtcyBwZXIga2cgb2YgYm9keSB3ZWlnaHQuXG4gKiAvLyBOYU4gaW5kaWNhdGVzIG5vIHJlY29tbWVudGF0aW9uIGdpdmVuLlxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnRha2VzKHR4dDogc3RyaW5nKTogSW50YWtlW10ge1xuICBpZiAoY29ycHVzID09IG51bGwpIHJldHVybiBbXTtcbiAgcmV0dXJuIGNvbHVtbnModHh0KS5tYXAociA9PiBjb3JwdXM/LmdldChyLmNvZGUpIGFzIEludGFrZSk7XG59XG4vLyNlbmRyZWdpb25cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxzQ0FBc0M7QUFDdEMsNkNBQTZDO0FBQzdDLDZCQUE2QjtBQUM3QixZQUFZLFNBQVUsV0FBVztBQUNqQyxTQUE4QyxVQUFVLFFBQU8sbUJBQW1CO0FBQ2xGLFNBQVEsV0FBVyxFQUFFLE9BQU8sUUFBTyxzQkFBc0I7QUE2QnpELFlBQVk7QUFLWixpQkFBaUI7QUFDakIsSUFBSSxTQUFxQztBQUN6QyxZQUFZO0FBS1osbUJBQW1CO0FBQ25COzs7O0NBSUMsR0FDRCxlQUFlLFlBQVksSUFBWTtFQUNyQyxNQUFNLE1BQU8sSUFBSTtFQUNqQixNQUFNLE9BQU8sTUFBTSxDQUFDLE1BQU0sTUFBTSxLQUFLLEVBQUUsSUFBSTtFQUMzQyxNQUFNLFVBQVUsSUFBSSxLQUFLLENBQUMsTUFBTTtJQUFDLGNBQWM7SUFBTSxTQUFTO0VBQUc7RUFDakUsS0FBSyxNQUFNLEtBQUssUUFBUztJQUN2QixNQUFNLElBQXFDLENBQUM7SUFDNUMsSUFBSyxNQUFNLEtBQUssRUFDZCxDQUFDLENBQUMsRUFBRSxHQUFHLE1BQUksU0FBUSxDQUFDLENBQUMsRUFBRSxHQUFHLFdBQVcsQ0FBQyxDQUFDLEVBQUU7SUFDM0MsSUFBSSxHQUFHLENBQUMsRUFBRSxJQUFJLEVBQUU7RUFDbEI7RUFDQSxPQUFPO0FBQ1Q7QUFHQTs7O0NBR0MsR0FDRCxPQUFPLGVBQWU7RUFDcEIsSUFBSSxRQUFRLE9BQU87RUFDbkIsTUFBTSxJQUFJO0VBQ1YsU0FBUyxNQUFNLFlBQVk7RUFBZSxNQUFNO0VBQ2hELE9BQU87QUFDVDtBQUdBOzs7Q0FHQyxHQUNELE9BQU8sU0FBUztFQUNkLE9BQU8sWUFBWSxPQUFPLENBQUM7QUFDN0I7QUFHQTs7Ozs7Q0FLQyxHQUNELE9BQU8sZUFBZSxXQUFXLE1BQVksU0FBUyxFQUFFLE1BQXVCLENBQUMsQ0FBQztFQUMvRSxPQUFPLFdBQVcsS0FBSztJQUFDLE1BQU07SUFBUSxRQUFRO0lBQVEsT0FBTztJQUFRLFFBQVE7SUFDM0UsUUFBUTtJQUFRLFFBQVE7SUFBUSxRQUFRO0lBQVEsTUFBTTtJQUFRLE1BQU07SUFBUSxTQUFTO0VBQU0sR0FDM0YsQ0FBQyxNQUFNLGFBQWEsRUFBRSxNQUFNLElBQzVCLE9BQU8sTUFBTSxDQUFDO0lBQUMsSUFBSTtJQUFRLE9BQU87SUFBTSxVQUFVO01BQUMsTUFBTTtJQUFHO0VBQUMsR0FBRztBQUNwRTtBQUdBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztDQXNDQyxHQUNELE9BQU8sU0FBUyxRQUFRLEdBQVc7RUFDakMsSUFBSSxVQUFVLE1BQU0sT0FBTyxFQUFFO0VBQzdCLE9BQU8sUUFBUSxLQUFLLEdBQUcsQ0FBQyxDQUFBLElBQUssUUFBUSxJQUFJLEVBQUUsSUFBSTtBQUNqRCxFQUNBLFlBQVkifQ==
@@ -0,0 +1,20 @@
1
+ Indian Food Composition Tables 2017
2
+ T. Longvah, R. Ananthan, K. Bhaskarachary and K. Venkaiah
3
+
4
+ Copyright © 2017 by National Institute of Nutrition
5
+ Indian Council of Medical Research
6
+ Department of Health Research Ministry of Health and Family Welfare, Government of India
7
+ Jamai Osmania (PO), Hyderabad – 500 007
8
+ Telangana, India Phone: +91 40 27197334, Fax: +91 40 27000339, Email: nin@ap.nic.in
9
+
10
+ INTAKES
11
+ - Column Code
12
+ - WHO Recommended Dietary Allowance
13
+ - US Estimated Average Requirement
14
+ - US Recommended Dietary Allowance (Male)
15
+ - US Recommended Dietary Allowance (Female)
16
+ - EU Population Reference Intake (Male)
17
+ - EU Population Reference Intake (Female)
18
+ - Tolerable intake Upper Level (US)
19
+ - Tolerable intake Upper Level (EU)
20
+ - Tolerable intake Upper Level (Japan)
@@ -0,0 +1,15 @@
1
+ food,factor
2
+ Barley and its flour;Rye and its flour;Oats,5.83
3
+ Rice and its flour,5.95
4
+ Wheat whole,5.83
5
+ Wheat bran,6.31
6
+ Refined wheat flour (Maida),5.70
7
+ Almonds,5.18
8
+ Peanuts,5.46
9
+ Soybean,5.71
10
+ "Cashew nuts;Pistachio nut;Chest nut",5.30
11
+ Egg whole,6.25
12
+ Meat and Fish,6.25
13
+ Milk and milk products,6.38
14
+ Sunflower seeds,5.30
15
+ Food where specific factor is not listed,6.25
@@ -0,0 +1,35 @@
1
+ import { type SetupTableOptions } from "@nodef/extra-sql";
2
+ /** Jones factor for conversion of nitrogen to protein. */ export interface JonesFactor {
3
+ /** Food. */ food: string;
4
+ /** Conversion Factor. */ factor: number;
5
+ }
6
+ /**
7
+ * Load the jones factors corpus from the file.
8
+ * @returns jones factors corpus
9
+ */ export declare function loadJonesFactors(): Promise<Map<string, JonesFactor>>;
10
+ /**
11
+ * Get the path to the jones factors CSV file.
12
+ * @returns CSV file URL
13
+ */ export declare function jonesFactorsCsv(): string;
14
+ /**
15
+ * Obtain SQL command to create and populate the jones factors table.
16
+ * @param tab table name
17
+ * @param opt options for the table
18
+ * @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
19
+ */ export declare function jonesFactorsSql(tab?: string, opt?: SetupTableOptions): Promise<string>;
20
+ /**
21
+ * Find matching jones factors of a food query.
22
+ * @param txt food query
23
+ * @returns matches `[{food, factor}]`
24
+ * @example
25
+ * ```javascript
26
+ * ifct2017.jonesFactors('maida');
27
+ * ifct2017.jonesFactors('Refined wheat');
28
+ * // → [ { food: 'Refined wheat flour (Maida)', factor: '5.70' } ]
29
+ *
30
+ * ifct2017.jonesFactors('what is jones factor of barley?');
31
+ * ifct2017.jonesFactors('jones factor of oats');
32
+ * // → [ { food: 'Barley and its flour;Rye and its flour;Oats',
33
+ * // → factor: '5.83' } ]
34
+ * ```
35
+ */ export declare function jonesFactors(txt: string): JonesFactor[];
@@ -0,0 +1,105 @@
1
+ // Copyright (C) 2025-26 Subhajit Sahu
2
+ // SPDX-License-Identifier: AGPL-3.0-or-later
3
+ // See LICENSE for full terms
4
+ import * as csv from "@std/csv";
5
+ import lunr from "lunr"; // @deno-types="npm:@types/lunr@2.3.7"
6
+ import { setupTable } from "@nodef/extra-sql";
7
+ //#endregion
8
+ //#region GLOBALS
9
+ let corpus = null;
10
+ let index = null;
11
+ //#endregion
12
+ //#region FUNCTIONS
13
+ /**
14
+ * Load the jones factors corpus from CSV file.
15
+ * @param file CSV file path
16
+ * @returns jones factors corpus
17
+ */ async function loadFromCsv(file) {
18
+ const map = new Map();
19
+ const data = await (await fetch(file)).text();
20
+ const records = csv.parse(data, {
21
+ skipFirstRow: true,
22
+ comment: "#"
23
+ });
24
+ for (const r of records){
25
+ const factor = parseFloat(r.factor);
26
+ map.set(r.food, {
27
+ food: r.food,
28
+ factor
29
+ });
30
+ }
31
+ return map;
32
+ }
33
+ /**
34
+ * Setup the lunr index for the jones factors corpus.
35
+ * @returns lunr index
36
+ */ function setupIndex(corpus) {
37
+ return lunr(function() {
38
+ this.ref('key');
39
+ this.field('food');
40
+ for (const r of corpus.values())this.add({
41
+ key: r.food,
42
+ food: r.food.replace(/[\W\s]+/g, ' ')
43
+ });
44
+ });
45
+ }
46
+ /**
47
+ * Load the jones factors corpus from the file.
48
+ * @returns jones factors corpus
49
+ */ export async function loadJonesFactors() {
50
+ if (corpus) return corpus;
51
+ corpus = await loadFromCsv(jonesFactorsCsv());
52
+ index = setupIndex(corpus);
53
+ return corpus;
54
+ }
55
+ /**
56
+ * Get the path to the jones factors CSV file.
57
+ * @returns CSV file URL
58
+ */ export function jonesFactorsCsv() {
59
+ return import.meta.resolve('./index.csv');
60
+ }
61
+ /**
62
+ * Obtain SQL command to create and populate the jones factors table.
63
+ * @param tab table name
64
+ * @param opt options for the table
65
+ * @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
66
+ */ export async function jonesFactorsSql(tab = "jonesfactors", opt = {}) {
67
+ return setupTable(tab, {
68
+ food: "TEXT",
69
+ factor: "REAL"
70
+ }, (await loadJonesFactors()).values(), Object.assign({
71
+ pk: "food",
72
+ index: true,
73
+ tsvector: {
74
+ food: "A"
75
+ }
76
+ }, opt));
77
+ }
78
+ /**
79
+ * Find matching jones factors of a food query.
80
+ * @param txt food query
81
+ * @returns matches `[{food, factor}]`
82
+ * @example
83
+ * ```javascript
84
+ * ifct2017.jonesFactors('maida');
85
+ * ifct2017.jonesFactors('Refined wheat');
86
+ * // → [ { food: 'Refined wheat flour (Maida)', factor: '5.70' } ]
87
+ *
88
+ * ifct2017.jonesFactors('what is jones factor of barley?');
89
+ * ifct2017.jonesFactors('jones factor of oats');
90
+ * // → [ { food: 'Barley and its flour;Rye and its flour;Oats',
91
+ * // → factor: '5.83' } ]
92
+ * ```
93
+ */ export function jonesFactors(txt) {
94
+ if (index == null) return [];
95
+ const a = [];
96
+ txt = txt.replace(/\W/g, ' ').replace(/factor/gi, '');
97
+ const mats = index.search(txt);
98
+ let max = 0;
99
+ for (const mat of mats)max = Math.max(max, Object.keys(mat.matchData.metadata).length);
100
+ for (const mat of mats)if (Object.keys(mat.matchData.metadata).length === max) a.push(corpus?.get(mat.ref) || {});
101
+ return a.length > 0 ? a : [
102
+ corpus?.get('Food where specific factor is not listed')
103
+ ];
104
+ } //#endregion
105
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9pZmN0MjAxNy9pZmN0MjAxNy9qb25lc2ZhY3RvcnMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChDKSAyMDI1LTI2IFN1Ymhhaml0IFNhaHVcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vci1sYXRlclxuLy8gU2VlIExJQ0VOU0UgZm9yIGZ1bGwgdGVybXNcbmltcG9ydCAqIGFzIGNzdiAgZnJvbSBcIkBzdGQvY3N2XCI7XG5pbXBvcnQgbHVuciBmcm9tIFwibHVuclwiOyAgLy8gQGRlbm8tdHlwZXM9XCJucG06QHR5cGVzL2x1bnJAMi4zLjdcIlxuaW1wb3J0IHt0eXBlIFJvd0RhdGEsIHR5cGUgU2V0dXBUYWJsZU9wdGlvbnMsIHNldHVwVGFibGV9IGZyb20gXCJAbm9kZWYvZXh0cmEtc3FsXCI7XG5cblxuXG5cbi8vI3JlZ2lvbiBUWVBFU1xuLyoqIEpvbmVzIGZhY3RvciBmb3IgY29udmVyc2lvbiBvZiBuaXRyb2dlbiB0byBwcm90ZWluLiAqL1xuZXhwb3J0IGludGVyZmFjZSBKb25lc0ZhY3RvciB7XG4gIC8qKiBGb29kLiAqL1xuICBmb29kOiBzdHJpbmcsXG4gIC8qKiBDb252ZXJzaW9uIEZhY3Rvci4gKi9cbiAgZmFjdG9yOiBudW1iZXJcbn07XG4vLyNlbmRyZWdpb25cblxuXG5cblxuLy8jcmVnaW9uIEdMT0JBTFNcbmxldCBjb3JwdXM6IE1hcDxzdHJpbmcsIEpvbmVzRmFjdG9yPiB8IG51bGwgPSBudWxsO1xubGV0IGluZGV4OiBsdW5yLkluZGV4IHwgbnVsbCA9IG51bGw7XG4vLyNlbmRyZWdpb25cblxuXG5cblxuLy8jcmVnaW9uIEZVTkNUSU9OU1xuLyoqXG4gKiBMb2FkIHRoZSBqb25lcyBmYWN0b3JzIGNvcnB1cyBmcm9tIENTViBmaWxlLlxuICogQHBhcmFtIGZpbGUgQ1NWIGZpbGUgcGF0aFxuICogQHJldHVybnMgam9uZXMgZmFjdG9ycyBjb3JwdXNcbiAqL1xuYXN5bmMgZnVuY3Rpb24gbG9hZEZyb21Dc3YoZmlsZTogc3RyaW5nKSB7XG4gIGNvbnN0IG1hcCAgPSBuZXcgTWFwPHN0cmluZywgSm9uZXNGYWN0b3I+KCk7XG4gIGNvbnN0IGRhdGEgPSBhd2FpdCAoYXdhaXQgZmV0Y2goZmlsZSkpLnRleHQoKTtcbiAgY29uc3QgcmVjb3JkcyA9IGNzdi5wYXJzZShkYXRhLCB7c2tpcEZpcnN0Um93OiB0cnVlLCBjb21tZW50OiBcIiNcIn0pO1xuICBmb3IgKGNvbnN0IHIgb2YgcmVjb3Jkcykge1xuICAgIGNvbnN0IGZhY3RvciA9IHBhcnNlRmxvYXQoci5mYWN0b3IpO1xuICAgIG1hcC5zZXQoci5mb29kLCB7Zm9vZDogci5mb29kLCBmYWN0b3J9KTtcbiAgfVxuICByZXR1cm4gbWFwO1xufVxuXG5cbi8qKlxuICogU2V0dXAgdGhlIGx1bnIgaW5kZXggZm9yIHRoZSBqb25lcyBmYWN0b3JzIGNvcnB1cy5cbiAqIEByZXR1cm5zIGx1bnIgaW5kZXhcbiAqL1xuZnVuY3Rpb24gc2V0dXBJbmRleChjb3JwdXM6IE1hcDxzdHJpbmcsIEpvbmVzRmFjdG9yPikge1xuICByZXR1cm4gbHVucihmdW5jdGlvbih0aGlzOiBsdW5yLkJ1aWxkZXIpIHtcbiAgICB0aGlzLnJlZigna2V5Jyk7XG4gICAgdGhpcy5maWVsZCgnZm9vZCcpO1xuICAgIGZvciAoY29uc3QgciBvZiBjb3JwdXMudmFsdWVzKCkpXG4gICAgICB0aGlzLmFkZCh7a2V5OiByLmZvb2QsIGZvb2Q6IHIuZm9vZC5yZXBsYWNlKC9bXFxXXFxzXSsvZywgJyAnKX0pO1xuICB9KTtcbn1cblxuXG4vKipcbiAqIExvYWQgdGhlIGpvbmVzIGZhY3RvcnMgY29ycHVzIGZyb20gdGhlIGZpbGUuXG4gKiBAcmV0dXJucyBqb25lcyBmYWN0b3JzIGNvcnB1c1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9hZEpvbmVzRmFjdG9ycygpOiBQcm9taXNlPE1hcDxzdHJpbmcsIEpvbmVzRmFjdG9yPj4ge1xuICBpZiAoY29ycHVzKSByZXR1cm4gY29ycHVzO1xuICBjb3JwdXMgPSBhd2FpdCBsb2FkRnJvbUNzdihqb25lc0ZhY3RvcnNDc3YoKSk7XG4gIGluZGV4ICA9IHNldHVwSW5kZXgoY29ycHVzKTtcbiAgcmV0dXJuIGNvcnB1cztcbn1cblxuXG4vKipcbiAqIEdldCB0aGUgcGF0aCB0byB0aGUgam9uZXMgZmFjdG9ycyBDU1YgZmlsZS5cbiAqIEByZXR1cm5zIENTViBmaWxlIFVSTFxuICovXG5leHBvcnQgZnVuY3Rpb24gam9uZXNGYWN0b3JzQ3N2KCk6IHN0cmluZyB7XG4gIHJldHVybiBpbXBvcnQubWV0YS5yZXNvbHZlKCcuL2luZGV4LmNzdicpO1xufVxuXG5cbi8qKlxuICogT2J0YWluIFNRTCBjb21tYW5kIHRvIGNyZWF0ZSBhbmQgcG9wdWxhdGUgdGhlIGpvbmVzIGZhY3RvcnMgdGFibGUuXG4gKiBAcGFyYW0gdGFiIHRhYmxlIG5hbWVcbiAqIEBwYXJhbSBvcHQgb3B0aW9ucyBmb3IgdGhlIHRhYmxlXG4gKiBAcmV0dXJucyBDUkVBVEUgVEFCTEUsIElOU0VSVCwgQ1JFQVRFIFZJRVcsIENSRUFURSBJTkRFWCBzdGF0ZW1lbnRzXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBqb25lc0ZhY3RvcnNTcWwodGFiOiBzdHJpbmc9XCJqb25lc2ZhY3RvcnNcIiwgb3B0OiBTZXR1cFRhYmxlT3B0aW9ucz17fSk6IFByb21pc2U8c3RyaW5nPiB7XG4gIHJldHVybiBzZXR1cFRhYmxlKHRhYiwge2Zvb2Q6IFwiVEVYVFwiLCBmYWN0b3I6IFwiUkVBTFwifSxcbiAgICAoYXdhaXQgbG9hZEpvbmVzRmFjdG9ycygpKS52YWx1ZXMoKSBhcyBJdGVyYWJsZTxSb3dEYXRhPixcbiAgICBPYmplY3QuYXNzaWduKHtwazogXCJmb29kXCIsIGluZGV4OiB0cnVlLCB0c3ZlY3Rvcjoge2Zvb2Q6IFwiQVwifX0sIG9wdCkpO1xufVxuXG5cbi8qKlxuICogRmluZCBtYXRjaGluZyBqb25lcyBmYWN0b3JzIG9mIGEgZm9vZCBxdWVyeS5cbiAqIEBwYXJhbSB0eHQgZm9vZCBxdWVyeVxuICogQHJldHVybnMgbWF0Y2hlcyBgW3tmb29kLCBmYWN0b3J9XWBcbiAqIEBleGFtcGxlXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiBpZmN0MjAxNy5qb25lc0ZhY3RvcnMoJ21haWRhJyk7XG4gKiBpZmN0MjAxNy5qb25lc0ZhY3RvcnMoJ1JlZmluZWQgd2hlYXQnKTtcbiAqIC8vIOKGkiBbIHsgZm9vZDogJ1JlZmluZWQgd2hlYXQgZmxvdXIgKE1haWRhKScsIGZhY3RvcjogJzUuNzAnIH0gXVxuICpcbiAqIGlmY3QyMDE3LmpvbmVzRmFjdG9ycygnd2hhdCBpcyBqb25lcyBmYWN0b3Igb2YgYmFybGV5PycpO1xuICogaWZjdDIwMTcuam9uZXNGYWN0b3JzKCdqb25lcyBmYWN0b3Igb2Ygb2F0cycpO1xuICogLy8g4oaSIFsgeyBmb29kOiAnQmFybGV5IGFuZCBpdHMgZmxvdXI7UnllIGFuZCBpdHMgZmxvdXI7T2F0cycsXG4gKiAvLyDihpIgICAgIGZhY3RvcjogJzUuODMnIH0gXVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBqb25lc0ZhY3RvcnModHh0OiBzdHJpbmcpOiBKb25lc0ZhY3RvcltdIHtcbiAgaWYgKGluZGV4ID09IG51bGwpIHJldHVybiBbXTtcbiAgY29uc3QgYTogSm9uZXNGYWN0b3JbXSA9IFtdO1xuICB0eHQgPSB0eHQucmVwbGFjZSgvXFxXL2csICcgJykucmVwbGFjZSgvZmFjdG9yL2dpLCAnJyk7XG4gIGNvbnN0IG1hdHMgPSBpbmRleC5zZWFyY2godHh0KTsgbGV0IG1heCA9IDA7XG4gIGZvciAoY29uc3QgbWF0IG9mIG1hdHMpXG4gICAgbWF4ID0gTWF0aC5tYXgobWF4LCBPYmplY3Qua2V5cyhtYXQubWF0Y2hEYXRhLm1ldGFkYXRhKS5sZW5ndGgpO1xuICBmb3IgKGNvbnN0IG1hdCBvZiBtYXRzKVxuICAgIGlmIChPYmplY3Qua2V5cyhtYXQubWF0Y2hEYXRhLm1ldGFkYXRhKS5sZW5ndGggPT09IG1heCkgYS5wdXNoKGNvcnB1cz8uZ2V0KG1hdC5yZWYpIHx8IHt9IGFzIEpvbmVzRmFjdG9yKTtcbiAgcmV0dXJuIGEubGVuZ3RoPjA/IGEgOiBbY29ycHVzPy5nZXQoJ0Zvb2Qgd2hlcmUgc3BlY2lmaWMgZmFjdG9yIGlzIG5vdCBsaXN0ZWQnKSBhcyBKb25lc0ZhY3Rvcl07XG59XG4vLyNlbmRyZWdpb25cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxzQ0FBc0M7QUFDdEMsNkNBQTZDO0FBQzdDLDZCQUE2QjtBQUM3QixZQUFZLFNBQVUsV0FBVztBQUNqQyxPQUFPLFVBQVUsT0FBTyxDQUFFLHNDQUFzQztBQUNoRSxTQUE4QyxVQUFVLFFBQU8sbUJBQW1CO0FBYWxGLFlBQVk7QUFLWixpQkFBaUI7QUFDakIsSUFBSSxTQUEwQztBQUM5QyxJQUFJLFFBQTJCO0FBQy9CLFlBQVk7QUFLWixtQkFBbUI7QUFDbkI7Ozs7Q0FJQyxHQUNELGVBQWUsWUFBWSxJQUFZO0VBQ3JDLE1BQU0sTUFBTyxJQUFJO0VBQ2pCLE1BQU0sT0FBTyxNQUFNLENBQUMsTUFBTSxNQUFNLEtBQUssRUFBRSxJQUFJO0VBQzNDLE1BQU0sVUFBVSxJQUFJLEtBQUssQ0FBQyxNQUFNO0lBQUMsY0FBYztJQUFNLFNBQVM7RUFBRztFQUNqRSxLQUFLLE1BQU0sS0FBSyxRQUFTO0lBQ3ZCLE1BQU0sU0FBUyxXQUFXLEVBQUUsTUFBTTtJQUNsQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLElBQUksRUFBRTtNQUFDLE1BQU0sRUFBRSxJQUFJO01BQUU7SUFBTTtFQUN2QztFQUNBLE9BQU87QUFDVDtBQUdBOzs7Q0FHQyxHQUNELFNBQVMsV0FBVyxNQUFnQztFQUNsRCxPQUFPLEtBQUs7SUFDVixJQUFJLENBQUMsR0FBRyxDQUFDO0lBQ1QsSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNYLEtBQUssTUFBTSxLQUFLLE9BQU8sTUFBTSxHQUMzQixJQUFJLENBQUMsR0FBRyxDQUFDO01BQUMsS0FBSyxFQUFFLElBQUk7TUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZO0lBQUk7RUFDaEU7QUFDRjtBQUdBOzs7Q0FHQyxHQUNELE9BQU8sZUFBZTtFQUNwQixJQUFJLFFBQVEsT0FBTztFQUNuQixTQUFTLE1BQU0sWUFBWTtFQUMzQixRQUFTLFdBQVc7RUFDcEIsT0FBTztBQUNUO0FBR0E7OztDQUdDLEdBQ0QsT0FBTyxTQUFTO0VBQ2QsT0FBTyxZQUFZLE9BQU8sQ0FBQztBQUM3QjtBQUdBOzs7OztDQUtDLEdBQ0QsT0FBTyxlQUFlLGdCQUFnQixNQUFZLGNBQWMsRUFBRSxNQUF1QixDQUFDLENBQUM7RUFDekYsT0FBTyxXQUFXLEtBQUs7SUFBQyxNQUFNO0lBQVEsUUFBUTtFQUFNLEdBQ2xELENBQUMsTUFBTSxrQkFBa0IsRUFBRSxNQUFNLElBQ2pDLE9BQU8sTUFBTSxDQUFDO0lBQUMsSUFBSTtJQUFRLE9BQU87SUFBTSxVQUFVO01BQUMsTUFBTTtJQUFHO0VBQUMsR0FBRztBQUNwRTtBQUdBOzs7Ozs7Ozs7Ozs7Ozs7Q0FlQyxHQUNELE9BQU8sU0FBUyxhQUFhLEdBQVc7RUFDdEMsSUFBSSxTQUFTLE1BQU0sT0FBTyxFQUFFO0VBQzVCLE1BQU0sSUFBbUIsRUFBRTtFQUMzQixNQUFNLElBQUksT0FBTyxDQUFDLE9BQU8sS0FBSyxPQUFPLENBQUMsWUFBWTtFQUNsRCxNQUFNLE9BQU8sTUFBTSxNQUFNLENBQUM7RUFBTSxJQUFJLE1BQU07RUFDMUMsS0FBSyxNQUFNLE9BQU8sS0FDaEIsTUFBTSxLQUFLLEdBQUcsQ0FBQyxLQUFLLE9BQU8sSUFBSSxDQUFDLElBQUksU0FBUyxDQUFDLFFBQVEsRUFBRSxNQUFNO0VBQ2hFLEtBQUssTUFBTSxPQUFPLEtBQ2hCLElBQUksT0FBTyxJQUFJLENBQUMsSUFBSSxTQUFTLENBQUMsUUFBUSxFQUFFLE1BQU0sS0FBSyxLQUFLLEVBQUUsSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDO0VBQzFGLE9BQU8sRUFBRSxNQUFNLEdBQUMsSUFBRyxJQUFJO0lBQUMsUUFBUSxJQUFJO0dBQTJEO0FBQ2pHLEVBQ0EsWUFBWSJ9
@@ -0,0 +1,12 @@
1
+ Indian Food Composition Tables 2017
2
+ T. Longvah, R. Ananthan, K. Bhaskarachary and K. Venkaiah
3
+
4
+ Copyright © 2017 by National Institute of Nutrition
5
+ Indian Council of Medical Research
6
+ Department of Health Research Ministry of Health and Family Welfare, Government of India
7
+ Jamai Osmania (PO), Hyderabad – 500 007
8
+ Telangana, India Phone: +91 40 27197334, Fax: +91 40 27000339, Email: nin@ap.nic.in
9
+
10
+ JONES FACTORS FOR CONVERSION OF NITROGEN TO PROTEIN
11
+ - Food
12
+ - Conversion Factor
@@ -0,0 +1,22 @@
1
+ lang,abbr
2
+ Assamese,A.
3
+ Bengali,B.
4
+ English,E.
5
+ Gujarati,G.
6
+ Hindi,H.
7
+ Kannada,Kan.
8
+ Kashmiri,Kash.
9
+ Khasi,Kh.
10
+ Konkani,Kon.
11
+ Malayalam,Mal.
12
+ Manipuri,M.
13
+ Marathi,Mar.
14
+ Nepali,N.
15
+ Oriya,O.
16
+ Punjabi,P.
17
+ Sanskrit,S.
18
+ Tamil,Tam.
19
+ Telugu,Tel.
20
+ Urdu,U.
21
+ Scientific name,Sci.
22
+ Common name,Common
@@ -0,0 +1,39 @@
1
+ import { type SetupTableOptions } from "@nodef/extra-sql";
2
+ /** Full form of language abbreviation. */ export interface Language {
3
+ /** Language. */ lang: string;
4
+ /** Abbreviation used. */ abbr: string;
5
+ }
6
+ /**
7
+ * Load the languages corpus from the file.
8
+ * @returns languages corpus
9
+ */ export declare function loadLanguages(): Promise<Map<string, Language>>;
10
+ /**
11
+ * Get the path to the languages CSV file.
12
+ * @returns CSV file URL
13
+ */ export declare function languagesCsv(): string;
14
+ /**
15
+ * Obtain SQL command to create and populate the languages table.
16
+ * @param tab table name
17
+ * @param opt options for the table
18
+ * @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
19
+ */ export declare function languagesSql(tab?: string, opt?: SetupTableOptions): Promise<string>;
20
+ /**
21
+ * Find matching languages of an abbr/lang query.
22
+ * @param txt abbr/lang query
23
+ * @returns `{abbr, lang}` if found, else null
24
+ * @example
25
+ * ```javascript
26
+ * ifct2017.languages('mal.');
27
+ * ifct2017.languages('Mal');
28
+ * // → { abbr: 'Mal.', lang: 'Malayalam' }
29
+ *
30
+ * ifct2017.languages('what is s.?');
31
+ * ifct2017.languages('S. stands for?');
32
+ * // → { abbr: 'S.', lang: 'Sanskrit' }
33
+ *
34
+ *
35
+ * // Note:
36
+ * // Full stops must immediately follow character, if present.
37
+ * // For single character abbreviations, full stop is mandatory.
38
+ * ```
39
+ */ export declare function languages(txt: string): Language | null;
@@ -0,0 +1,103 @@
1
+ // Copyright (C) 2025-26 Subhajit Sahu
2
+ // SPDX-License-Identifier: AGPL-3.0-or-later
3
+ // See LICENSE for full terms
4
+ import * as csv from "@std/csv";
5
+ import { setupTable } from "@nodef/extra-sql";
6
+ //#endregion
7
+ //#region GLOBALS
8
+ let corpus = null;
9
+ let match = null;
10
+ //#endregion
11
+ //#region FUNCTIONS
12
+ /**
13
+ * Create a regex to match the abbreviations in the corpus.
14
+ * @param lst list of abbreviations to match
15
+ * @returns a regex to match the abbreviations
16
+ */ function createRegex(lst) {
17
+ let a = '(^|\\W+)(';
18
+ for (const v of lst)a += v.length > 1 ? `${v}|` : `${v}\\.|`;
19
+ a = a.substring(0, a.length - 1);
20
+ a += `)(\\W+|$)`;
21
+ return new RegExp(a, 'i');
22
+ }
23
+ /**
24
+ * Load the languages corpus from CSV file.
25
+ * @param file CSV file path
26
+ * @returns languages corpus
27
+ */ async function loadFromCsv(file) {
28
+ const map = new Map();
29
+ const data = await (await fetch(file)).text();
30
+ const records = csv.parse(data, {
31
+ skipFirstRow: true,
32
+ comment: "#"
33
+ });
34
+ for (const r of records){
35
+ const key = r.abbr.replace(/\W/g, '').toLowerCase();
36
+ map.set(key, r);
37
+ }
38
+ return map;
39
+ }
40
+ /**
41
+ * Load the languages corpus from the file.
42
+ * @returns languages corpus
43
+ */ export async function loadLanguages() {
44
+ if (corpus) return corpus;
45
+ corpus = await loadFromCsv(languagesCsv());
46
+ match = createRegex(corpus.keys());
47
+ return corpus;
48
+ }
49
+ /**
50
+ * Get the path to the languages CSV file.
51
+ * @returns CSV file URL
52
+ */ export function languagesCsv() {
53
+ return import.meta.resolve('./index.csv');
54
+ }
55
+ /**
56
+ * Obtain SQL command to create and populate the languages table.
57
+ * @param tab table name
58
+ * @param opt options for the table
59
+ * @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
60
+ */ export async function languagesSql(tab = "languages", opt = {}) {
61
+ return setupTable(tab, {
62
+ abbr: "TEXT",
63
+ lang: "TEXT"
64
+ }, (await loadLanguages()).values(), Object.assign({
65
+ pk: "abbr",
66
+ index: true,
67
+ tsvector: {
68
+ abbr: "A",
69
+ lang: "B"
70
+ }
71
+ }, opt));
72
+ }
73
+ /**
74
+ * Find matching languages of an abbr/lang query.
75
+ * @param txt abbr/lang query
76
+ * @returns `{abbr, lang}` if found, else null
77
+ * @example
78
+ * ```javascript
79
+ * ifct2017.languages('mal.');
80
+ * ifct2017.languages('Mal');
81
+ * // → { abbr: 'Mal.', lang: 'Malayalam' }
82
+ *
83
+ * ifct2017.languages('what is s.?');
84
+ * ifct2017.languages('S. stands for?');
85
+ * // → { abbr: 'S.', lang: 'Sanskrit' }
86
+ *
87
+ *
88
+ * // Note:
89
+ * // Full stops must immediately follow character, if present.
90
+ * // For single character abbreviations, full stop is mandatory.
91
+ * ```
92
+ */ export function languages(txt) {
93
+ if (match == null) return null;
94
+ const re = /((\w\s+|\w\.\s*|\w\-\s*|\w$)+)|\w+/g;
95
+ txt = txt.replace(re, (m)=>{
96
+ const v = m.replace(/\W/g, '');
97
+ return v.length === 1 ? m.trim() + ' ' : v + ' ';
98
+ }).toLowerCase();
99
+ const m = txt.match(match);
100
+ if (m == null) return null;
101
+ return corpus?.get(m[2].replace('.', '')) || null;
102
+ } //#endregion
103
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9pZmN0MjAxNy9pZmN0MjAxNy9sYW5ndWFnZXMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChDKSAyMDI1LTI2IFN1Ymhhaml0IFNhaHVcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vci1sYXRlclxuLy8gU2VlIExJQ0VOU0UgZm9yIGZ1bGwgdGVybXNcbmltcG9ydCAqIGFzIGNzdiAgZnJvbSBcIkBzdGQvY3N2XCI7XG5pbXBvcnQge3R5cGUgUm93RGF0YSwgdHlwZSBTZXR1cFRhYmxlT3B0aW9ucywgc2V0dXBUYWJsZX0gZnJvbSBcIkBub2RlZi9leHRyYS1zcWxcIjtcblxuXG5cblxuLy8jcmVnaW9uIFRZUEVTXG4vKiogRnVsbCBmb3JtIG9mIGxhbmd1YWdlIGFiYnJldmlhdGlvbi4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTGFuZ3VhZ2Uge1xuICAvKiogTGFuZ3VhZ2UuICovXG4gIGxhbmc6IHN0cmluZyxcbiAgLyoqIEFiYnJldmlhdGlvbiB1c2VkLiAqL1xuICBhYmJyOiBzdHJpbmdcbn07XG4vLyNlbmRyZWdpb25cblxuXG5cblxuLy8jcmVnaW9uIEdMT0JBTFNcbmxldCBjb3JwdXM6IE1hcDxzdHJpbmcsIExhbmd1YWdlPiB8IG51bGwgPSBudWxsO1xubGV0IG1hdGNoOiBSZWdFeHAgfCBudWxsID0gbnVsbDtcbi8vI2VuZHJlZ2lvblxuXG5cblxuXG4vLyNyZWdpb24gRlVOQ1RJT05TXG4vKipcbiAqIENyZWF0ZSBhIHJlZ2V4IHRvIG1hdGNoIHRoZSBhYmJyZXZpYXRpb25zIGluIHRoZSBjb3JwdXMuXG4gKiBAcGFyYW0gbHN0IGxpc3Qgb2YgYWJicmV2aWF0aW9ucyB0byBtYXRjaFxuICogQHJldHVybnMgYSByZWdleCB0byBtYXRjaCB0aGUgYWJicmV2aWF0aW9uc1xuICovXG5mdW5jdGlvbiBjcmVhdGVSZWdleChsc3Q6IEl0ZXJhYmxlPHN0cmluZz4pOiBSZWdFeHAge1xuICBsZXQgYSA9ICcoXnxcXFxcVyspKCc7XG4gIGZvciAoY29uc3QgdiBvZiBsc3QpXG4gICAgYSArPSB2Lmxlbmd0aD4xPyBgJHt2fXxgOmAke3Z9XFxcXC58YDtcbiAgYSA9IGEuc3Vic3RyaW5nKDAsIGEubGVuZ3RoLTEpO1xuICBhICs9IGApKFxcXFxXK3wkKWA7XG4gIHJldHVybiBuZXcgUmVnRXhwKGEsICdpJyk7XG59XG5cblxuLyoqXG4gKiBMb2FkIHRoZSBsYW5ndWFnZXMgY29ycHVzIGZyb20gQ1NWIGZpbGUuXG4gKiBAcGFyYW0gZmlsZSBDU1YgZmlsZSBwYXRoXG4gKiBAcmV0dXJucyBsYW5ndWFnZXMgY29ycHVzXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGxvYWRGcm9tQ3N2KGZpbGU6IHN0cmluZykge1xuICBjb25zdCBtYXAgID0gbmV3IE1hcDxzdHJpbmcsIExhbmd1YWdlPigpO1xuICBjb25zdCBkYXRhID0gYXdhaXQgKGF3YWl0IGZldGNoKGZpbGUpKS50ZXh0KCk7XG4gIGNvbnN0IHJlY29yZHMgPSBjc3YucGFyc2UoZGF0YSwge3NraXBGaXJzdFJvdzogdHJ1ZSwgY29tbWVudDogXCIjXCJ9KTtcbiAgZm9yIChjb25zdCByIG9mIHJlY29yZHMpIHtcbiAgICBjb25zdCBrZXkgPSByLmFiYnIucmVwbGFjZSgvXFxXL2csICcnKS50b0xvd2VyQ2FzZSgpO1xuICAgIG1hcC5zZXQoa2V5LCByIGFzIHVua25vd24gYXMgTGFuZ3VhZ2UpO1xuICB9XG4gIHJldHVybiBtYXA7XG59XG5cblxuLyoqXG4gKiBMb2FkIHRoZSBsYW5ndWFnZXMgY29ycHVzIGZyb20gdGhlIGZpbGUuXG4gKiBAcmV0dXJucyBsYW5ndWFnZXMgY29ycHVzXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2FkTGFuZ3VhZ2VzKCk6IFByb21pc2U8TWFwPHN0cmluZywgTGFuZ3VhZ2U+PiB7XG4gIGlmIChjb3JwdXMpIHJldHVybiBjb3JwdXM7XG4gIGNvcnB1cyA9IGF3YWl0IGxvYWRGcm9tQ3N2KGxhbmd1YWdlc0NzdigpKTtcbiAgbWF0Y2ggID0gY3JlYXRlUmVnZXgoY29ycHVzLmtleXMoKSk7XG4gIHJldHVybiBjb3JwdXM7XG59XG5cblxuLyoqXG4gKiBHZXQgdGhlIHBhdGggdG8gdGhlIGxhbmd1YWdlcyBDU1YgZmlsZS5cbiAqIEByZXR1cm5zIENTViBmaWxlIFVSTFxuICovXG5leHBvcnQgZnVuY3Rpb24gbGFuZ3VhZ2VzQ3N2KCk6IHN0cmluZyB7XG4gIHJldHVybiBpbXBvcnQubWV0YS5yZXNvbHZlKCcuL2luZGV4LmNzdicpO1xufVxuXG5cbi8qKlxuICogT2J0YWluIFNRTCBjb21tYW5kIHRvIGNyZWF0ZSBhbmQgcG9wdWxhdGUgdGhlIGxhbmd1YWdlcyB0YWJsZS5cbiAqIEBwYXJhbSB0YWIgdGFibGUgbmFtZVxuICogQHBhcmFtIG9wdCBvcHRpb25zIGZvciB0aGUgdGFibGVcbiAqIEByZXR1cm5zIENSRUFURSBUQUJMRSwgSU5TRVJULCBDUkVBVEUgVklFVywgQ1JFQVRFIElOREVYIHN0YXRlbWVudHNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxhbmd1YWdlc1NxbCh0YWI6IHN0cmluZz1cImxhbmd1YWdlc1wiLCBvcHQ6IFNldHVwVGFibGVPcHRpb25zPXt9KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgcmV0dXJuIHNldHVwVGFibGUodGFiLCB7YWJicjogXCJURVhUXCIsIGxhbmc6IFwiVEVYVFwifSxcbiAgICAoYXdhaXQgbG9hZExhbmd1YWdlcygpKS52YWx1ZXMoKSBhcyBJdGVyYWJsZTxSb3dEYXRhPixcbiAgICBPYmplY3QuYXNzaWduKHtwazogXCJhYmJyXCIsIGluZGV4OiB0cnVlLCB0c3ZlY3Rvcjoge2FiYnI6IFwiQVwiLCBsYW5nOiBcIkJcIn19LCBvcHQpKTtcbn1cblxuXG4vKipcbiAqIEZpbmQgbWF0Y2hpbmcgbGFuZ3VhZ2VzIG9mIGFuIGFiYnIvbGFuZyBxdWVyeS5cbiAqIEBwYXJhbSB0eHQgYWJici9sYW5nIHF1ZXJ5XG4gKiBAcmV0dXJucyBge2FiYnIsIGxhbmd9YCBpZiBmb3VuZCwgZWxzZSBudWxsXG4gKiBAZXhhbXBsZVxuICogYGBgamF2YXNjcmlwdFxuICogaWZjdDIwMTcubGFuZ3VhZ2VzKCdtYWwuJyk7XG4gKiBpZmN0MjAxNy5sYW5ndWFnZXMoJ01hbCcpO1xuICogLy8g4oaSIHsgYWJicjogJ01hbC4nLCBsYW5nOiAnTWFsYXlhbGFtJyB9XG4gKlxuICogaWZjdDIwMTcubGFuZ3VhZ2VzKCd3aGF0IGlzIHMuPycpO1xuICogaWZjdDIwMTcubGFuZ3VhZ2VzKCdTLiBzdGFuZHMgZm9yPycpO1xuICogLy8g4oaSIHsgYWJicjogJ1MuJywgbGFuZzogJ1NhbnNrcml0JyB9XG4gKlxuICpcbiAqIC8vIE5vdGU6XG4gKiAvLyBGdWxsIHN0b3BzIG11c3QgaW1tZWRpYXRlbHkgZm9sbG93IGNoYXJhY3RlciwgaWYgcHJlc2VudC5cbiAqIC8vIEZvciBzaW5nbGUgY2hhcmFjdGVyIGFiYnJldmlhdGlvbnMsIGZ1bGwgc3RvcCBpcyBtYW5kYXRvcnkuXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxhbmd1YWdlcyh0eHQ6IHN0cmluZyk6IExhbmd1YWdlIHwgbnVsbCB7XG4gIGlmIChtYXRjaD09bnVsbCkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHJlID0gLygoXFx3XFxzK3xcXHdcXC5cXHMqfFxcd1xcLVxccyp8XFx3JCkrKXxcXHcrL2c7XG4gIHR4dCA9IHR4dC5yZXBsYWNlKHJlLCBtID0+IHtcbiAgICBjb25zdCB2ID0gbS5yZXBsYWNlKC9cXFcvZywgJycpO1xuICAgIHJldHVybiB2Lmxlbmd0aD09PTE/IG0udHJpbSgpKycgJyA6IHYrJyAnO1xuICB9KS50b0xvd2VyQ2FzZSgpO1xuICBjb25zdCBtID0gdHh0Lm1hdGNoKG1hdGNoKTtcbiAgaWYgKG09PW51bGwpIHJldHVybiBudWxsO1xuICByZXR1cm4gY29ycHVzPy5nZXQobVsyXS5yZXBsYWNlKCcuJywgJycpKSB8fCBudWxsO1xufVxuLy8j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
@@ -0,0 +1,12 @@
1
+ Indian Food Composition Tables 2017
2
+ T. Longvah, R. Ananthan, K. Bhaskarachary and K. Venkaiah
3
+
4
+ Copyright © 2017 by National Institute of Nutrition
5
+ Indian Council of Medical Research
6
+ Department of Health Research Ministry of Health and Family Welfare, Government of India
7
+ Jamai Osmania (PO), Hyderabad – 500 007
8
+ Telangana, India Phone: +91 40 27197334, Fax: +91 40 27000339, Email: nin@ap.nic.in
9
+
10
+ LANGUAGE ABBREVIATIONS
11
+ - Languages
12
+ - Abbreviations used