PageSourceSearch

https://agricheck.me/js/model.js

js agricheck.me collected 2026-09-28 07:08:49 UTC 3,517 bytes, 120 lines download raw bytes

1const ENDPOINT = 'https://cached.lindas.admin.ch/query';
2
3function buildQuery() {
4  return `
5    PREFIX : <https://agriculture.ld.admin.ch/inspection/>
6    PREFIX schema: <http://schema.org/>
7    PREFIX dct: <http://purl.org/dc/terms/>
8    SELECT DISTINCT ?item ?class ?name ?description ?parent ?identifier
9    FROM <https://lindas.admin.ch/foag/inspections>
10    WHERE
11    {
12      :42EA1020A8742ACABFB1B7A426619C42 schema:hasPart+ / :includesInspectionPoints* ?item .
13      ?item a ?class .
14      VALUES ?class { dct:Collection :InspectionPoint }
15      OPTIONAL {
16        { ?item schema:name ?name }
17        UNION
18        { ?item schema:description ?description }
19      }
20      OPTIONAL {
21        ?item ?link ?parent .
22        VALUES ?link { schema:isPartOf :belongsToGroup }
23      }
24      OPTIONAL { ?item schema:identifier ?identifier }
25    }
26    ORDER BY ?identifier ?item
27    `;
28}
29
30export async function fetchBindings() {
31  const res  = await fetch(ENDPOINT, {
32    method:  'POST',
33    headers: {
34      'Content-Type': 'application/sparql-query',
35      'Accept':       'application/sparql-results+json'
36    },
37    body: buildQuery()
38  });
39  if (!res.ok) {
40    throw new Error(`SPARQL request failed: ${res.status} - ${res.statusText}`);
41  }
42  return res.json();
43}
44
45export function buildNodeMap(bindingsJson) {
46  const rows = bindingsJson.results.bindings;
47  const v = (row, key) => row[key]?.value;
48  const l = (row, key) => row[key]?.['xml:lang'];
49
50  const map = new Map();
51  for (const row of rows) {
52    const uri = v(row, 'item');
53    if (!map.has(uri)) {
54      map.set(uri, {
55        uri,
56        type: v(row, 'class').includes('Collection') ? 'Collection' : 'InspectionPoint',
57        label:      {},
58        comment:    {},
59        identifier: v(row, 'identifier') || null,
60        subGroups:        [],
61        inspectionPoints: [],
62        superGroup:  null,
63        parentGroup: null
64      });
65    }
66    const node = map.get(uri);
67    if (v(row, 'name'))        node.label[l(row, 'name')] = v(row, 'name');
68    if (v(row, 'description')) node.comment[l(row, 'description')] = v(row, 'description');
69  }
70
71  const processedLinks = new Set();
72  for (const row of rows) {
73    const uri    = v(row, 'item');
74    const parent = v(row, 'parent');
75    if (!parent) continue;
76
77    const linkId = `${uri}->${parent}`;
78    if (processedLinks.has(linkId)) continue;
79    processedLinks.add(linkId);
80
81    const node       = map.get(uri);
82    const parentNode = map.get(parent);
83    if (!node || !parentNode) continue;
84
85    if (node.type === 'Collection') {
86      node.superGroup = parent;
87      if (!parentNode.subGroups.includes(uri)) parentNode.subGroups.push(uri);
88    } else {
89      node.parentGroup = parent;
90      if (!parentNode.inspectionPoints.includes(uri)) parentNode.inspectionPoints.push(uri);
91    }
92  }
93  return map;
94}
95
96export function getDescendantIPs(collectionURI, nodeMap, visited = new Set()) {
97  if (visited.has(collectionURI)) return [];
98  visited.add(collectionURI);
99
100  const node = nodeMap.get(collectionURI);
101  if (!node || node.type !== 'Collection') return [];
102
103  let ips = [...node.inspectionPoints];
104  for (const sub of node.subGroups) {
105    ips = ips.concat(getDescendantIPs(sub, nodeMap, visited));
106  }
107  return ips;
108}
109
110export function getBreadcrumbs(uri, nodeMap) {
111  const trail = [];
112  let cur = uri;
113  while (cur) {
114    const n = nodeMap.get(cur);
115    if (!n) break;
116    trail.unshift(n.label || cur.split('/').pop());
117    cur = n.superGroup || n.parentGroup;
118  }
119  return trail;
120}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.