@robosystems/report-components 0.1.3 → 0.2.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/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js +1 -1
- package/dist/chunk-POSLHOTN.js +564 -0
- package/dist/chunk-POSLHOTN.js.map +1 -0
- package/dist/{index-DDFpPfUd.d.ts → index-D6FzPTm5.d.ts} +77 -13
- package/dist/index.d.ts +27 -3
- package/dist/index.js +185 -50
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-JTTICHPF.js +0 -273
- package/dist/chunk-JTTICHPF.js.map +0 -1
package/dist/adapters/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { b as CypherAdapterConfig, R as ReportAdapter, i as cypherAdapter,
|
|
1
|
+
export { b as CypherAdapterConfig, R as ReportAdapter, g as SecQuery, h as SecReportShell, i as SecSection, l as cypherAdapter, m as fetchSecReportShell, n as fetchSecSection, o as jsonldFileAdapter, p as mergeSecSections, q as parseJsonld, r as parseStore, s as parseStructureDefinition } from '../index-D6FzPTm5.js';
|
|
2
2
|
import 'n3';
|
package/dist/adapters/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { cypherAdapter, jsonldFileAdapter, parseJsonld, parseStore } from '../chunk-
|
|
1
|
+
export { cypherAdapter, fetchSecReportShell, fetchSecSection, jsonldFileAdapter, mergeSecSections, parseJsonld, parseStore, parseStructureDefinition } from '../chunk-POSLHOTN.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
import { DataFactory, Store, Parser } from 'n3';
|
|
2
|
+
import jsonld from 'jsonld';
|
|
3
|
+
|
|
4
|
+
// src/constants.ts
|
|
5
|
+
var NS = {
|
|
6
|
+
rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
|
|
7
|
+
rs: "https://robosystems.ai/vocab/",
|
|
8
|
+
rsgaap: "https://robosystems.ai/taxonomy/rs-gaap/v1/",
|
|
9
|
+
skos: "http://www.w3.org/2004/02/skos/core#",
|
|
10
|
+
xlink: "http://www.w3.org/1999/xlink#",
|
|
11
|
+
xbrli: "http://www.xbrl.org/2003/instance#",
|
|
12
|
+
link: "http://www.xbrl.org/2003/linkbase#",
|
|
13
|
+
iso4217: "http://www.xbrl.org/2003/iso4217#"
|
|
14
|
+
};
|
|
15
|
+
var IRI = {
|
|
16
|
+
type: NS.rdf + "type",
|
|
17
|
+
// rs: classes
|
|
18
|
+
Report: NS.rs + "Report",
|
|
19
|
+
Fact: NS.rs + "Fact",
|
|
20
|
+
InformationBlock: NS.rs + "InformationBlock",
|
|
21
|
+
Structure: NS.rs + "Structure",
|
|
22
|
+
Association: NS.rs + "Association",
|
|
23
|
+
Element: NS.rs + "Element",
|
|
24
|
+
Period: NS.rs + "Period",
|
|
25
|
+
Unit: NS.rs + "Unit",
|
|
26
|
+
Entity: NS.rs + "Entity",
|
|
27
|
+
// rs: predicates
|
|
28
|
+
element: NS.rs + "element",
|
|
29
|
+
period: NS.rs + "period",
|
|
30
|
+
unit: NS.rs + "unit",
|
|
31
|
+
entity: NS.rs + "entity",
|
|
32
|
+
factSet: NS.rs + "factSet",
|
|
33
|
+
numericValue: NS.rs + "numericValue",
|
|
34
|
+
decimals: NS.rs + "decimals",
|
|
35
|
+
blockType: NS.rs + "blockType",
|
|
36
|
+
associationType: NS.rs + "associationType",
|
|
37
|
+
hasAssociation: NS.rs + "hasAssociation",
|
|
38
|
+
roleUri: NS.rs + "roleUri",
|
|
39
|
+
structureName: NS.rs + "structureName",
|
|
40
|
+
abstract: NS.rs + "abstract",
|
|
41
|
+
monetary: NS.rs + "monetary",
|
|
42
|
+
legalName: NS.rs + "legalName",
|
|
43
|
+
country: NS.rs + "country",
|
|
44
|
+
// skos:
|
|
45
|
+
prefLabel: NS.skos + "prefLabel",
|
|
46
|
+
// xlink:
|
|
47
|
+
from: NS.xlink + "from",
|
|
48
|
+
to: NS.xlink + "to",
|
|
49
|
+
role: NS.xlink + "role",
|
|
50
|
+
// xbrli:
|
|
51
|
+
instant: NS.xbrli + "instant",
|
|
52
|
+
startDate: NS.xbrli + "startDate",
|
|
53
|
+
endDate: NS.xbrli + "endDate",
|
|
54
|
+
periodType: NS.xbrli + "periodType",
|
|
55
|
+
balance: NS.xbrli + "balance",
|
|
56
|
+
measure: NS.xbrli + "measure",
|
|
57
|
+
// link:
|
|
58
|
+
order: NS.link + "order",
|
|
59
|
+
weight: NS.link + "weight"
|
|
60
|
+
};
|
|
61
|
+
var PREFIXES = [
|
|
62
|
+
["rs-gaap", NS.rsgaap],
|
|
63
|
+
["disclosures", "https://robosystems.ai/taxonomy/rs-gaap/disclosures/v1/"],
|
|
64
|
+
["us-gaap", "http://fasb.org/us-gaap/"],
|
|
65
|
+
["dei", "http://xbrl.sec.gov/dei/"],
|
|
66
|
+
["rs", NS.rs],
|
|
67
|
+
["skos", NS.skos],
|
|
68
|
+
["xbrli", NS.xbrli],
|
|
69
|
+
["xlink", NS.xlink],
|
|
70
|
+
["link", NS.link],
|
|
71
|
+
["iso4217", NS.iso4217]
|
|
72
|
+
];
|
|
73
|
+
function qname(iri) {
|
|
74
|
+
for (const [prefix, ns] of PREFIXES) {
|
|
75
|
+
if (iri.startsWith(ns)) {
|
|
76
|
+
return `${prefix}:${iri.slice(ns.length)}`;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const slash = iri.lastIndexOf("/");
|
|
80
|
+
const hash = iri.lastIndexOf("#");
|
|
81
|
+
return iri.slice(Math.max(slash, hash) + 1);
|
|
82
|
+
}
|
|
83
|
+
function humanize(iri) {
|
|
84
|
+
const local = qname(iri).split(":").pop() ?? iri;
|
|
85
|
+
return local.replace(/(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g, " ");
|
|
86
|
+
}
|
|
87
|
+
function isExternalFactUrl(value) {
|
|
88
|
+
return !!value && /^https?:\/\/\S+\/fact_[0-9a-f]+\.(html|txt)$/i.test(value);
|
|
89
|
+
}
|
|
90
|
+
var BLOCK_ORDER = {
|
|
91
|
+
balance_sheet: 0,
|
|
92
|
+
income_statement: 1,
|
|
93
|
+
cash_flow_statement: 2,
|
|
94
|
+
equity_statement: 3
|
|
95
|
+
};
|
|
96
|
+
var BLOCK_TITLES = {
|
|
97
|
+
balance_sheet: "Balance Sheet",
|
|
98
|
+
income_statement: "Income Statement",
|
|
99
|
+
cash_flow_statement: "Cash Flow Statement",
|
|
100
|
+
equity_statement: "Statement of Changes in Equity"
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// src/adapters/sec.ts
|
|
104
|
+
var ENTITY_META_Q = `
|
|
105
|
+
MATCH (ent:Entity)-[:ENTITY_HAS_REPORT]->(r:Report {identifier: $rid})
|
|
106
|
+
RETURN ent.identifier AS entity_id, ent.name AS entity_name,
|
|
107
|
+
ent.legal_name AS legal_name, ent.cik AS cik, ent.ticker AS ticker,
|
|
108
|
+
r.form AS form, r.report_date AS report_date`;
|
|
109
|
+
var SECTIONS_Q = `
|
|
110
|
+
MATCH (r:Report {identifier: $rid})-[:REPORT_HAS_FACT]->(f:Fact {has_dimensions: false})<-[:FACT_SET_CONTAINS_FACT]-(fs:FactSet)<-[:STRUCTURE_HAS_FACT_SET]-(s:Structure)
|
|
111
|
+
RETURN s.identifier AS sid, s.canonical_type AS canonical_type,
|
|
112
|
+
s.definition AS definition, s.number AS number,
|
|
113
|
+
collect(DISTINCT fs.identifier) AS factsets
|
|
114
|
+
ORDER BY number`;
|
|
115
|
+
var FACTS_Q = `
|
|
116
|
+
MATCH (fs:FactSet {identifier: $fsid})-[:FACT_SET_CONTAINS_FACT]->(f:Fact {has_dimensions: false})-[:FACT_HAS_ELEMENT]->(e:Element),
|
|
117
|
+
(f)-[:FACT_HAS_PERIOD]->(p:Period)
|
|
118
|
+
WHERE f.value IS NOT NULL
|
|
119
|
+
RETURN f.identifier AS fid, e.qname AS qname, e.name AS ename, e.balance AS balance,
|
|
120
|
+
e.period_type AS e_period_type, e.is_abstract AS is_abstract, e.is_numeric AS is_numeric,
|
|
121
|
+
f.numeric_value AS numeric_value, f.value AS raw_value, f.decimals AS decimals,
|
|
122
|
+
p.identifier AS pid, p.period_type AS period_type,
|
|
123
|
+
p.start_date AS start_date, p.end_date AS end_date
|
|
124
|
+
LIMIT 2000`;
|
|
125
|
+
var UNITS_Q = `
|
|
126
|
+
MATCH (fs:FactSet {identifier: $fsid})-[:FACT_SET_CONTAINS_FACT]->(f:Fact {has_dimensions: false})-[:FACT_HAS_UNIT]->(u:Unit)
|
|
127
|
+
WHERE f.value IS NOT NULL
|
|
128
|
+
RETURN f.identifier AS fid, u.measure AS unit
|
|
129
|
+
LIMIT 2000`;
|
|
130
|
+
var ASSOC_Q = `
|
|
131
|
+
MATCH (s:Structure {identifier: $sid})-[:STRUCTURE_HAS_ASSOCIATION]->(a:Association),
|
|
132
|
+
(a)-[:ASSOCIATION_HAS_FROM_ELEMENT]->(pe:Element),
|
|
133
|
+
(a)-[:ASSOCIATION_HAS_TO_ELEMENT]->(ce:Element)
|
|
134
|
+
RETURN a.association_type AS association_type, a.order_value AS order_value,
|
|
135
|
+
a.weight AS weight, pe.qname AS parent, ce.qname AS child`;
|
|
136
|
+
function str(row, key) {
|
|
137
|
+
const v = row[key];
|
|
138
|
+
return typeof v === "string" && v !== "" ? v : v == null ? null : String(v);
|
|
139
|
+
}
|
|
140
|
+
function num(row, key) {
|
|
141
|
+
const v = row[key];
|
|
142
|
+
if (v === null || v === void 0 || v === "") return null;
|
|
143
|
+
const n = typeof v === "number" ? v : Number(v);
|
|
144
|
+
return Number.isNaN(n) ? null : n;
|
|
145
|
+
}
|
|
146
|
+
function bool(row, key) {
|
|
147
|
+
const v = row[key];
|
|
148
|
+
return v === true || v === "true";
|
|
149
|
+
}
|
|
150
|
+
function periodType(raw) {
|
|
151
|
+
return raw === "instant" || raw === "duration" ? raw : null;
|
|
152
|
+
}
|
|
153
|
+
var DENSE_PERIOD_FRACTION = 0.2;
|
|
154
|
+
function filterToDominantPeriods(facts, periods) {
|
|
155
|
+
const countByEnd = /* @__PURE__ */ new Map();
|
|
156
|
+
for (const f of facts) {
|
|
157
|
+
const end = periods[f.period]?.end;
|
|
158
|
+
if (end) countByEnd.set(end, (countByEnd.get(end) ?? 0) + 1);
|
|
159
|
+
}
|
|
160
|
+
if (countByEnd.size <= 1) return facts;
|
|
161
|
+
const max = Math.max(...countByEnd.values());
|
|
162
|
+
const threshold = max * DENSE_PERIOD_FRACTION;
|
|
163
|
+
const keep = new Set(
|
|
164
|
+
[...countByEnd].filter(([, count]) => count >= threshold).map(([end]) => end)
|
|
165
|
+
);
|
|
166
|
+
return facts.filter((f) => {
|
|
167
|
+
const end = periods[f.period]?.end;
|
|
168
|
+
return end !== void 0 && keep.has(end);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
var CORE_STATEMENT_TYPES = /* @__PURE__ */ new Set([
|
|
172
|
+
"balance_sheet",
|
|
173
|
+
"income_statement",
|
|
174
|
+
"cash_flow_statement",
|
|
175
|
+
"equity_statement",
|
|
176
|
+
"comprehensive_income"
|
|
177
|
+
]);
|
|
178
|
+
function parseStructureDefinition(definition, canonicalType) {
|
|
179
|
+
const raw = (definition ?? "").trim();
|
|
180
|
+
const parts = raw.split(" - ");
|
|
181
|
+
let type = "";
|
|
182
|
+
let title = raw;
|
|
183
|
+
if (parts.length >= 3) {
|
|
184
|
+
type = parts[1].trim();
|
|
185
|
+
title = parts.slice(2).join(" - ").trim();
|
|
186
|
+
} else if (parts.length === 2) {
|
|
187
|
+
title = parts[1].trim();
|
|
188
|
+
}
|
|
189
|
+
let kind = "Other";
|
|
190
|
+
if (/cover/i.test(title)) kind = "Cover";
|
|
191
|
+
else if (type === "Statement") kind = "Statement";
|
|
192
|
+
else if (type === "Disclosure") kind = "Disclosure";
|
|
193
|
+
else if (type === "Document") kind = "Document";
|
|
194
|
+
if (canonicalType && CORE_STATEMENT_TYPES.has(canonicalType)) kind = "Statement";
|
|
195
|
+
return { title: title || raw || canonicalType || "Section", kind };
|
|
196
|
+
}
|
|
197
|
+
function mapEntity(row) {
|
|
198
|
+
if (!row) return null;
|
|
199
|
+
const id = str(row, "entity_id");
|
|
200
|
+
if (!id) return null;
|
|
201
|
+
return {
|
|
202
|
+
id,
|
|
203
|
+
name: str(row, "entity_name") ?? str(row, "legal_name") ?? "Entity",
|
|
204
|
+
legalName: str(row, "legal_name"),
|
|
205
|
+
country: null
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
async function fetchSecReportShell(query, reportId) {
|
|
209
|
+
const [entityRows, sectionRows] = await Promise.all([
|
|
210
|
+
query(ENTITY_META_Q, { rid: reportId }),
|
|
211
|
+
query(SECTIONS_Q, { rid: reportId })
|
|
212
|
+
]);
|
|
213
|
+
const sections = sectionRows.map((row, order) => {
|
|
214
|
+
const { title, kind } = parseStructureDefinition(
|
|
215
|
+
str(row, "definition"),
|
|
216
|
+
str(row, "canonical_type")
|
|
217
|
+
);
|
|
218
|
+
const factsets = Array.isArray(row.factsets) ? row.factsets.filter((v) => typeof v === "string") : [];
|
|
219
|
+
return {
|
|
220
|
+
id: str(row, "sid") ?? "",
|
|
221
|
+
title,
|
|
222
|
+
kind,
|
|
223
|
+
canonicalType: str(row, "canonical_type"),
|
|
224
|
+
order,
|
|
225
|
+
factsetIds: factsets
|
|
226
|
+
};
|
|
227
|
+
}).filter((s) => s.id && s.factsetIds.length > 0);
|
|
228
|
+
return { reportId, entity: mapEntity(entityRows[0]), sections };
|
|
229
|
+
}
|
|
230
|
+
function accumulateElement(elements, row) {
|
|
231
|
+
const q = str(row, "qname");
|
|
232
|
+
if (!q || elements[q]) return;
|
|
233
|
+
const balance = str(row, "balance");
|
|
234
|
+
elements[q] = {
|
|
235
|
+
id: q,
|
|
236
|
+
qname: q,
|
|
237
|
+
label: str(row, "ename") ? humanize(str(row, "ename")) : humanize(q),
|
|
238
|
+
balance: balance === "debit" || balance === "credit" ? balance : null,
|
|
239
|
+
periodType: periodType(str(row, "e_period_type")),
|
|
240
|
+
abstract: bool(row, "is_abstract"),
|
|
241
|
+
monetary: bool(row, "is_numeric")
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
function accumulatePeriod(periods, row) {
|
|
245
|
+
const id = str(row, "pid");
|
|
246
|
+
if (!id || periods[id]) return;
|
|
247
|
+
const type = periodType(str(row, "period_type")) ?? "duration";
|
|
248
|
+
const startDate = str(row, "start_date");
|
|
249
|
+
const endDate = str(row, "end_date");
|
|
250
|
+
periods[id] = {
|
|
251
|
+
id,
|
|
252
|
+
type,
|
|
253
|
+
instant: type === "instant" ? endDate : null,
|
|
254
|
+
startDate,
|
|
255
|
+
endDate,
|
|
256
|
+
end: endDate ?? ""
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
async function fetchSecSection(query, shell, section) {
|
|
260
|
+
const [factRowGroups, unitRowGroups, assocRows] = await Promise.all([
|
|
261
|
+
Promise.all(section.factsetIds.map((fsid) => query(FACTS_Q, { fsid }))),
|
|
262
|
+
Promise.all(section.factsetIds.map((fsid) => query(UNITS_Q, { fsid }))),
|
|
263
|
+
query(ASSOC_Q, { sid: section.id })
|
|
264
|
+
]);
|
|
265
|
+
const unitByFid = /* @__PURE__ */ new Map();
|
|
266
|
+
for (const row of unitRowGroups.flat()) {
|
|
267
|
+
const fid = str(row, "fid");
|
|
268
|
+
const measure = str(row, "unit");
|
|
269
|
+
if (fid && measure) unitByFid.set(fid, measure);
|
|
270
|
+
}
|
|
271
|
+
const elements = {};
|
|
272
|
+
const periods = {};
|
|
273
|
+
const units = {};
|
|
274
|
+
const facts = [];
|
|
275
|
+
const seenFacts = /* @__PURE__ */ new Set();
|
|
276
|
+
for (const row of factRowGroups.flat()) {
|
|
277
|
+
const fid = str(row, "fid");
|
|
278
|
+
const element = str(row, "qname");
|
|
279
|
+
const period = str(row, "pid");
|
|
280
|
+
if (!fid || !element || !period || seenFacts.has(fid)) continue;
|
|
281
|
+
seenFacts.add(fid);
|
|
282
|
+
accumulateElement(elements, row);
|
|
283
|
+
accumulatePeriod(periods, row);
|
|
284
|
+
const measure = unitByFid.get(fid) ?? null;
|
|
285
|
+
if (measure && !units[measure]) {
|
|
286
|
+
const compact = qname(measure);
|
|
287
|
+
units[measure] = {
|
|
288
|
+
id: measure,
|
|
289
|
+
measure: compact,
|
|
290
|
+
label: compact.includes(":") ? compact.split(":").pop() : compact
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
const value = num(row, "numeric_value");
|
|
294
|
+
facts.push({
|
|
295
|
+
id: fid,
|
|
296
|
+
element,
|
|
297
|
+
period,
|
|
298
|
+
unit: measure,
|
|
299
|
+
entity: shell.entity?.id ?? null,
|
|
300
|
+
factSet: section.id,
|
|
301
|
+
value,
|
|
302
|
+
decimals: str(row, "decimals"),
|
|
303
|
+
textValue: value === null ? str(row, "raw_value") : null
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
const calcAssociations = [];
|
|
307
|
+
const presAssociations = [];
|
|
308
|
+
for (const row of assocRows) {
|
|
309
|
+
const parent = str(row, "parent");
|
|
310
|
+
const child = str(row, "child");
|
|
311
|
+
if (!parent || !child) continue;
|
|
312
|
+
const order = num(row, "order_value") ?? 0;
|
|
313
|
+
const type = str(row, "association_type")?.toLowerCase();
|
|
314
|
+
if (type === "calculation") {
|
|
315
|
+
calcAssociations.push({
|
|
316
|
+
parent,
|
|
317
|
+
child,
|
|
318
|
+
weight: num(row, "weight") ?? 1,
|
|
319
|
+
order,
|
|
320
|
+
role: null,
|
|
321
|
+
structure: section.id
|
|
322
|
+
});
|
|
323
|
+
} else if (type === "presentation") {
|
|
324
|
+
presAssociations.push({ parent, child, order, role: null, structure: section.id });
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
const informationBlock = {
|
|
328
|
+
id: section.id,
|
|
329
|
+
blockType: section.canonicalType ?? "",
|
|
330
|
+
factSet: section.id,
|
|
331
|
+
label: section.title,
|
|
332
|
+
structureId: section.id
|
|
333
|
+
};
|
|
334
|
+
const structure = {
|
|
335
|
+
id: section.id,
|
|
336
|
+
blockType: section.canonicalType ?? "",
|
|
337
|
+
roleUri: null,
|
|
338
|
+
structureName: section.title,
|
|
339
|
+
order: section.order
|
|
340
|
+
};
|
|
341
|
+
return {
|
|
342
|
+
reportId: shell.reportId,
|
|
343
|
+
reportIri: null,
|
|
344
|
+
entity: shell.entity,
|
|
345
|
+
informationBlocks: [informationBlock],
|
|
346
|
+
structures: [structure],
|
|
347
|
+
facts: filterToDominantPeriods(facts, periods),
|
|
348
|
+
elements,
|
|
349
|
+
periods,
|
|
350
|
+
units,
|
|
351
|
+
calcAssociations,
|
|
352
|
+
presAssociations
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
function mergeSecSections(shell, sections) {
|
|
356
|
+
const elements = {};
|
|
357
|
+
const periods = {};
|
|
358
|
+
const units = {};
|
|
359
|
+
const informationBlocks = [];
|
|
360
|
+
const structures = [];
|
|
361
|
+
const facts = [];
|
|
362
|
+
const calcAssociations = [];
|
|
363
|
+
const presAssociations = [];
|
|
364
|
+
for (const part of sections) {
|
|
365
|
+
Object.assign(elements, part.elements);
|
|
366
|
+
Object.assign(periods, part.periods);
|
|
367
|
+
Object.assign(units, part.units);
|
|
368
|
+
informationBlocks.push(...part.informationBlocks);
|
|
369
|
+
structures.push(...part.structures);
|
|
370
|
+
facts.push(...part.facts);
|
|
371
|
+
calcAssociations.push(...part.calcAssociations);
|
|
372
|
+
presAssociations.push(...part.presAssociations);
|
|
373
|
+
}
|
|
374
|
+
return {
|
|
375
|
+
reportId: shell.reportId,
|
|
376
|
+
reportIri: null,
|
|
377
|
+
entity: shell.entity,
|
|
378
|
+
informationBlocks,
|
|
379
|
+
structures,
|
|
380
|
+
facts,
|
|
381
|
+
elements,
|
|
382
|
+
periods,
|
|
383
|
+
units,
|
|
384
|
+
calcAssociations,
|
|
385
|
+
presAssociations
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// src/adapters/cypher.ts
|
|
390
|
+
function cypherAdapter(config) {
|
|
391
|
+
return {
|
|
392
|
+
source: `sec:${config.reportId}`,
|
|
393
|
+
load: async () => {
|
|
394
|
+
const shell = await fetchSecReportShell(config.query, config.reportId);
|
|
395
|
+
const sections = await Promise.all(
|
|
396
|
+
shell.sections.map((section) => fetchSecSection(config.query, shell, section))
|
|
397
|
+
);
|
|
398
|
+
return mergeSecSections(shell, sections);
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
var { namedNode } = DataFactory;
|
|
403
|
+
function makeReaders(store) {
|
|
404
|
+
const objects = (s, p) => store.getObjects(namedNode(s), namedNode(p), null);
|
|
405
|
+
const firstValue = (s, p) => {
|
|
406
|
+
const os = objects(s, p);
|
|
407
|
+
return os.length ? os[0].value : null;
|
|
408
|
+
};
|
|
409
|
+
const subjectsOfType = (type) => store.getSubjects(namedNode(IRI.type), namedNode(type), null).map((t) => t.value);
|
|
410
|
+
return { objects, firstValue, subjectsOfType };
|
|
411
|
+
}
|
|
412
|
+
function toNumber(raw) {
|
|
413
|
+
if (raw === null || raw === "") return null;
|
|
414
|
+
const n = Number(raw);
|
|
415
|
+
return Number.isNaN(n) ? null : n;
|
|
416
|
+
}
|
|
417
|
+
function parseStore(store) {
|
|
418
|
+
const { objects, firstValue, subjectsOfType } = makeReaders(store);
|
|
419
|
+
const elements = {};
|
|
420
|
+
for (const id of subjectsOfType(IRI.Element)) {
|
|
421
|
+
const balance = firstValue(id, IRI.balance);
|
|
422
|
+
const periodType2 = firstValue(id, IRI.periodType);
|
|
423
|
+
elements[id] = {
|
|
424
|
+
id,
|
|
425
|
+
qname: qname(id),
|
|
426
|
+
label: firstValue(id, IRI.prefLabel) ?? humanize(id),
|
|
427
|
+
balance: balance === "debit" || balance === "credit" ? balance : null,
|
|
428
|
+
periodType: periodType2 === "instant" || periodType2 === "duration" ? periodType2 : null,
|
|
429
|
+
abstract: firstValue(id, IRI.abstract) === "true",
|
|
430
|
+
monetary: firstValue(id, IRI.monetary) === "true"
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
const periods = {};
|
|
434
|
+
for (const id of subjectsOfType(IRI.Period)) {
|
|
435
|
+
const declared = firstValue(id, IRI.periodType);
|
|
436
|
+
const instant = firstValue(id, IRI.instant);
|
|
437
|
+
const startDate = firstValue(id, IRI.startDate);
|
|
438
|
+
const endDate = firstValue(id, IRI.endDate);
|
|
439
|
+
const type = declared === "instant" ? "instant" : declared === "duration" ? "duration" : instant ? "instant" : "duration";
|
|
440
|
+
const end = (type === "instant" ? instant : endDate) ?? instant ?? endDate ?? "";
|
|
441
|
+
periods[id] = { id, type, instant, startDate, endDate, end };
|
|
442
|
+
}
|
|
443
|
+
const units = {};
|
|
444
|
+
for (const id of subjectsOfType(IRI.Unit)) {
|
|
445
|
+
const measureTerm = objects(id, IRI.measure)[0];
|
|
446
|
+
const measure = measureTerm ? qname(measureTerm.value) : "unknown";
|
|
447
|
+
units[id] = {
|
|
448
|
+
id,
|
|
449
|
+
measure,
|
|
450
|
+
label: measure.includes(":") ? measure.split(":").pop() : measure
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
let entity = null;
|
|
454
|
+
const entityIds = subjectsOfType(IRI.Entity);
|
|
455
|
+
if (entityIds.length) {
|
|
456
|
+
const id = entityIds[0];
|
|
457
|
+
entity = {
|
|
458
|
+
id,
|
|
459
|
+
name: firstValue(id, IRI.prefLabel) ?? firstValue(id, IRI.legalName) ?? "Entity",
|
|
460
|
+
legalName: firstValue(id, IRI.legalName),
|
|
461
|
+
country: firstValue(id, IRI.country)
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
const facts = [];
|
|
465
|
+
for (const id of subjectsOfType(IRI.Fact)) {
|
|
466
|
+
facts.push({
|
|
467
|
+
id,
|
|
468
|
+
element: firstValue(id, IRI.element) ?? "",
|
|
469
|
+
period: firstValue(id, IRI.period) ?? "",
|
|
470
|
+
unit: firstValue(id, IRI.unit),
|
|
471
|
+
entity: firstValue(id, IRI.entity),
|
|
472
|
+
factSet: firstValue(id, IRI.factSet),
|
|
473
|
+
value: toNumber(firstValue(id, IRI.numericValue)),
|
|
474
|
+
decimals: firstValue(id, IRI.decimals)
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
const informationBlocks = [];
|
|
478
|
+
for (const id of subjectsOfType(IRI.InformationBlock)) {
|
|
479
|
+
informationBlocks.push({
|
|
480
|
+
id,
|
|
481
|
+
blockType: firstValue(id, IRI.blockType) ?? "",
|
|
482
|
+
factSet: firstValue(id, IRI.factSet),
|
|
483
|
+
label: firstValue(id, IRI.prefLabel)
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
const structures = [];
|
|
487
|
+
const assocStructure = /* @__PURE__ */ new Map();
|
|
488
|
+
for (const id of subjectsOfType(IRI.Structure)) {
|
|
489
|
+
structures.push({
|
|
490
|
+
id,
|
|
491
|
+
blockType: firstValue(id, IRI.blockType) ?? "",
|
|
492
|
+
roleUri: firstValue(id, IRI.roleUri),
|
|
493
|
+
structureName: firstValue(id, IRI.structureName)
|
|
494
|
+
});
|
|
495
|
+
for (const assoc of objects(id, IRI.hasAssociation)) {
|
|
496
|
+
assocStructure.set(assoc.value, id);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
const calcAssociations = [];
|
|
500
|
+
const presAssociations = [];
|
|
501
|
+
for (const id of subjectsOfType(IRI.Association)) {
|
|
502
|
+
const parent = firstValue(id, IRI.from);
|
|
503
|
+
const child = firstValue(id, IRI.to);
|
|
504
|
+
if (!parent || !child) continue;
|
|
505
|
+
const type = firstValue(id, IRI.associationType);
|
|
506
|
+
const order = toNumber(firstValue(id, IRI.order)) ?? 0;
|
|
507
|
+
const role = firstValue(id, IRI.role);
|
|
508
|
+
const structure = assocStructure.get(id) ?? null;
|
|
509
|
+
if (type === "calculation") {
|
|
510
|
+
calcAssociations.push({
|
|
511
|
+
parent,
|
|
512
|
+
child,
|
|
513
|
+
weight: toNumber(firstValue(id, IRI.weight)) ?? 1,
|
|
514
|
+
order,
|
|
515
|
+
role,
|
|
516
|
+
structure
|
|
517
|
+
});
|
|
518
|
+
} else if (type === "presentation") {
|
|
519
|
+
presAssociations.push({ parent, child, order, role, structure });
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
let reportIri = null;
|
|
523
|
+
for (const graph of store.getGraphs(null, null, null)) {
|
|
524
|
+
const hash = graph.value.indexOf("#");
|
|
525
|
+
if (hash > 0) {
|
|
526
|
+
reportIri = graph.value.slice(0, hash);
|
|
527
|
+
break;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
if (!reportIri) {
|
|
531
|
+
const reports = subjectsOfType(IRI.Report);
|
|
532
|
+
reportIri = reports.length ? reports[0] : null;
|
|
533
|
+
}
|
|
534
|
+
const reportId = reportIri ? reportIri.split("/").pop() ?? null : null;
|
|
535
|
+
return {
|
|
536
|
+
reportId,
|
|
537
|
+
reportIri,
|
|
538
|
+
entity,
|
|
539
|
+
informationBlocks,
|
|
540
|
+
structures,
|
|
541
|
+
facts,
|
|
542
|
+
elements,
|
|
543
|
+
periods,
|
|
544
|
+
units,
|
|
545
|
+
calcAssociations,
|
|
546
|
+
presAssociations
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
async function parseJsonld(doc) {
|
|
550
|
+
const json = typeof doc === "string" ? JSON.parse(doc) : doc;
|
|
551
|
+
const nquads = await jsonld.toRDF(json, { format: "application/n-quads" });
|
|
552
|
+
const store = new Store(new Parser({ format: "application/n-quads" }).parse(nquads));
|
|
553
|
+
return parseStore(store);
|
|
554
|
+
}
|
|
555
|
+
function jsonldFileAdapter(doc, source = "holon.jsonld") {
|
|
556
|
+
return {
|
|
557
|
+
source,
|
|
558
|
+
load: () => parseJsonld(doc)
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
export { BLOCK_ORDER, BLOCK_TITLES, NS, cypherAdapter, fetchSecReportShell, fetchSecSection, humanize, isExternalFactUrl, jsonldFileAdapter, mergeSecSections, parseJsonld, parseStore, parseStructureDefinition, qname };
|
|
563
|
+
//# sourceMappingURL=chunk-POSLHOTN.js.map
|
|
564
|
+
//# sourceMappingURL=chunk-POSLHOTN.js.map
|