ifct2017 2.0.15 → 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.
- package/LICENSE +661 -21
- package/README.md +1019 -71
- package/abbreviations/index.csv +78 -0
- package/abbreviations/index.d.ts +39 -0
- package/abbreviations/index.js +103 -0
- package/abbreviations/index.txt +12 -0
- package/about/build.ts +31 -0
- package/about/index.d.ts +47 -0
- package/about/index.js +110 -0
- package/about/index.txt +174 -0
- package/build.ts +115 -0
- package/carbohydrates/index.csv +8 -0
- package/carbohydrates/index.d.ts +42 -0
- package/carbohydrates/index.js +112 -0
- package/carbohydrates/index.txt +14 -0
- package/codes/index.csv +2904 -0
- package/codes/index.d.ts +36 -0
- package/codes/index.js +102 -0
- package/codes/index.txt +12 -0
- package/columndescriptions/build.ts +22 -0
- package/columndescriptions/index.csv +215 -0
- package/columndescriptions/index.d.ts +44 -0
- package/columndescriptions/index.js +119 -0
- package/columns/build.ts +23 -0
- package/columns/index.csv +215 -0
- package/columns/index.d.ts +39 -0
- package/columns/index.js +111 -0
- package/columns/index.txt +71 -0
- package/compositingcentres/index.csv +7 -0
- package/compositingcentres/index.d.ts +35 -0
- package/compositingcentres/index.js +103 -0
- package/compositingcentres/index.txt +13 -0
- package/compositions/build.ts +212 -0
- package/compositions/index.csv +543 -0
- package/compositions/index.d.ts +254 -0
- package/compositions/index.js +204 -0
- package/compositionstats/build.ts +103 -0
- package/compositionstats/index.csv +4 -0
- package/compositionstats/index.d.ts +31 -0
- package/compositionstats/index.js +97 -0
- package/contents/index.csv +21 -0
- package/contents/index.d.ts +39 -0
- package/contents/index.js +102 -0
- package/contents/index.txt +13 -0
- package/deno.lock +67 -0
- package/descriptions/index.csv +543 -0
- package/descriptions/index.d.ts +45 -0
- package/descriptions/index.js +124 -0
- package/descriptions/index.txt +15 -0
- package/energies/index.csv +6 -0
- package/energies/index.d.ts +34 -0
- package/energies/index.js +101 -0
- package/energies/index.txt +13 -0
- package/frequencydistribution/index.csv +10 -0
- package/frequencydistribution/index.d.ts +36 -0
- package/frequencydistribution/index.js +90 -0
- package/frequencydistribution/index.txt +14 -0
- package/groups/index.csv +21 -0
- package/groups/index.d.ts +46 -0
- package/groups/index.js +118 -0
- package/groups/index.txt +14 -0
- package/hierarchy/asset.csv +215 -0
- package/hierarchy/asset.txt +70 -0
- package/hierarchy/build.ts +73 -0
- package/hierarchy/index.csv +215 -0
- package/hierarchy/index.d.ts +39 -0
- package/hierarchy/index.js +100 -0
- package/hierarchy/index.txt +14 -0
- package/index.d.ts +24 -28
- package/index.js +28 -39
- package/index.test.ts +717 -0
- package/intakes/build.ts +28 -0
- package/intakes/index.csv +42 -0
- package/intakes/index.d.ts +66 -0
- package/intakes/index.js +113 -0
- package/intakes/index.txt +20 -0
- package/jonesfactors/index.csv +15 -0
- package/jonesfactors/index.d.ts +35 -0
- package/jonesfactors/index.js +105 -0
- package/jonesfactors/index.txt +12 -0
- package/languages/index.csv +22 -0
- package/languages/index.d.ts +39 -0
- package/languages/index.js +103 -0
- package/languages/index.txt +12 -0
- package/methods/build.ts +101 -0
- package/methods/index.csv +37 -0
- package/methods/index.d.ts +39 -0
- package/methods/index.js +196 -0
- package/methods/index.txt +13 -0
- package/package.json +15 -63
- package/regions/index.csv +7 -0
- package/regions/index.d.ts +36 -0
- package/regions/index.js +100 -0
- package/regions/index.txt +12 -0
- package/representations/build.ts +133 -0
- package/representations/index.csv +215 -0
- package/representations/index.d.ts +36 -0
- package/representations/index.js +91 -0
- package/retentionfactors/groups.csv +21 -0
- package/retentionfactors/index.csv +215 -0
- package/samplingunits/index.csv +36 -0
- package/samplingunits/index.d.ts +39 -0
- package/samplingunits/index.js +110 -0
- package/samplingunits/index.txt +14 -0
- package/yieldfactors/index.csv +543 -0
- package/yieldfactors/index.d.ts +57 -0
- package/yieldfactors/index.js +158 -0
- package/yieldfactors/index.txt +294 -0
- package/corpus.js +0 -6
- package/corpus.min.js +0 -1
- package/pictures.d.ts +0 -41
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type SetupTableOptions } from "@nodef/extra-sql";
|
|
2
|
+
/** Regional compositing centre and sample size of each region. */ export interface CompositingCentre {
|
|
3
|
+
/** Region. */ region: string;
|
|
4
|
+
/** Regional Compositing centre. */ centre: string;
|
|
5
|
+
/** Sample size. */ samples: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Load the compositing centres corpus from the file.
|
|
9
|
+
* @returns compositing centres corpus
|
|
10
|
+
*/ export declare function loadCompositingCentres(): Promise<Map<string, CompositingCentre>>;
|
|
11
|
+
/**
|
|
12
|
+
* Get the path to the compositing centres CSV file.
|
|
13
|
+
* @returns CSV file URL
|
|
14
|
+
*/ export declare function compositingCentresCsv(): string;
|
|
15
|
+
/**
|
|
16
|
+
* Obtain SQL command to create and populate the compositing centres table.
|
|
17
|
+
* @param tab table name
|
|
18
|
+
* @param opt options for the table
|
|
19
|
+
* @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
|
|
20
|
+
*/ export declare function compositingCentresSql(tab?: string, opt?: SetupTableOptions): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Find matching compositing centres of a region/centre query.
|
|
23
|
+
* @param txt region/centre query
|
|
24
|
+
* @returns matches `[{region, centre, samples}]`
|
|
25
|
+
* @examples
|
|
26
|
+
* ```javascript
|
|
27
|
+
* ifct2017.compositingCentres('west');
|
|
28
|
+
* ifct2017.compositingCentres('Mumbai');
|
|
29
|
+
* // → [ { region: 'West', centre: 'Mumbai', samples: 12 } ]
|
|
30
|
+
*
|
|
31
|
+
* ifct2017.compositingCentres('what is compositing centre of north east?');
|
|
32
|
+
* ifct2017.compositingCentres('North East compositing centre');
|
|
33
|
+
* // → [ { region: 'North East', centre: 'Guwahati', samples: 11 } ]
|
|
34
|
+
* ```
|
|
35
|
+
*/ export declare function compositingCentres(txt: string): CompositingCentre[];
|
|
@@ -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 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 compositing centres corpus from CSV file.
|
|
15
|
+
* @param file CSV file path
|
|
16
|
+
* @returns compositing centres 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 samples = parseFloat(r.samples);
|
|
26
|
+
map.set(r.region, {
|
|
27
|
+
region: r.region,
|
|
28
|
+
centre: r.centre,
|
|
29
|
+
samples
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return map;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Setup the lunr index for the compositing centres corpus.
|
|
36
|
+
* @returns lunr index
|
|
37
|
+
*/ function setupIndex(corpus) {
|
|
38
|
+
return lunr(function() {
|
|
39
|
+
this.ref('region');
|
|
40
|
+
this.field('region');
|
|
41
|
+
this.field('centre');
|
|
42
|
+
for (const r of corpus.values())this.add(r);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Load the compositing centres corpus from the file.
|
|
47
|
+
* @returns compositing centres corpus
|
|
48
|
+
*/ export async function loadCompositingCentres() {
|
|
49
|
+
if (corpus) return corpus;
|
|
50
|
+
corpus = await loadFromCsv(compositingCentresCsv());
|
|
51
|
+
index = setupIndex(corpus);
|
|
52
|
+
return corpus;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get the path to the compositing centres CSV file.
|
|
56
|
+
* @returns CSV file URL
|
|
57
|
+
*/ export function compositingCentresCsv() {
|
|
58
|
+
return import.meta.resolve('./index.csv');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Obtain SQL command to create and populate the compositing centres table.
|
|
62
|
+
* @param tab table name
|
|
63
|
+
* @param opt options for the table
|
|
64
|
+
* @returns CREATE TABLE, INSERT, CREATE VIEW, CREATE INDEX statements
|
|
65
|
+
*/ export async function compositingCentresSql(tab = "compositingcentres", opt = {}) {
|
|
66
|
+
return setupTable(tab, {
|
|
67
|
+
region: "TEXT",
|
|
68
|
+
centre: "TEXT",
|
|
69
|
+
samples: "INT"
|
|
70
|
+
}, (await loadCompositingCentres()).values(), Object.assign({
|
|
71
|
+
pk: "region",
|
|
72
|
+
index: true,
|
|
73
|
+
tsvector: {
|
|
74
|
+
region: "A",
|
|
75
|
+
centre: "B"
|
|
76
|
+
}
|
|
77
|
+
}, opt));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Find matching compositing centres of a region/centre query.
|
|
81
|
+
* @param txt region/centre query
|
|
82
|
+
* @returns matches `[{region, centre, samples}]`
|
|
83
|
+
* @examples
|
|
84
|
+
* ```javascript
|
|
85
|
+
* ifct2017.compositingCentres('west');
|
|
86
|
+
* ifct2017.compositingCentres('Mumbai');
|
|
87
|
+
* // → [ { region: 'West', centre: 'Mumbai', samples: 12 } ]
|
|
88
|
+
*
|
|
89
|
+
* ifct2017.compositingCentres('what is compositing centre of north east?');
|
|
90
|
+
* ifct2017.compositingCentres('North East compositing centre');
|
|
91
|
+
* // → [ { region: 'North East', centre: 'Guwahati', samples: 11 } ]
|
|
92
|
+
* ```
|
|
93
|
+
*/ export function compositingCentres(txt) {
|
|
94
|
+
if (index == null) return [];
|
|
95
|
+
const a = [];
|
|
96
|
+
txt = txt.replace(/\W/g, ' ');
|
|
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;
|
|
102
|
+
} //#endregion
|
|
103
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9pZmN0MjAxNy9pZmN0MjAxNy9jb21wb3NpdGluZ2NlbnRyZXMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChDKSAyMDI1LTI2IFN1Ymhhaml0IFNhaHVcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vci1sYXRlclxuLy8gU2VlIExJQ0VOU0UgZm9yIGZ1bGwgdGVybXNcbmltcG9ydCAqIGFzIGNzdiAgZnJvbSBcIkBzdGQvY3N2XCI7XG5pbXBvcnQgbHVuciBmcm9tIFwibHVuclwiOyAgLy8gQGRlbm8tdHlwZXM9XCJucG06QHR5cGVzL2x1bnJAMi4zLjdcIlxuaW1wb3J0IHt0eXBlIFJvd0RhdGEsIHR5cGUgU2V0dXBUYWJsZU9wdGlvbnMsIHNldHVwVGFibGV9IGZyb20gXCJAbm9kZWYvZXh0cmEtc3FsXCI7XG5cblxuXG5cbi8vI3JlZ2lvbiBUWVBFU1xuLyoqIFJlZ2lvbmFsIGNvbXBvc2l0aW5nIGNlbnRyZSBhbmQgc2FtcGxlIHNpemUgb2YgZWFjaCByZWdpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvc2l0aW5nQ2VudHJlIHtcbiAgLyoqIFJlZ2lvbi4gKi9cbiAgcmVnaW9uOiBzdHJpbmcsXG4gIC8qKiBSZWdpb25hbCBDb21wb3NpdGluZyBjZW50cmUuICovXG4gIGNlbnRyZTogc3RyaW5nLFxuICAvKiogU2FtcGxlIHNpemUuICovXG4gIHNhbXBsZXM6IG51bWJlclxufTtcbi8vI2VuZHJlZ2lvblxuXG5cblxuXG4vLyNyZWdpb24gR0xPQkFMU1xubGV0IGNvcnB1czogTWFwPHN0cmluZywgQ29tcG9zaXRpbmdDZW50cmU+IHwgbnVsbCA9IG51bGw7XG5sZXQgaW5kZXg6IGx1bnIuSW5kZXggfCBudWxsID0gbnVsbDtcbi8vI2VuZHJlZ2lvblxuXG5cblxuXG4vLyNyZWdpb24gRlVOQ1RJT05TXG4vKipcbiAqIExvYWQgdGhlIGNvbXBvc2l0aW5nIGNlbnRyZXMgY29ycHVzIGZyb20gQ1NWIGZpbGUuXG4gKiBAcGFyYW0gZmlsZSBDU1YgZmlsZSBwYXRoXG4gKiBAcmV0dXJucyBjb21wb3NpdGluZyBjZW50cmVzIGNvcnB1c1xuICovXG5hc3luYyBmdW5jdGlvbiBsb2FkRnJvbUNzdihmaWxlOiBzdHJpbmcpIHtcbiAgY29uc3QgbWFwICA9IG5ldyBNYXA8c3RyaW5nLCBDb21wb3NpdGluZ0NlbnRyZT4oKTtcbiAgY29uc3QgZGF0YSA9IGF3YWl0IChhd2FpdCBmZXRjaChmaWxlKSkudGV4dCgpO1xuICBjb25zdCByZWNvcmRzID0gY3N2LnBhcnNlKGRhdGEsIHtza2lwRmlyc3RSb3c6IHRydWUsIGNvbW1lbnQ6IFwiI1wifSk7XG4gIGZvciAoY29uc3QgciBvZiByZWNvcmRzKSB7XG4gICAgY29uc3Qgc2FtcGxlcyA9IHBhcnNlRmxvYXQoci5zYW1wbGVzKTtcbiAgICBtYXAuc2V0KHIucmVnaW9uLCB7cmVnaW9uOiByLnJlZ2lvbiwgY2VudHJlOiByLmNlbnRyZSwgc2FtcGxlc30pO1xuICB9XG4gIHJldHVybiBtYXA7XG59XG5cblxuLyoqXG4gKiBTZXR1cCB0aGUgbHVuciBpbmRleCBmb3IgdGhlIGNvbXBvc2l0aW5nIGNlbnRyZXMgY29ycHVzLlxuICogQHJldHVybnMgbHVuciBpbmRleFxuICovXG5mdW5jdGlvbiBzZXR1cEluZGV4KGNvcnB1czogTWFwPHN0cmluZywgQ29tcG9zaXRpbmdDZW50cmU+KSB7XG4gIHJldHVybiBsdW5yKGZ1bmN0aW9uKHRoaXM6IGx1bnIuQnVpbGRlcikge1xuICAgIHRoaXMucmVmKCdyZWdpb24nKTtcbiAgICB0aGlzLmZpZWxkKCdyZWdpb24nKTtcbiAgICB0aGlzLmZpZWxkKCdjZW50cmUnKTtcbiAgICBmb3IgKGNvbnN0IHIgb2YgY29ycHVzLnZhbHVlcygpKVxuICAgICAgdGhpcy5hZGQocik7XG4gIH0pO1xufVxuXG5cbi8qKlxuICogTG9hZCB0aGUgY29tcG9zaXRpbmcgY2VudHJlcyBjb3JwdXMgZnJvbSB0aGUgZmlsZS5cbiAqIEByZXR1cm5zIGNvbXBvc2l0aW5nIGNlbnRyZXMgY29ycHVzXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2FkQ29tcG9zaXRpbmdDZW50cmVzKCk6IFByb21pc2U8TWFwPHN0cmluZywgQ29tcG9zaXRpbmdDZW50cmU+PiB7XG4gIGlmIChjb3JwdXMpIHJldHVybiBjb3JwdXM7XG4gIGNvcnB1cyA9IGF3YWl0IGxvYWRGcm9tQ3N2KGNvbXBvc2l0aW5nQ2VudHJlc0NzdigpKTtcbiAgaW5kZXggID0gc2V0dXBJbmRleChjb3JwdXMpO1xuICByZXR1cm4gY29ycHVzO1xufVxuXG5cbi8qKlxuICogR2V0IHRoZSBwYXRoIHRvIHRoZSBjb21wb3NpdGluZyBjZW50cmVzIENTViBmaWxlLlxuICogQHJldHVybnMgQ1NWIGZpbGUgVVJMXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wb3NpdGluZ0NlbnRyZXNDc3YoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGltcG9ydC5tZXRhLnJlc29sdmUoJy4vaW5kZXguY3N2Jyk7XG59XG5cblxuLyoqXG4gKiBPYnRhaW4gU1FMIGNvbW1hbmQgdG8gY3JlYXRlIGFuZCBwb3B1bGF0ZSB0aGUgY29tcG9zaXRpbmcgY2VudHJlcyB0YWJsZS5cbiAqIEBwYXJhbSB0YWIgdGFibGUgbmFtZVxuICogQHBhcmFtIG9wdCBvcHRpb25zIGZvciB0aGUgdGFibGVcbiAqIEByZXR1cm5zIENSRUFURSBUQUJMRSwgSU5TRVJULCBDUkVBVEUgVklFVywgQ1JFQVRFIElOREVYIHN0YXRlbWVudHNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvbXBvc2l0aW5nQ2VudHJlc1NxbCh0YWI6IHN0cmluZz1cImNvbXBvc2l0aW5nY2VudHJlc1wiLCBvcHQ6IFNldHVwVGFibGVPcHRpb25zPXt9KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgcmV0dXJuIHNldHVwVGFibGUodGFiLCB7cmVnaW9uOiBcIlRFWFRcIiwgY2VudHJlOiBcIlRFWFRcIiwgc2FtcGxlczogXCJJTlRcIn0sXG4gICAgKGF3YWl0IGxvYWRDb21wb3NpdGluZ0NlbnRyZXMoKSkudmFsdWVzKCkgYXMgSXRlcmFibGU8Um93RGF0YT4sXG4gICAgT2JqZWN0LmFzc2lnbih7cGs6IFwicmVnaW9uXCIsIGluZGV4OiB0cnVlLCB0c3ZlY3Rvcjoge3JlZ2lvbjogXCJBXCIsIGNlbnRyZTogXCJCXCJ9fSwgb3B0KSk7XG59XG5cblxuLyoqXG4gKiBGaW5kIG1hdGNoaW5nIGNvbXBvc2l0aW5nIGNlbnRyZXMgb2YgYSByZWdpb24vY2VudHJlIHF1ZXJ5LlxuICogQHBhcmFtIHR4dCByZWdpb24vY2VudHJlIHF1ZXJ5XG4gKiBAcmV0dXJucyBtYXRjaGVzIGBbe3JlZ2lvbiwgY2VudHJlLCBzYW1wbGVzfV1gXG4gKiBAZXhhbXBsZXNcbiAqIGBgYGphdmFzY3JpcHRcbiAqIGlmY3QyMDE3LmNvbXBvc2l0aW5nQ2VudHJlcygnd2VzdCcpO1xuICogaWZjdDIwMTcuY29tcG9zaXRpbmdDZW50cmVzKCdNdW1iYWknKTtcbiAqIC8vIOKGkiBbIHsgcmVnaW9uOiAnV2VzdCcsIGNlbnRyZTogJ011bWJhaScsIHNhbXBsZXM6IDEyIH0gXVxuICpcbiAqIGlmY3QyMDE3LmNvbXBvc2l0aW5nQ2VudHJlcygnd2hhdCBpcyBjb21wb3NpdGluZyBjZW50cmUgb2Ygbm9ydGggZWFzdD8nKTtcbiAqIGlmY3QyMDE3LmNvbXBvc2l0aW5nQ2VudHJlcygnTm9ydGggRWFzdCBjb21wb3NpdGluZyBjZW50cmUnKTtcbiAqIC8vIOKGkiBbIHsgcmVnaW9uOiAnTm9ydGggRWFzdCcsIGNlbnRyZTogJ0d1d2FoYXRpJywgc2FtcGxlczogMTEgfSBdXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBvc2l0aW5nQ2VudHJlcyh0eHQ6IHN0cmluZyk6IENvbXBvc2l0aW5nQ2VudHJlW10ge1xuICBpZiAoaW5kZXggPT0gbnVsbCkgcmV0dXJuIFtdO1xuICBjb25zdCBhOiBDb21wb3NpdGluZ0NlbnRyZVtdID0gW107IHR4dCA9IHR4dC5yZXBsYWNlKC9cXFcvZywgJyAnKTtcbiAgY29uc3QgbWF0cyA9IGluZGV4LnNlYXJjaCh0eHQpOyBsZXQgbWF4ID0gMDtcbiAgZm9yIChjb25zdCBtYXQgb2YgbWF0cylcbiAgICBtYXggPSBNYXRoLm1heChtYXgsIE9iamVjdC5rZXlzKG1hdC5tYXRjaERhdGEubWV0YWRhdGEpLmxlbmd0aCk7XG4gIGZvciAoY29uc3QgbWF0IG9mIG1hdHMpXG4gICAgaWYgKE9iamVjdC5rZXlzKG1hdC5tYXRjaERhdGEubWV0YWRhdGEpLmxlbmd0aCA9PT0gbWF4KSBhLnB1c2goY29ycHVzPy5nZXQobWF0LnJlZikgfHwge30gYXMgQ29tcG9zaXRpbmdDZW50cmUpO1xuICByZXR1cm4gYTtcbn1cbi8vI2VuZHJlZ2lvblxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHNDQUFzQztBQUN0Qyw2Q0FBNkM7QUFDN0MsNkJBQTZCO0FBQzdCLFlBQVksU0FBVSxXQUFXO0FBQ2pDLE9BQU8sVUFBVSxPQUFPLENBQUUsc0NBQXNDO0FBQ2hFLFNBQThDLFVBQVUsUUFBTyxtQkFBbUI7QUFlbEYsWUFBWTtBQUtaLGlCQUFpQjtBQUNqQixJQUFJLFNBQWdEO0FBQ3BELElBQUksUUFBMkI7QUFDL0IsWUFBWTtBQUtaLG1CQUFtQjtBQUNuQjs7OztDQUlDLEdBQ0QsZUFBZSxZQUFZLElBQVk7RUFDckMsTUFBTSxNQUFPLElBQUk7RUFDakIsTUFBTSxPQUFPLE1BQU0sQ0FBQyxNQUFNLE1BQU0sS0FBSyxFQUFFLElBQUk7RUFDM0MsTUFBTSxVQUFVLElBQUksS0FBSyxDQUFDLE1BQU07SUFBQyxjQUFjO0lBQU0sU0FBUztFQUFHO0VBQ2pFLEtBQUssTUFBTSxLQUFLLFFBQVM7SUFDdkIsTUFBTSxVQUFVLFdBQVcsRUFBRSxPQUFPO0lBQ3BDLElBQUksR0FBRyxDQUFDLEVBQUUsTUFBTSxFQUFFO01BQUMsUUFBUSxFQUFFLE1BQU07TUFBRSxRQUFRLEVBQUUsTUFBTTtNQUFFO0lBQU87RUFDaEU7RUFDQSxPQUFPO0FBQ1Q7QUFHQTs7O0NBR0MsR0FDRCxTQUFTLFdBQVcsTUFBc0M7RUFDeEQsT0FBTyxLQUFLO0lBQ1YsSUFBSSxDQUFDLEdBQUcsQ0FBQztJQUNULElBQUksQ0FBQyxLQUFLLENBQUM7SUFDWCxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ1gsS0FBSyxNQUFNLEtBQUssT0FBTyxNQUFNLEdBQzNCLElBQUksQ0FBQyxHQUFHLENBQUM7RUFDYjtBQUNGO0FBR0E7OztDQUdDLEdBQ0QsT0FBTyxlQUFlO0VBQ3BCLElBQUksUUFBUSxPQUFPO0VBQ25CLFNBQVMsTUFBTSxZQUFZO0VBQzNCLFFBQVMsV0FBVztFQUNwQixPQUFPO0FBQ1Q7QUFHQTs7O0NBR0MsR0FDRCxPQUFPLFNBQVM7RUFDZCxPQUFPLFlBQVksT0FBTyxDQUFDO0FBQzdCO0FBR0E7Ozs7O0NBS0MsR0FDRCxPQUFPLGVBQWUsc0JBQXNCLE1BQVksb0JBQW9CLEVBQUUsTUFBdUIsQ0FBQyxDQUFDO0VBQ3JHLE9BQU8sV0FBVyxLQUFLO0lBQUMsUUFBUTtJQUFRLFFBQVE7SUFBUSxTQUFTO0VBQUssR0FDcEUsQ0FBQyxNQUFNLHdCQUF3QixFQUFFLE1BQU0sSUFDdkMsT0FBTyxNQUFNLENBQUM7SUFBQyxJQUFJO0lBQVUsT0FBTztJQUFNLFVBQVU7TUFBQyxRQUFRO01BQUssUUFBUTtJQUFHO0VBQUMsR0FBRztBQUNyRjtBQUdBOzs7Ozs7Ozs7Ozs7OztDQWNDLEdBQ0QsT0FBTyxTQUFTLG1CQUFtQixHQUFXO0VBQzVDLElBQUksU0FBUyxNQUFNLE9BQU8sRUFBRTtFQUM1QixNQUFNLElBQXlCLEVBQUU7RUFBRSxNQUFNLElBQUksT0FBTyxDQUFDLE9BQU87RUFDNUQsTUFBTSxPQUFPLE1BQU0sTUFBTSxDQUFDO0VBQU0sSUFBSSxNQUFNO0VBQzFDLEtBQUssTUFBTSxPQUFPLEtBQ2hCLE1BQU0sS0FBSyxHQUFHLENBQUMsS0FBSyxPQUFPLElBQUksQ0FBQyxJQUFJLFNBQVMsQ0FBQyxRQUFRLEVBQUUsTUFBTTtFQUNoRSxLQUFLLE1BQU0sT0FBTyxLQUNoQixJQUFJLE9BQU8sSUFBSSxDQUFDLElBQUksU0FBUyxDQUFDLFFBQVEsRUFBRSxNQUFNLEtBQUssS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQztFQUMxRixPQUFPO0FBQ1QsRUFDQSxZQUFZIn0=
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
+
REGIONAL COMPOSITING CENTRES AND SAMPLE SIZE OF EACH REGION
|
|
11
|
+
- Region
|
|
12
|
+
- Regional Compositing centre
|
|
13
|
+
- Sample size
|
|
@@ -0,0 +1,212 @@
|
|
|
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
|
+
import {loadColumns} from "../columns/index.ts";
|
|
7
|
+
import {type Description, loadDescriptions} from "../descriptions/index.ts";
|
|
8
|
+
import {type Group, loadGroups} from "../groups/index.ts";
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
const BASE = ['code', 'name', 'scie', 'lang', 'grup', 'regn', 'tags'];
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
function round(val: number) {
|
|
19
|
+
return Math.round(val * 1e+12) / 1e+12;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
// function significantDigits(n: number) {
|
|
24
|
+
// return n.toExponential().replace(/e[\+\-0-9]*$/, '').replace( /^0\.?0*|\./, '').length;
|
|
25
|
+
// }
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
type ReduceFn<V=string> = (acc: Map<string, V>, r: Record<string, string>) => void;
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
async function readCsv<V=string>(pth: string, fn: ReduceFn<V>, acc: Map<string, V>) {
|
|
32
|
+
const data = await Deno.readTextFile(pth);
|
|
33
|
+
const records = csv.parse(data, {skipFirstRow: true, comment: "#"});
|
|
34
|
+
for (const record of records)
|
|
35
|
+
fn(acc, record);
|
|
36
|
+
return acc;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
interface Dat {
|
|
41
|
+
code: string[];
|
|
42
|
+
name: string[];
|
|
43
|
+
scie: string[];
|
|
44
|
+
lang: string[];
|
|
45
|
+
grup: string[];
|
|
46
|
+
regn: number[];
|
|
47
|
+
tags: string[];
|
|
48
|
+
[key: string]: unknown[];
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
async function writeIndex() {
|
|
55
|
+
let dat: Dat = {
|
|
56
|
+
code: [],
|
|
57
|
+
name: [],
|
|
58
|
+
scie: [],
|
|
59
|
+
lang: [],
|
|
60
|
+
grup: [],
|
|
61
|
+
regn: [],
|
|
62
|
+
tags: [],
|
|
63
|
+
};
|
|
64
|
+
let di = 0;
|
|
65
|
+
const map = new Map();
|
|
66
|
+
let factors = new Map<string, string>();
|
|
67
|
+
let renames = new Map<string, string>();
|
|
68
|
+
let sums = new Map<string, string>();
|
|
69
|
+
let orders = new Map<string, string[]>();
|
|
70
|
+
let descCorpus: Map<string, Description>;
|
|
71
|
+
let grupCorpus: Map<string, Group>;
|
|
72
|
+
await loadGroups();
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
function valParse(val: string, code: string, dat: Dat, i: number) {
|
|
76
|
+
const f = factors.get(code) as string;
|
|
77
|
+
const fn = parseFloat(f.replace(/\*.*/, ''));
|
|
78
|
+
const fi = f.indexOf('*');
|
|
79
|
+
const fk = fi>=0? f.substring(fi+1) : null;
|
|
80
|
+
const a = (parseFloat(val) || 0) * fn * (fk? parseFloat(dat[fk][i] as string) || 0 : 1);
|
|
81
|
+
// a = parseFloat(a.toExponential((significantDigits(parseFloat(val))||1)-1));
|
|
82
|
+
return round(a);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
function nameSci(str: string) {
|
|
87
|
+
const bgn = str.lastIndexOf('(');
|
|
88
|
+
if (bgn<0) return '';
|
|
89
|
+
let end = str.lastIndexOf(')');
|
|
90
|
+
end = end<0? str.length : end;
|
|
91
|
+
const sci = str.substring(bgn+1, end).trim();
|
|
92
|
+
const spc = sci.search(/\s/g);
|
|
93
|
+
return spc>=0 && sci!=='small intestine'? sci : '';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function nameBas(str: string) {
|
|
97
|
+
const sci = nameSci(str);
|
|
98
|
+
if (!sci) return str.trim();
|
|
99
|
+
return str.replace(new RegExp(`\\(\\s*${sci}\\s*\\)`), '').trim();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function readAssetRow(row: Record<string, string>) {
|
|
103
|
+
const cod = row.code.trim();
|
|
104
|
+
const old = map.has(cod);
|
|
105
|
+
const nam = nameBas(row.name);
|
|
106
|
+
const sci = nameSci(row.name);
|
|
107
|
+
const i = old? map.get(cod) : map.set(cod, di) && di++;
|
|
108
|
+
dat.code[i] = cod;
|
|
109
|
+
dat.name[i] = old && dat.name[i].length > nam.length? dat.name[i] : nam;
|
|
110
|
+
dat.scie[i] = old && dat.scie[i].length > sci.length? dat.scie[i] : sci;
|
|
111
|
+
dat.lang[i] = (descCorpus.get(cod) || {desc: ''}).desc;
|
|
112
|
+
dat.grup[i] = (grupCorpus.get(cod[0]) as Group).group;
|
|
113
|
+
dat.regn[i] = parseInt(row.regn.trim(), 10);
|
|
114
|
+
dat.tags[i] = (grupCorpus.get(cod[0]) as Group).tags.trim();
|
|
115
|
+
dat.name[i] = (descCorpus.get(cod) || {name: dat.name[i]}).name;
|
|
116
|
+
dat.scie[i] = (descCorpus.get(cod) || {scie: dat.scie[i]}).scie;
|
|
117
|
+
for (const k in row) {
|
|
118
|
+
if (BASE.includes(k)) continue;
|
|
119
|
+
const val = row[k].trim().split('±');
|
|
120
|
+
const kt = renames.get(k) || k;
|
|
121
|
+
if (!dat[kt]) { dat[kt] = []; dat[kt+'_e'] = []; }
|
|
122
|
+
dat[kt][i] = valParse(val[0]||'0', k, dat, i);
|
|
123
|
+
dat[kt+'_e'][i] = valParse(val[1]||'0', k, dat, i);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function readAsset(pth: string) {
|
|
128
|
+
const data = await Deno.readTextFile(pth);
|
|
129
|
+
const records = csv.parse(data, {skipFirstRow: true, comment: "#"});
|
|
130
|
+
for (const record of records)
|
|
131
|
+
readAssetRow(record);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function nullToZero(d: Dat) {
|
|
135
|
+
for (const k of Object.keys(d)) {
|
|
136
|
+
for (let i=0; i<di; i++)
|
|
137
|
+
d[k][i] = d[k][i]!=null? d[k][i] : 0;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function sumColumns(d: Dat, i: number, ks: string[]) {
|
|
142
|
+
let a = 0;
|
|
143
|
+
for (const k of ks)
|
|
144
|
+
a += d[k][i] as number;
|
|
145
|
+
return a;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function sumAll(d: Dat) {
|
|
149
|
+
for (const [k, exp] of sums) {
|
|
150
|
+
d[k] = d[k] || [];
|
|
151
|
+
const sumk = exp.replace(/\s/g, '').split('+');
|
|
152
|
+
for (let i=0; i<di; i++)
|
|
153
|
+
d[k][i] = d[k][i] || round(sumColumns(d, i, sumk));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function orderAll(d: Dat) {
|
|
158
|
+
const a: Record<string, unknown[]> = {};
|
|
159
|
+
for (const k in d) {
|
|
160
|
+
if (k in a) continue;
|
|
161
|
+
for (const ak of orders.get(k) || []) {
|
|
162
|
+
a[ak] = d[ak];
|
|
163
|
+
const ake = ak + '_e';
|
|
164
|
+
if (ake in d) a[ake] = d[ake];
|
|
165
|
+
}
|
|
166
|
+
a[k] = d[k];
|
|
167
|
+
}
|
|
168
|
+
return a;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
async function writeIndexMain() {
|
|
173
|
+
await loadColumns();
|
|
174
|
+
grupCorpus = await loadGroups();
|
|
175
|
+
descCorpus = await loadDescriptions();
|
|
176
|
+
factors = await readCsv(path.join(import.meta.dirname || '', 'configs/factors.csv'), (acc, r) => acc.set(r.code, r.factor), new Map<string, string>());
|
|
177
|
+
renames = await readCsv(path.join(import.meta.dirname || '', 'configs/renames.csv'), (acc, r) => acc.set(r.code, r.actual), new Map<string, string>());
|
|
178
|
+
sums = await readCsv(path.join(import.meta.dirname || '', 'configs/sums.csv'), (acc, r) => acc.set(r.code, r.expression), new Map<string, string>());
|
|
179
|
+
orders = await readCsv(path.join(import.meta.dirname || '', 'configs/orders.csv'), (acc, r) => {
|
|
180
|
+
const arr = acc.get(r.before) || [];
|
|
181
|
+
acc.set(r.before, arr);
|
|
182
|
+
arr.push(r.code);
|
|
183
|
+
}, new Map<string, string[]>());
|
|
184
|
+
const assetsDir = path.join(import.meta.dirname || '', 'assets');
|
|
185
|
+
const assetsFiles = Array.from(Deno.readDirSync(assetsDir)).sort((a, b) => a.name.localeCompare(b.name));
|
|
186
|
+
for (const file of assetsFiles) {
|
|
187
|
+
if (!file.name.endsWith('.csv')) continue;
|
|
188
|
+
console.log(`Reading asset file: ${file.name}`);
|
|
189
|
+
await readAsset(path.join(import.meta.dirname || '', 'assets', file.name));
|
|
190
|
+
}
|
|
191
|
+
nullToZero(dat);
|
|
192
|
+
sumAll(dat);
|
|
193
|
+
dat = orderAll(dat) as Dat;
|
|
194
|
+
const ks = Object.keys(dat);
|
|
195
|
+
// let a = ks.map(k => `"${columns(k.replace(/_e$/, ''))[0].name}; ${k}"`).join() + '\n';
|
|
196
|
+
let a = ks.join() + '\n';
|
|
197
|
+
for (let i=0; i<di; i++) {
|
|
198
|
+
for (const k of ks) {
|
|
199
|
+
const v = dat[k][i];
|
|
200
|
+
a += JSON.stringify(v==null? 0:v) + ',';
|
|
201
|
+
}
|
|
202
|
+
a = a.substring(0, a.length-1) + '\n';
|
|
203
|
+
}
|
|
204
|
+
await Deno.writeTextFile(path.join(import.meta.dirname || '', 'index.csv'), a);
|
|
205
|
+
}
|
|
206
|
+
await writeIndexMain();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
export async function build() {
|
|
211
|
+
await writeIndex();
|
|
212
|
+
}
|