From 3966af15107a43be4e19c67e0f57ac88ceb6e5e7 Mon Sep 17 00:00:00 2001 From: nicola leonardi Date: Sat, 20 Jun 2026 18:37:57 +0200 Subject: [PATCH] costruzione grafo --- scripts/costruzione_grafo/ax_tree_to_graph.py | 690 +++++++++ scripts/costruzione_grafo/draw_graph_pyvis.py | 24 + .../KnowledgeGraph_manager.py | 179 +++ .../__pycache__/graph_manager.cpython-311.pyc | Bin 0 -> 45347 bytes .../__pycache__/neo4j_manager.cpython-311.pyc | Bin 0 -> 13013 bytes .../dependences/graph/graph_manager.py | 1216 ++++++++++++++++ .../dependences/graph/neo4j_manager.py | 292 ++++ .../utils/__pycache__/utils.cpython-311.pyc | Bin 0 -> 8356 bytes .../dependences/utils/utils.py | 165 +++ .../neo4j_management/env.env | 30 + .../outputs/my_kg_server_log.log | 322 +++++ .../persistence/accessibility_graph.json | 1 + .../target_size_extractor_script.py | 7 +- scripts/test_utenti_03_2026/rebuttal.ipynb | 1232 +++++++++++++++++ 14 files changed, 4155 insertions(+), 3 deletions(-) create mode 100644 scripts/costruzione_grafo/ax_tree_to_graph.py create mode 100644 scripts/costruzione_grafo/draw_graph_pyvis.py create mode 100644 scripts/costruzione_grafo/neo4j_management/KnowledgeGraph_manager.py create mode 100644 scripts/costruzione_grafo/neo4j_management/dependences/graph/__pycache__/graph_manager.cpython-311.pyc create mode 100644 scripts/costruzione_grafo/neo4j_management/dependences/graph/__pycache__/neo4j_manager.cpython-311.pyc create mode 100644 scripts/costruzione_grafo/neo4j_management/dependences/graph/graph_manager.py create mode 100644 scripts/costruzione_grafo/neo4j_management/dependences/graph/neo4j_manager.py create mode 100644 scripts/costruzione_grafo/neo4j_management/dependences/utils/__pycache__/utils.cpython-311.pyc create mode 100644 scripts/costruzione_grafo/neo4j_management/dependences/utils/utils.py create mode 100644 scripts/costruzione_grafo/neo4j_management/env.env create mode 100644 scripts/costruzione_grafo/neo4j_management/outputs/my_kg_server_log.log create mode 100644 scripts/costruzione_grafo/neo4j_management/persistence/accessibility_graph.json create mode 100644 scripts/test_utenti_03_2026/rebuttal.ipynb diff --git a/scripts/costruzione_grafo/ax_tree_to_graph.py b/scripts/costruzione_grafo/ax_tree_to_graph.py new file mode 100644 index 0000000..7289978 --- /dev/null +++ b/scripts/costruzione_grafo/ax_tree_to_graph.py @@ -0,0 +1,690 @@ +""" +Architettura dello script +Il pipeline ha 6 fasi ben separate. +Fase 1 — Playwright snapshot (_flatten_playwright_snapshot): estrae l'albero annidato restituito da page.accessibility.snapshot(interesting_only=False) e lo appiattisce in un dizionario. Ogni nodo porta role, name, stato ARIA (checked, expanded, disabled, required, ecc.) e un riferimento al parent per ricostruire la struttura. +Fase 2 — CDP via cdp_use (extract_and_build): lancia Chromium con --remote-debugging-port=9222, poi connette CDPClient al WebSocket del target page. Chiama Accessibility.enable → Accessibility.getFullAXTree → Accessibility.disable. Questo restituisce tutti i nodi AX inclusi quelli ignored, con parentId, childIds, backendDOMNodeId e le properties ARIA estese. +Fase 3 — Build grafo (build_graph): tre pass distinti. Il primo aggiunge tutti i nodi CDP con attributi puliti (_node_to_attrs). Il secondo aggiunge gli archi strutturali parent→child. Il terzo aggiunge archi ARIA relazionali (labelledby, describedby, controls, owns, flowto, activedescendant) risolti tramite backendDOMNodeId. +Fase 4 — Merge (merge_playwright_data): riconcilia i nodi Playwright con i nodi CDP per (role, name) e arricchisce gli attributi del grafo — utile perché Playwright espone alcuni stati che CDP non restituisce direttamente. +Fase 5 — Export: supporta sia .graphml (portabile, compatibile con Gephi/yEd) che .json node-link (compatibile con D3.js e altri tool di visualizzazione). +""" + +"""Riferimenti utili +browser_use: +site-packages\\browser_use\dom\\views.py #per aria-attributes + +""" + +""" +environmnet to use: accessibility_graph +ax_tree_to_graph.py +=================== +Extract the accessibility tree of a web page and transform it into a +NetworkX directed graph. + +Two extraction strategies are used and merged: + 1. CDP (cdp_use) – low-level Chrome DevTools Protocol via + Accessibility.getFullAXTree, which exposes every node + including ignored ones, parentId / childIds, + backendDOMNodeId, and all ARIA properties. + 2. Playwright – high-level snapshot via page.accessibility.snapshot(), + used to enrich CDP nodes with computed state attributes. + +The final graph uses CDP node-ids as node keys. Playwright data is merged +as additional attributes where a matching node is found. + +Usage +----- + python ax_tree_to_graph.py [--output graph.graphml] [--draw] [--no-ignored] + python ax_tree_to_graph.py https://www.regione.toscana.it/regione/amministrazione-trasparente/bandi-di-concorso --output graph.json --draw + python ax_tree_to_graph.py https://www.regione.toscana.it/regione/amministrazione-trasparente/bandi-di-concorso --output graph_ignored.json --draw --no-ignored #per ignorare quelli nodi che hanno ignored=true + + +Requirements +------------ + pip install playwright cdp-use networkx matplotlib + playwright install chromium +""" + +import argparse +import asyncio +import json +import socket +import sys +from typing import Any, Optional + +import networkx as nx +from playwright.async_api import async_playwright +from cdp_use import CDPClient + + +# ───────────────────────────────────────────────────────────────────────────── +# Helpers +# ───────────────────────────────────────────────────────────────────────────── + +def _find_free_port() -> int: + """Return an available TCP port on localhost.""" + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.bind(("", 0)) + return s.getsockname()[1] + + +# ───────────────────────────────────────────────────────────────────────────── +# 1. Playwright snapshot → flat lookup dict {(role, name) -> attrs} +# ───────────────────────────────────────────────────────────────────────────── + +import re +import yaml +from typing import Optional, Union, List, Dict, Any + +import re +import yaml +from typing import Optional, Any + + +import re +import yaml +from typing import Optional, Any + +def _flatten_playwright_snapshot( + yaml_str: str, + result: Optional[dict] = None, +) -> dict: + """ + Parses Playwright's YAML ARIA snapshot string and flattens it into a dict + keyed by (role, name) for later merging with CDP nodes. + """ + if result is None: + result = {} + + try: + parsed_data = yaml.safe_load(yaml_str) + except Exception as e: + print(f" [!] Failed to parse ARIA snapshot YAML: {e}") + return result + + node_regex = re.compile(r'^([a-zA-Z0-9_-]+)(?:\s+"([^"]*)")?(?:\s+\[(.*)\])?$') + + def _process_node(node: Any, depth: int = 0): + if isinstance(node, list): + for item in node: + _process_node(item, depth) + elif isinstance(node, dict): + for key, value in node.items(): + _parse_single_node(key, value, depth) + elif isinstance(node, str): + _parse_single_node(node, None, depth) + + def _parse_single_node(node_key: str, node_value: Any, depth: int): + if node_key == "box": + return + + match = node_regex.match(node_key.strip()) + if not match: + return + + role = (match.group(1) or "unknown").lower() + name = (match.group(2) or "").strip() + attr_string = match.group(3) or "" + + if role == "text" and not name: + name = node_key.replace("text ", "").strip('" ') + + key = (role, name) + + if key not in result: + attrs = { + "pw_role": role, + "pw_name": name, + "pw_depth": depth, #represents the nesting level of that element within the page's accessibility tree structure. The accessibility depth (pw_depth) is usually shallower than the actual DOM level because it skips all the purely visual wrapper elements + #"pw_level": #gestito in maniera custom sotto #pw_level represents the hierarchical structural level of an element—most commonly used for headings, lists, and tree grids. + #It directly maps to the standard HTML heading levels (

through

) or explicit aria-level attributes used on elements. + #This is a semantic property coming directly from the browser's accessibility layer. pw_depth: This is a structural + } + + + # ── 1. Clean & extract box details ──────────────────────────── + if "box=" in attr_string: + box_match = re.search(r'box=\[?(-?\d+),(-?\d+),(-?\d+),(-?\d+)\]?', attr_string) + if box_match: + attrs["pw_box"] = [int(x) for x in box_match.groups()] + attr_string = re.sub(r',?\s*box=\[?[\d,,-]+\]?', '', attr_string).strip() + + # ── 2. FIX: Clean & extract level details safely ────────────── + if "level=" in attr_string: + level_match = re.search(r'level=(\d+)', attr_string) + if level_match: + attrs["pw_level"] = int(level_match.group(1)) + # Clean out the level substring so the comma loop doesn't get corrupted brackets + attr_string = re.sub(r',?\s*level=\d+\]?\s*\[?', '', attr_string).strip() + + # ── 3. Parse remaining standard inline attributes ───────────── + if attr_string: + # Clean up residual broken brackets before splitting + attr_string = attr_string.replace('[', '').replace(']', '').strip() + for pair in attr_string.split(','): + pair = pair.strip() + if not pair: + continue + if '=' in pair: + k, v = pair.split('=', 1) + attrs[f"pw_{k.strip()}"] = v.strip().strip('"') + else: + attrs[f"pw_{pair}"] = True + + # ── 4. Extract nested structural sub-nodes ──────────────────── + if isinstance(node_value, dict): + if "box" in node_value: + attrs["pw_box"] = node_value["box"] + + for k, v in node_value.items(): + if k != "box" and not node_regex.match(k.strip()): + attrs[f"pw_{k}"] = v + + result[key] = {k: v for k, v in attrs.items() if v is not None and v != ""} + + # ── 5. Handle child hierarchies ─────────────────────────────────── + if isinstance(node_value, list): + _process_node(node_value, depth + 1) + elif isinstance(node_value, dict): + for k, v in node_value.items(): + if k != "box" and node_regex.match(k.strip()): + _parse_single_node(k, v, depth + 1) + + _process_node(parsed_data) + return result + + + + +# ───────────────────────────────────────────────────────────────────────────── +# 2. CDP AXNode helpers +# ───────────────────────────────────────────────────────────────────────────── + +def _unwrap_ax_value(ax_value: Optional[dict]) -> Any: + """ + Unwrap a CDP AXValue dict { type, value, relatedNodes?, … } + to a plain Python scalar. + """ + if ax_value is None: + return None + raw = ax_value.get("value") + typ = ax_value.get("type", "") + if typ == "boolean": + return bool(raw) + if typ in ("integer", "number"): + try: + return float(raw) + except (TypeError, ValueError): + return raw + if typ=="nodeList": #typical for labelledby properties + # Return a list of backendDOMNodeId for related nodes + #print(f"[*] Unwrapping nodeList: {ax_value}") + return [n.get("idref") for n in ax_value.get("relatedNodes", []) if n.get("backendDOMNodeId") is not None] + if isinstance(raw, dict): + return raw.get("value") or str(raw) + return raw + + +def _node_to_attrs(node: dict) -> dict: + """Convert a raw CDP AXNode dict into clean, flat node attributes.""" + attrs: dict = { + "node_id": node.get("nodeId", ""), + "ignored": node.get("ignored", False), + "role": _unwrap_ax_value(node.get("role")), + "chrome_role": _unwrap_ax_value(node.get("chromeRole")), + "name": _unwrap_ax_value(node.get("name")), + "description": _unwrap_ax_value(node.get("description")), + "value": _unwrap_ax_value(node.get("value")), + "backend_dom_node_id": node.get("backendDOMNodeId"), + "frame_id": node.get("frameId"), + "type": _unwrap_ax_value(node.get("role")),# already use for role + } + + # Flatten all ARIA properties (focusable, focused, disabled, level, …) + #NB aria-hidden property is missing, because it is not returned directly from CDP nor playwright. Probably can be inferred with some heuristic + for prop in node.get("properties") or []: # manage properties attributes + pname = prop.get("name", "") + pval = _unwrap_ax_value(prop.get("value")) + + if pname: + attrs[f"aria_{pname}"] = pval + + # Collect ignore reasons as a readable string + reasons = [ + # _unwrap_ax_value(r.get("value")) + r.get("name") + for r in node.get("ignoredReasons") or [] + ] + filtered = [str(r) for r in reasons if r is not None] + if filtered: + attrs["ignored_reasons"] = "; ".join(filtered) + + return {k: v for k, v in attrs.items() if v is not None and v != ""} + + +# ───────────────────────────────────────────────────────────────────────────── +# 3. Build NetworkX graph from CDP nodes +# ───────────────────────────────────────────────────────────────────────────── + +def build_graph(cdp_nodes: list[dict]) -> nx.DiGraph: + """ + Build a directed graph from the CDP AXNode list. + + Nodes : one per AXNode, keyed by nodeId string. + Edges : parent → child (relation="child") + node → related_node (relation=aria_property_name, + e.g. "labelledby", "controls") + """ + G = nx.DiGraph() + id_to_raw: dict[str, dict] = {} + + # ── pass 1: add all nodes ───────────────────────────────────────────── + for raw in cdp_nodes: + nid = raw.get("nodeId", "") + if not nid: + continue + G.add_node(nid, **_node_to_attrs(raw)) + id_to_raw[nid] = raw + + # ── pass 2: structural edges (parent → child) ───────────────────────── + edge_attributes_child = { + "relation": "hasChild", + "type": "hasChild" + } + + edge_attributes_parent = { + "relation": "hasParent", + "type": "hasParent" + } + + """for nid, raw in id_to_raw.items(): + parent_id = raw.get("parentId") + if parent_id and parent_id in G and not G.has_edge(parent_id, nid): + G.add_edge(parent_id, nid, **edge_attributes) + + for child_id in raw.get("childIds") or []: + if child_id in G and not G.has_edge(nid, child_id): + G.add_edge(nid, child_id, **edge_attributes)""" + + + for nid, raw in id_to_raw.items(): + parent_id = raw.get("parentId") + # Direct link to parent: Flow goes UP from child to parent + if parent_id and parent_id in G: + if not G.has_edge(nid, parent_id): + G.add_edge(nid, parent_id, **edge_attributes_parent) + # Optional: Add the downward link if you want bidirectional navigation + #if not G.has_edge(parent_id, nid): + # G.add_edge(parent_id, nid, **edge_attributes_child) + + # Direct link to children: Flow goes DOWN from parent to child + for child_id in raw.get("childIds") or []: + if child_id in G: + if not G.has_edge(nid, child_id): + G.add_edge(nid, child_id, **edge_attributes_child) + # Optional: Add the upward link + #if not G.has_edge(child_id, nid): + # G.add_edge(child_id, nid, **edge_attributes_parent) + + # ── pass 3: ARIA relationship edges ─────────────────────────────────── + # these links are built from node properties setted before (from "node properties" attributes). In reality they are built from id_to_raw but they follow the same elaboration + # these link has superior importance respect to parent-child relationship because they represent a semantic relationship. ths is why they override he previous + # because they are both node attributes and edge attributes, mayybe are redundant. TBM + ARIA_REL_PROPS = { #aria-describedby has the name describedby and so on... + + #Labeling and Describing. These attributes form a relationship between an element and the text that identifies or explains it. + 'describedby', #'aria-describedby' has the name 'describedby' in CDP properties + 'labelledby', + 'details', + + #Controlling and Owning. These attributes define hierarchy, control, and structural relationships when elements aren't nested inside each other in the actual HTML code. + 'controls', + 'owns', + 'activedescendant', + + #Navigating and Ordering. These attributes help assistive technologies understand how to navigate between distinct elements or content blocks. + 'flowto', + 'colindex', + 'rowindex' + } + + backend_to_nid: dict[int, str] = { + raw.get("backendDOMNodeId"): nid + for nid, raw in id_to_raw.items() + if raw.get("backendDOMNodeId") is not None + } + + for nid, raw in id_to_raw.items(): + for prop in raw.get("properties") or []: + pname = prop.get("name", "") + if pname not in ARIA_REL_PROPS: + continue + else: + print(f" [*] Processing ARIA relation property: {pname}") + + pval = prop.get("value", {}) + print(f" [*] ARIA relation value: {pval}") + + for rel_node in pval.get("relatedNodes", []): + bid = rel_node.get("backendDOMNodeId") + target = backend_to_nid.get(bid) + if not target: + print(f" [!] Warning: No target node found for ARIA relation {pname} with backendDOMNodeId {bid}") + if G.has_edge(nid, target): + print(f" [!] Warning: Edge already exists for {nid} --{pname}--> {target}, updating link") + #if target and not G.has_edge(nid, target): + if target : #ovverride! this link is more important than the parent-child relationship + print(f" [*] Adding ARIA edge: {nid} --{pname}--> {target}") + edge_attributes = { + "relation": pname, + "type": pname + } + G.add_edge(nid, target, **edge_attributes) + + return G + + +# ───────────────────────────────────────────────────────────────────────────── +# 4. Merge Playwright data into the graph (best-effort by role+name) +# ───────────────────────────────────────────────────────────────────────────── + +def merge_playwright_data(G: nx.DiGraph, pw_flat: dict) -> None: + """ + Match Playwright nodes to CDP nodes by (role, name) and enrich + graph node attributes with Playwright-specific computed states. + NB: only nodes are managed, not edges, since Playwright snapshot doesn't expose parent/child relationships. + """ + role_name_to_nid: dict[tuple, str] = {} + for nid, attrs in G.nodes(data=True): + role = str(attrs.get("role") or "").lower() + name = str(attrs.get("name") or "").strip() + key = (role, name) + if key not in role_name_to_nid: + role_name_to_nid[key] = nid + + for (role, name), pw_attrs in pw_flat.items(): + nid = role_name_to_nid.get((role, name)) + if nid: + # Only add keys not already present from CDP + existing = G.nodes[nid] + for k, v in pw_attrs.items(): + if k not in existing: + G.nodes[nid][k] = v + + +# ───────────────────────────────────────────────────────────────────────────── +# 5. Graph summary +# ───────────────────────────────────────────────────────────────────────────── + +def print_graph_summary(G: nx.DiGraph) -> None: + print(f"\n{'='*60}") + print(" Accessibility Tree Graph Summary") + print(f"{'='*60}") + print(f" Nodes (AX nodes) : {G.number_of_nodes()}") + print(f" Edges : {G.number_of_edges()}") + + ignored = sum(1 for _, a in G.nodes(data=True) if a.get("ignored")) + print(f" Ignored nodes : {ignored}") + + roles: dict[str, int] = {} + for _, attrs in G.nodes(data=True): + r = str(attrs.get("role") or "none") + roles[r] = roles.get(r, 0) + 1 + print("\n Role distribution (top 20):") + for role, cnt in sorted(roles.items(), key=lambda x: -x[1])[:20]: + print(f" {role:<30} {cnt}") + + edge_types: dict[str, int] = {} + for _, _, a in G.edges(data=True): + rel = a.get("relation", "unknown") + edge_types[rel] = edge_types.get(rel, 0) + 1 + print("\n Edge types:") + for rel, cnt in sorted(edge_types.items(), key=lambda x: -x[1]): + print(f" {rel:<30} {cnt}") + + components = nx.number_connected_components(G.to_undirected()) + dag = nx.is_directed_acyclic_graph(G) + print(f"\n Connected components: {components}") + print(f" DAG : {'yes' if dag else 'no (cycles detected)'}") + print(f"{'='*60}\n") + + +# ───────────────────────────────────────────────────────────────────────────── +# 6. Export +# ───────────────────────────────────────────────────────────────────────────── + +def save_graph(G: nx.DiGraph, path: str) -> None: + if path.endswith(".json"): + data = nx.node_link_data(G) + with open(path, "w", encoding="utf-8") as f: + json.dump(data, f, indent=2, default=str) + print(f"[*] Saved → {path} (node-link JSON)") + else: + # GraphML requires all attribute values to be strings + G_exp = G.copy() + for _, attrs in G_exp.nodes(data=True): + for k in list(attrs): + attrs[k] = str(attrs[k]) + for _, _, attrs in G_exp.edges(data=True): + for k in list(attrs): + attrs[k] = str(attrs[k]) + nx.write_graphml(G_exp, path) + print(f"[*] Saved → {path} (GraphML)") + + +def draw_graph(G: nx.DiGraph, max_nodes: int = 80, out: str = "ax_graph.png") -> None: + try: + import matplotlib.pyplot as plt + except ImportError: + print("[!] matplotlib not installed — skipping draw") + return + + if G.number_of_nodes() > max_nodes: + print(f"[*] Subgraph: top {max_nodes} nodes by degree") + top = sorted(G.nodes(), key=lambda n: G.degree(n), reverse=True)[:max_nodes] + G = G.subgraph(top).copy() + + ROLE_COLORS = { + "WebArea": "#4A90D9", "RootWebArea": "#4A90D9", + "heading": "#F57C00", "link": "#388E3C", + "button": "#7B1FA2", "img": "#C62828", + "image": "#C62828", "textbox": "#1565C0", + "navigation": "#00838F", "main": "#558B2F", + "banner": "#AD1457", "contentinfo": "#6D4C41", + "list": "#0288D1", "listitem": "#0288D1", + "form": "#E64A19", "checkbox": "#6A1B9A", + "combobox": "#283593", "region": "#4527A0", + "generic": "#B0BEC5", "none": "#ECEFF1", + } + + node_colors, labels = [], {} + for nid, attrs in G.nodes(data=True): + role = str(attrs.get("role") or attrs.get("pw_role") or "none") + node_colors.append(ROLE_COLORS.get(role, "#CFD8DC")) + name = str(attrs.get("name") or attrs.get("pw_name") or "")[:22] + labels[nid] = f"{role}\n{name}" if name else role + + plt.figure(figsize=(22, 15)) + try: + pos = nx.nx_agraph.graphviz_layout(G, prog="dot") + except Exception: + pos = nx.spring_layout(G, seed=42, k=2.5) + + nx.draw_networkx( + G, pos=pos, labels=labels, + node_color=node_colors, node_size=700, + font_size=6, arrows=True, + edge_color="#90A4AE", width=0.8, + ) + plt.title("Accessibility Tree Graph", fontsize=14) + plt.axis("off") + plt.tight_layout() + plt.savefig(out, dpi=150, bbox_inches="tight") + print(f"[*] Graph image saved → {out}") + + +# ───────────────────────────────────────────────────────────────────────────── +# 7. Main pipeline +# ───────────────────────────────────────────────────────────────────────────── + +async def extract_and_build(url: str) -> nx.DiGraph: + """ + Full pipeline: + a) Pick a free TCP port for CDP remote debugging. + b) Launch Chromium (Playwright) with that port. + c) Navigate to the URL and wait for network idle. + d) Extract AX snapshot via page.accessibility.snapshot(). + e) Extract full AX tree via CDP (cdp_use). + f) Build NetworkX graph; merge Playwright data. + """ + debug_port = _find_free_port() + print(f"[*] Using CDP debug port: {debug_port}") + + async with async_playwright() as pw: + browser = await pw.chromium.launch( + headless=True, + args=[f"--remote-debugging-port={debug_port}"], + ) + context = await browser.new_context(viewport={"width": 1920, "height": 1080}) + page = await context.new_page() + + print(f"[*] Navigating to: {url}") + await page.goto(url, wait_until="networkidle", timeout=30_000) + await page.wait_for_timeout(1000) # let dynamic content settle + + # ── Step A: Playwright accessibility snapshot ───────────────────── + print("[*] Playwright: extracting accessibility snapshot …") + + pw_snapshot_str: str = "" + try: + # Captures the new YAML-based ARIA snapshot including bounding box coordinates + # https://playwright.dev/python/docs/aria-snapshots + snapshot = await page.aria_snapshot(boxes=True,mode="ai") + if snapshot: + pw_snapshot_str = snapshot + # Since it's a YAML string, we can count lines or characters to log density + #print(f"yaml file: {pw_snapshot_str.strip().splitlines()}") + line_count = len(pw_snapshot_str.strip().splitlines()) + print(f" → Playwright ARIA snapshot collected ({line_count} lines of YAML structure)") + pw_flat = _flatten_playwright_snapshot(snapshot) + else: + print(" [!] Snapshot returned None (page may be empty)") + except Exception as e: + print(f" [!] Playwright snapshot failed: {e}") + + + # ── Step B: CDP via cdp_use ─────────────────────────────────────── + print("[*] CDP: connecting via cdp_use …") + cdp_nodes: list[dict] = [] + try: + import urllib.request + with urllib.request.urlopen( + f"http://localhost:{debug_port}/json", timeout=5 + ) as resp: + targets = json.loads(resp.read()) + + page_targets = [ + t for t in targets + if t.get("type") == "page" and "webSocketDebuggerUrl" in t + ] + + if not page_targets: + raise RuntimeError("No page target found in CDP /json endpoint") + + ws_url = page_targets[0]["webSocketDebuggerUrl"] + print(f" → WebSocket: {ws_url}") + + async with CDPClient(ws_url) as cdp: + await cdp.send_raw("Accessibility.enable") + result = await cdp.send_raw("Accessibility.getFullAXTree", {}) + cdp_nodes = result.get("nodes", []) + await cdp.send_raw("Accessibility.disable") + + print(f" → {len(cdp_nodes)} CDP AX nodes collected") + + except Exception as e: + print(f" [!] CDP extraction failed: {e}") + + await browser.close() + + # ── Build graph ─────────────────────────────────────────────────────── + if cdp_nodes: + print("[*] Building graph from CDP nodes …") + G = build_graph(cdp_nodes) + if pw_flat: + print("[*] Merging Playwright attributes …") + merge_playwright_data(G, pw_flat) + elif pw_flat: + print("[!] CDP unavailable — building graph from Playwright snapshot only") + G = _build_graph_from_pw(pw_flat) + else: + raise RuntimeError("No accessibility data could be extracted.") + + return G + + +def _build_graph_from_pw(pw_flat: dict) -> nx.DiGraph: + """Fallback: build a simple graph from Playwright snapshot only.""" + G = nx.DiGraph() + id_map: dict[tuple, str] = {} + + for i, (key, attrs) in enumerate(pw_flat.items()): + nid = str(i) + id_map[key] = nid + G.add_node(nid, **attrs) + + # Playwright flat dict doesn't carry parent references directly; + # reconstruct by depth ordering (parent = most recent node at depth-1) + depth_stack: dict[int, str] = {} + for i, (key, attrs) in enumerate(pw_flat.items()): + nid = str(i) + depth = attrs.get("pw_depth", 0) + if depth > 0 and (depth - 1) in depth_stack: + G.add_edge(depth_stack[depth - 1], nid, relation="pw_child")#static, has to be manged + depth_stack[depth] = nid + + return G + + +# ───────────────────────────────────────────────────────────────────────────── +# 8. CLI +# ───────────────────────────────────────────────────────────────────────────── + +def _parse_args() -> argparse.Namespace: + p = argparse.ArgumentParser( + description="Extract the accessibility tree of a web page → NetworkX graph" + ) + p.add_argument("url", help="URL to analyse (http/https or file://)") + p.add_argument( + "--output", "-o", default="ax_graph.graphml", + help="Output path (.graphml or .json) [default: ax_graph.graphml]", + ) + p.add_argument( + "--draw", action="store_true", + help="Render and save ax_graph.png", + ) + p.add_argument( + "--no-ignored", action="store_true", + help="Remove ignored AX nodes before saving", + ) + return p.parse_args() + + +async def main() -> None: + args = _parse_args() + G = await extract_and_build(args.url) + + if args.no_ignored: + to_remove = [n for n, a in G.nodes(data=True) if a.get("ignored")] + G.remove_nodes_from(to_remove) + print(f"[*] Removed {len(to_remove)} ignored nodes") + + print_graph_summary(G) + save_graph(G, args.output) + + if args.draw: + draw_graph(G) + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/scripts/costruzione_grafo/draw_graph_pyvis.py b/scripts/costruzione_grafo/draw_graph_pyvis.py new file mode 100644 index 0000000..64bbe9f --- /dev/null +++ b/scripts/costruzione_grafo/draw_graph_pyvis.py @@ -0,0 +1,24 @@ +import json +import networkx as nx +from pyvis.network import Network + +# 1. Load the Node-link JSON data +file_path = "graph.json" # Replace with your actual file path +with open(file_path, "r") as f: + data = json.load(f) + +# 2. Reconstruct the NetworkX graph +G = nx.readwrite.json_graph.node_link_graph(data) + +# 3. Initialize PyVis Network +# '100%' width/height makes it responsive. 'notebook=False' is for standalone scripts. +net = Network(height="750px", width="100%", bgcolor="#222222", font_color="white",filter_menu=True,cdn_resources="remote") + +# 4. Import the NetworkX graph into PyVis +net.from_nx(G) + +# 5. Enable the interactive physics/control UI panel (Optional, but great for tweaking layout) +net.show_buttons(filter_=["physics", "nodes", "edges"]) + +# 6. Save and open the interactive graph in your default browser +net.write_html("interactive_graph.html", open_browser=True) \ No newline at end of file diff --git a/scripts/costruzione_grafo/neo4j_management/KnowledgeGraph_manager.py b/scripts/costruzione_grafo/neo4j_management/KnowledgeGraph_manager.py new file mode 100644 index 0000000..28573ba --- /dev/null +++ b/scripts/costruzione_grafo/neo4j_management/KnowledgeGraph_manager.py @@ -0,0 +1,179 @@ +#### To launch the script +# python KnowledgeGraph_manager.py --graph_name accessibility_graph --graph_type directed --from_graph ../graph.json --save_to_neo4j + +import sys + +import argparse + +import json + +from dependences.graph.neo4j_manager import Neo4jManager, neo4j_exception +from dependences.graph.graph_manager import ( + GraphManager, + key_error_exception, + graph_exception, +) +from dotenv import load_dotenv, find_dotenv +from dependences.utils.utils import return_from_env_valid, logging_startup, Params +import logging + + +exception_msg = "Exception: %s" + + +def app_startup(use_neo4j=False): + default_savelog = return_from_env_valid("savelog", "False") + default_loglevel = return_from_env_valid("loglevel", "INFO") + default_logmode = return_from_env_valid("logmode", "a") + default_logpath = return_from_env_valid("logpath", "/my_kg_server_log.log") + directory_separator = return_from_env_valid("directory_separator", "/") + + params = Params( + default_savelog, + default_loglevel, + default_logmode, + default_logpath, + directory_separator, + ) + + logging_startup(params) + + default_persistence_path = return_from_env_valid( + "default_persistence_path", "persistence" + ) + + GRAPH_CONFIG = {"default_persistence_path": default_persistence_path} + graph_manager = GraphManager(GRAPH_CONFIG) + + neo4j_manager = None + + if use_neo4j: + neo4j_uri = return_from_env_valid("neo4j_uri", "bolt://localhost:7687") + neo4j_user = return_from_env_valid("neo4j_user", "neo4j") + neo4j_password = return_from_env_valid("neo4j_password", "neo4j") + neo4j_database = return_from_env_valid("neo4j_database", "neo4j") + + NEO4J_CONFIG = { + "uri": neo4j_uri, + "user": neo4j_user, + "password": neo4j_password, + "database": neo4j_database, + } + neo4j_manager = Neo4jManager(NEO4J_CONFIG) + + return graph_manager, neo4j_manager + + +def cli(sys_argv): + + # Import environment variables + env_path = find_dotenv(filename="env.env") + + if env_path == "": + print("env path not found: service starting with the default params values") + + _ = load_dotenv(env_path) # read .env file + + + parser = argparse.ArgumentParser(description="Knowledge Graph Management") + + + + graph_type_options = {"direct", "undirected"} + parser.add_argument( + "--graph_type", + type=str, + default="directed", + help=(f"Which graph type to buid. Options: {graph_type_options}."), + ) + + parser.add_argument( + "--graph_name", + type=str, + default="my_graphname", + help="the graph name to be created.", + ) + + + + parser.add_argument( + "--save_to_neo4j", action="store_true", help="save graph on Neo4j" + ) + + parser.add_argument( + "--from_graph", + type=str, + default="", + help="start from a pre-existing graph. Path and name has to be provided.", + ) + + + + args = parser.parse_args(sys_argv) + + graph_manager, neo4j_manager = app_startup(use_neo4j=args.save_to_neo4j) + + logging.info("kg manager started with cli args:%s", args) + + + + if 1:#args.task == "populate_graph": + + try: + + if args.from_graph != "": + + logging.info("populate graph from a pre-existing one") + start_from_empty_graph = False + ini_graph = graph_manager.load_graph_from_file(args.from_graph) + + else: + logging.info("populate graph from scratch") + start_from_empty_graph = True + ini_graph = None + + graph = ini_graph + graph_manager.graphs[args.graph_name] = graph + try: + graph_manager.persist_graph_to_file( + graph_name=args.graph_name, + file_name=graph_manager.default_persistence_path + + "/" + + args.graph_name + + ".json", + ) + except Exception as e: + logging.error(exception_msg + " %s", e) + + if args.save_to_neo4j: + logging.info("saving graph to neo4j...") + neo4j_manager.delete_graph_from_neo4j() # because neo4j support only one graph delete is mandatory + + neo4j_manager.save_graph_to_neo4j(graph) + logging.info("graph saved to neo4j") + + except key_error_exception as e: + logging.error(e) + + except graph_exception as e: + logging.error(e) + + except neo4j_exception as e: + logging.error(e) + + except Exception as e: + logging.error(exception_msg + " %s", e) + + else: + logging.info("graph %s correctly created", args.graph_name) + + else: + logging.warning("The task:%s is not managed", args.task) + raise ValueError( + f"{args.task} is not a valid --args.exercise_solution option. Options: {task_type_options}" + ) + + +if __name__ == "__main__": + + cli(sys.argv[1:]) diff --git a/scripts/costruzione_grafo/neo4j_management/dependences/graph/__pycache__/graph_manager.cpython-311.pyc b/scripts/costruzione_grafo/neo4j_management/dependences/graph/__pycache__/graph_manager.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..087e833b2d78961bfe50d51b7f3f3963ec8c3fa0 GIT binary patch literal 45347 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 literal 0 HcmV?d00001 diff --git a/scripts/costruzione_grafo/neo4j_management/dependences/graph/__pycache__/neo4j_manager.cpython-311.pyc b/scripts/costruzione_grafo/neo4j_management/dependences/graph/__pycache__/neo4j_manager.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37de0256a31ca72223840e14375222d871753033 GIT binary patch literal 13013 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 K`8ugY9{&T3?>NQ) literal 0 HcmV?d00001 diff --git a/scripts/costruzione_grafo/neo4j_management/dependences/graph/graph_manager.py b/scripts/costruzione_grafo/neo4j_management/dependences/graph/graph_manager.py new file mode 100644 index 0000000..a249dbc --- /dev/null +++ b/scripts/costruzione_grafo/neo4j_management/dependences/graph/graph_manager.py @@ -0,0 +1,1216 @@ +import networkx as nx +import json +import pickle +import os +from dependences.utils.utils import create_folder, clean_str, process_row +import logging +from copy import deepcopy +from typing import Any, Dict, List, Optional, Tuple, Generator, Union +import pandas as pd + +### Graph element types definition + +# node format (id_node,{attr_dict}) +# Define node type as a union of common hashable types +NodeLabel = Union[int, str, tuple] +# Define node attribute dictionary type +NodeData = Dict[str, Any] +Node = Tuple[NodeLabel, NodeData] + + +# edge format (id_node_source, id_node_dest, {attr_dict}) +# Define edge attribute dictionary type +EdgeData = Dict[str, Any] +# Define the edge type +Edge = Tuple[NodeLabel, NodeLabel, EdgeData] + +EdgeList = List[Edge] +NodeList = List[Node] + +### ------------------- + + +class key_error_exception(Exception): + "Raised when there is serach in a dictionary with a not valid key" + + pass + + +class graph_exception(Exception): + "Raised when a graph exception araise" + + pass + + +class GraphManager: + + graphs: dict + default_persistence_path: str + + def __init__(self, cfg=dict) -> None: + """Init method definition.""" + + self.default_persistence_path = cfg["default_persistence_path"] + self.graphs = {} + + def create_nx_graph( + self, + graph_name: str = "my_graphname", + graph_type: str = "directed", + ) -> nx.Graph: # Multigraph option are not taken into consideration + if graph_type == "directed": + graph = nx.DiGraph() + else: + graph = nx.Graph() + + self.graphs[graph_name] = graph + return graph + + def load_graph(self, graph: str | dict) -> nx.Graph: + """Load a graph from a graphml string representation or a networkx dict graph .""" + return ( + nx.parse_graphml(graph) + if isinstance(graph, str) + else nx.node_link_graph(graph) + ) + + def get_graph_info(self, graph: str | nx.Graph) -> dict: + + try: + return ( + nx.node_link_data(nx.parse_graphml(graph)) + if isinstance(graph, str) + else nx.node_link_data(graph) + ) + except Exception as e: + logging.error("exception:%s", e) + raise graph_exception("Graph info exception:" + str(e)) + + def stringify_graph(self, G: nx.Graph) -> str: + return "".join(nx.generate_graphml(G)) + + def load_graph_from_file(self, file_name: str = "graph.json") -> nx.Graph: + + try: + file_type = file_name.split(".")[-1] + graph_name = file_name.split("/")[-1].split(".")[ + 0 + ] # the graph name is the file name + if file_type == "json": + with open(file_name, "r") as f: + graph = nx.node_link_graph(json.load(f)) + + elif file_type == "pickle": + + with open(file_name, "rb") as f: + + graph = pickle.load(f) + + elif file_type == "graphml": + graph = nx.read_graphml(file_name) + + else: + graph = None + + except Exception as e: + logging.error("exception:%s", e) + raise graph_exception("Load graph from file exception:" + str(e)) + + else: + self.graphs[graph_name] = graph + return graph + + def load_graphs_from_dir(self) -> bool: + try: + for curdir, _, filenames in os.walk(self.default_persistence_path): + if curdir != self.default_persistence_path: + continue + + for filename in filenames: + self.load_graph_from_file(curdir + "/" + filename) + except Exception as e: + logging.error("exception:%s", e) + + return False + + def get_graph_from_name(self, graph_name: str) -> nx.Graph: + + try: + G = self.graphs[graph_name] + + return G + except KeyError as e: + logging.error("key error exception:%s", e) + raise key_error_exception("Graph key-name error exception:" + str(e)) + + except Exception as e: + logging.error("exception:%s", e) + raise graph_exception("Graph name error exception:" + str(e)) + + def persist_graph_to_file( + self, graph_name: str, file_name: str = "graph.json" + ) -> bool: + + try: + + G = self.get_graph_from_name(graph_name) + + if ( + "/" in file_name + ): # able to manage folder in the form type persistence/graph.json + next_path = file_name.split("/")[0] + + _ = create_folder(root_path=os.getcwd(), next_path=next_path) + + file_type = file_name.split(".")[-1] + + if file_type == "json": + + with open(file_name, "w") as f: + json.dump(nx.node_link_data(G), f) + + elif file_type == "pickle": + + with open(file_name, "wb") as f: + f.write(pickle.dumps(G, pickle.HIGHEST_PROTOCOL)) + + elif file_type == "graphml": + nx.write_graphml(G, file_name) + + else: + return False + return True + except Exception as e: + logging.error("exception:%s", e) + return False + + def persist_graphs_to_dir(self, default_type: str = ".json") -> bool: + try: + + for graphname in self.graphs.keys(): + self.persist_graph_to_file( + graph_name=graphname, + filename=self.default_persistence_path + + "/" + + graphname + + default_type, + ) + except Exception as e: + logging.error("exception:%s", e) + return False + + def delete_graph(self, graph_name: str, also_filesytem: bool = False) -> bool: + + try: + G = self.get_graph_from_name(graph_name) + + logging.info( + "deleting graph with #nodes:%s and number of edge: %s", + str(G.number_of_nodes()), + str(G.number_of_edges()), + ) + + del G + del self.graphs[graph_name] + + if also_filesytem: + for curdir, _, filenames in os.walk(self.default_persistence_path): + + if curdir != self.default_persistence_path: + + continue + for filename in filenames: + if ( + filename.split(".")[0] == graph_name + ): # delete without formt check + logging.info( + "deleting graph file from filesystem:%s ", graph_name + ) + os.remove(curdir + "/" + filename) + + return True + + except key_error_exception as e: + logging.error("exception deleting graph key error:%s", e) + raise graph_exception("Delete graph exception:" + str(e)) + + except Exception as e: + logging.error("exception deleting graph:%s", e) + raise graph_exception("Delete graph exception:" + str(e)) + + def delete_graphs(self, also_filesytem: bool = False) -> bool: + + all_graphs = deepcopy(self.graphs) + try: + for graphname in all_graphs.keys(): + self.delete_graph(graph_name=graphname, also_filesytem=also_filesytem) + return True + except Exception as e: + logging.error("exception:%s", e) + return False + + def graph_properties( + self, + G: nx.Graph, + interests: list = [ + "general", + "centrality", + "clustering", + "connected_component", + "assortativity", + "path_related", + "communities", + ], + ) -> dict: + + g_returned_features = {} + + try: + + for interest in interests: + if interest == "general": + g_features = {} + # general properties + + g_features["is_directed"] = G.is_directed() + + g_features["is_multigraph"] = G.is_multigraph() + + g_features["number_of_nodes"] = G.number_of_nodes() + + g_features["number_of_edges"] = G.number_of_edges() + + graph_degrees = G.degree() + + g_features["graph_degrees"] = graph_degrees + + degree_hist = nx.degree_histogram(G) + + g_features["degree_hist"] = degree_hist + + max_degree = max(graph_degrees, key=lambda x: x[1])[1] + + g_features["max_degree"] = max_degree + + g_features["average_degree"] = round( + (2 * G.number_of_edges()) / G.number_of_nodes(), 2 + ) + + if not (G.is_directed()): + + g_features["is_connected"] = nx.is_connected(G) + + g_features["is_DAG"] = nx.is_directed_acyclic_graph(G) + + if G.is_directed() and not (G.is_multigraph()): + + g_features["is_aperiodic"] = nx.is_aperiodic(G) + g_features["is_strongly_connected"] = nx.is_strongly_connected( + G + ) + + elif not (G.is_directed()) and not (G.is_multigraph()): + + g_features["cycles"] = nx.cycle_basis(G) + + g_features["number_of_selfloops"] = nx.number_of_selfloops(G) + + g_returned_features["general"] = g_features + + if interest == "centrality": + g_features = {} + # centrality + + try: + g_features["degree_centrality"] = nx.degree_centrality(G) + g_features["closeness_centrality"] = nx.closeness_centrality(G) + g_features["pagerank"] = nx.pagerank(G, alpha=0.8) + g_features["betweenness_centrality"] = ( + nx.betweenness_centrality(G) + ) + + except Exception as e: + logging.error("exception on centrality:%s", e) + + g_returned_features["centrality"] = g_features + + if interest == "clustering": + g_features = {} + # clustering + if not (G.is_multigraph()): + + g_features["clustering"] = nx.clustering(G) + g_features["average_clustering"] = nx.average_clustering(G) + g_returned_features["clustering"] = g_features + + if interest == "connected_component": + g_features = {} + + # connected component + if not (G.is_directed()): + + g_features["number_connected_components"] = ( + nx.number_connected_components(G) + ) + # identify largest connected component= Giant component + Gcc = sorted(nx.connected_components(G), key=len, reverse=True) + G0 = G.subgraph(Gcc[0]) + + g_features["giant_component_edges"] = G0.number_of_edges() + g_features["giant_component_nodes"] = G0.number_of_nodes() + g_returned_features["connected_component"] = g_features + + if interest == "assortativity": + g_features = {} + ##### Assortativity + # connectivity + + g_features["average_neighbor_degree"] = nx.average_neighbor_degree( + G + ) + g_features["average_degree_connectivity"] = ( + nx.average_degree_connectivity(G) + ) + + # degree correlation + # Assortativity measures the similarity of connections in the graph with respect to the node degree. + # print("pearson coefficient:",nx.degree_pearson_correlation_coefficient(G))#same result + g_features["degree_assortativity_coefficient"] = ( + nx.degree_assortativity_coefficient(G) + ) + ##### + g_returned_features["assortativity"] = g_features + + if interest == "path_related": + g_features = {} + # path related + + if not (G.is_directed()): + if nx.is_connected(G): # valid only for undirected + g_features["shortest_path"] = nx.shortest_path(G) + + try: + + g_features["average_shortest_path_length"] = ( + nx.average_shortest_path_length(G) + ) + except Exception as e: + + logging.error( + "exception on average shortest path:%s", e + ) + + try: + # The eccentricity of a node v is the maximum distance from v to all other nodes in G + g_features["eccentricity"] = nx.eccentricity(G) + # The radius is the minimum eccentricity. + + g_features["radius"] = nx.radius(G) + # The diameter is the maximum eccentricity. + + g_features["diameter"] = nx.diameter(G) + except Exception as e: + + logging.error("exception on eccentricity:%s", e) + try: + # link analysis (hubs analysis) + # Returns HITS hubs and authorities values for nodes. The HITS algorithm computes two numbers for a node. Authorities estimates the node value based on the incoming links. Hubs estimates the node value based on outgoing links. + + g_features["hits"] = nx.hits(G) + # isolates + # An *isolate* is a node with no neighbors (that is, with degree zero). + + g_features["number_of_isolates"] = nx.number_of_isolates(G) + # print("small word coeff:",nx.omega(G),nx.sigma(G)) #very long computation effort + # print("tree broadcasting:",nx.tree_broadcast_time(G)) + except Exception as e: + logging.error("exception on hits/number_of_isolates:%s", e) + + g_returned_features["path_related"] = g_features + + if interest == "communities": + g_features = {} + # communities + community_louvain = nx.community.louvain_communities(G, seed=123) + communities_lp = list(nx.community.label_propagation_communities(G)) + g_features["community_louvain"] = community_louvain + g_features["communities_lp"] = communities_lp + g_features["number_community_louvain"] = len(community_louvain) + g_features["number_communities_lp"] = len(communities_lp) + + g_returned_features["communities"] = g_features + + except Exception as e: + logging.error("not managed exception on graph properties calculation:%s", e) + + finally: + return g_returned_features + + def from_generator_to_list(self, generator: Generator) -> list: + try: + return list(generator) + except Exception as e: + logging.error("exception on from_generator_to_list:%s", e) + return [] + + def match_attributes(self, data: dict, filter_data: dict) -> bool: + + if ( + filter_data is None or len(filter_data) == 0 + ): # if no filter applied(={}) return True + return True + + for k, v in filter_data.items(): + if data.get(k) != v: + return False + + return True + + def filter_entities_by_attributes( + self, entities: EdgeList | NodeList, attrib: dict, type: str = "node" + ) -> Generator: + if type == "node": + for entity, entitydata in entities: + if self.match_attributes(entitydata, attrib): + yield entity, entitydata + elif type == "edge": + for entitysource, entitydest, entitydata in entities: + if self.match_attributes(entitydata, attrib): + yield entitysource, entitydest, entitydata + else: + return + + ### graphs section + def get_graphs(self, with_info: bool = False) -> dict: + out_dict = {} + count = 0 + part_dict = {} + for k, v in self.graphs.items(): + + if with_info: + + info = self.get_graph_info(v) + part_dict[str(count)] = {k: info} + else: + part_dict[str(count)] = k + count += 1 + + out_dict["graphs"] = part_dict + + return out_dict + + def get_graph(self, graph_name: str) -> dict: # valuate redundance of the method + out_dict = {} + + graph = self.graphs[graph_name] + + info = self.get_graph_info(graph) + + out_dict[graph_name] = info + + return out_dict + + ### nodes section + def node_ego_graph(self, G: nx.Graph, node: str | int) -> nx.Graph: + ego = None + try: + ego = nx.ego_graph(G, node) + + except Exception as e: + logging.error("exception on ego graph:%s", e) + raise graph_exception("exception on ego graph:" + str(e)) + finally: + return ego + + def node_list_neighbour(self, G: nx.Graph, node: str | int) -> NodeList: + neigh_list = [] + try: + neigh_list = list(G.neighbors(node)) + except Exception as e: + logging.error("exception on neighbour extracion:%s", e) + finally: + return neigh_list + + def nodes(self, G: nx.Graph) -> NodeList: + return G.nodes(data=True) + + def node_by_name(self, G: nx.Graph, node: str | int) -> NodeData: + if node in G.nodes: + return G.nodes[node] # just select the element from the list + else: + return dict() + + def delete_node(self, G: nx.Graph, node: str | int) -> None: + + try: + G.remove_node(node) + except Exception as e: + logging.error("exception deleting the node:%s", e) + raise graph_exception("exception deleting the node:" + str(e)) + + ### edge section + def edges(self, G: nx.Graph) -> EdgeList: + return G.edges(data=True) + + def delete_edge(self, G: nx.Graph, source: str | int, dest: str | int) -> None: + try: + G.remove_edge(source, dest) + except Exception as e: + logging.error("exception deleting the edge:%s", e) + raise graph_exception("exception deleting the edge:" + str(e)) + + def edge_by_source_dest( + self, G: nx.Graph, source: str | int, dest: str | int + ) -> EdgeData: + if (source, dest) in G.edges: + + return G.edges[(source, dest)] # just select the element from the list + else: + return dict() + + def edges_by_source_dest( # the difference between the edge_by_source_dest method is that it returns also the source-destination pairs (also considering direction) + self, G: nx.Graph, source: str | int, dest: str | int, is_direct: bool = False + ) -> EdgeList: + + filtered_edges = [] + if is_direct == False: + # Filter edges by source and destination + filtered_edges = [ + (u, v, d) + for u, v, d in G.edges(data=True) + if (u == source and v == dest) or (u == dest and v == source) + ] + else: + # Filter edges by source and destination considering direction + filtered_edges = [ + (u, v, d) for u, v, d in G.edges(data=True) if u == source and v == dest + ] + + return filtered_edges + + def edges_by_extreme(self, G: nx.Graph, extreme: str | int) -> EdgeList: + + filtered_edges = [] + # Filter edges by the extreme + filtered_edges = [ + (u, v, d) + for u, v, d in G.edges(data=True) + if (u == extreme) or (v == extreme) + ] + + return filtered_edges + + # path section + def shortest_path( + self, G: nx.Graph, source: str | int, dest: str | int, method: str = "dijkstra" + ) -> list: + + shortest_path = [] + try: + if not (G.has_node(source) and G.has_node(dest)): + logging.error( + "exception on shortest_path extraction. Source or destination node not exists" + ) + else: + + shortest_path = nx.shortest_path( + G=G, source=source, target=dest, method=method + ) + except Exception as e: + logging.error("exception on shortest_path extracion:%s", e) + return shortest_path + + def shortest_simple_paths( + self, G: nx.Graph, source: str | int, dest: str | int + ) -> Generator | None: + + if not (G.has_node(source) and G.has_node(dest)): + logging.error( + "exception on shortest_simple_paths extraction no source or destination node" + ) + return None + else: + try: + shortest_paths = nx.shortest_simple_paths( + G=G, source=source, target=dest + ) + return shortest_paths + + except nx.NetworkXNoPath as e: + + logging.error( + "exception on shortest_simple_paths extracion no Path:%s", e + ) + return None + + except Exception as e: + logging.error("exception on shortest_simple_paths extracion:%s", e) + return None + + def longest_path(self, G: nx.Graph) -> list: + longest_path = [] + try: + longest_path = nx.dag_longest_path(G) + return longest_path + except nx.NetworkXNotImplemented as e: + logging.error("exception on longest_path extraction:%s", e) + raise graph_exception("Graph longest_path error exception:" + str(e)) + + except Exception as e: + logging.error("exception on longest_path extraction:%s", e) + raise graph_exception("Graph longest_path error exception:" + str(e)) + + # graph population section + def merge_attributes( + self, + item_attributes: Dict[str, Any], + entity=Dict, + policy_on_conflict: str = "controlled_override", + ) -> None: + + try: + if policy_on_conflict == "forced_override": + + for key, value in item_attributes.items(): + entity[key] = value + + elif policy_on_conflict == "controlled_override": + + for key, value in item_attributes.items(): + + if ( + clean_str(str(value)) == "" or value == None + ): # avoiding replacing attributes with empty values + logging.info( + "avoided override because of attribute value:%s,%s", + key, + value, + ) + pass + else: + entity[key] = value + + elif policy_on_conflict == "keep": + + pass + else: + pass # maybe some specific rule. Example: the len of the attributes or some qualitative check. Maybe concatenate attributes if string or min, max, mean if numeric + # take inspiration from merge_graphs.py in graphRag library + except Exception as e: + logging.error("exception on merge_attributes:%s", e) + + def add_merge_node( + self, + graph: nx.Graph, + item_attributes: Dict[str, Any], + policy_on_conflict: str = "controlled_override", + ) -> None: + + try: + id = item_attributes["id"] + + del item_attributes[ + "id" + ] # delete id as attribute because already used as node_id + if id in graph.nodes(): # if graph.has_node(id): + + self.merge_attributes( + item_attributes=item_attributes, + entity=graph.nodes[id], + policy_on_conflict=policy_on_conflict, + ) + + else: + + graph.add_node(id, **item_attributes) + except Exception as e: + logging.error("exception on adding-merging node:%s", e) + raise graph_exception("Graph exception on adding-merging node:" + str(e)) + + def add_merge_edge( + self, + graph: nx.Graph, + item_attributes: Dict[str, Any], + policy_on_conflict: str = "controlled_override", + ) -> None: + + try: + source = item_attributes["source"] + target = item_attributes["target"] + + del item_attributes[ + "source" + ] # delete source ad target as attribute because already used as edge references + del item_attributes["target"] + if graph.has_edge(source, target): + self.merge_attributes( + item_attributes=item_attributes, + entity=graph.edges[(source, target)], + policy_on_conflict=policy_on_conflict, + ) + else: + if not (graph.has_node(source)) or not (graph.has_node(target)): + logging.warning( + "the graph is missing source or target node, do not add edge:%s,%s", + source, + target, + ) + + else: + # because by default add_edge also add node if not present in the graph it is needed to chech to avoid node settings without the proper attributes settings + + graph.add_edge(source, target, **item_attributes) + except Exception as e: + logging.error("exception on adding-merging edge:%s", e) + raise graph_exception("Graph exception on adding-merging edge:" + str(e)) + + def manage_inter_dataset_edges( + self, ini_graph_file_info: dict, graph: nx.Graph + ) -> nx.Graph: + """ + attention: the method use eval() see the other method _noeval + """ + # work directly with the graph methods + logging.info("start working with inter-dataset edge definitions") + nodes = self.nodes(graph) + edges = self.edges(graph) + logging.info( + "Initial graph counter, nodes:%s, edge :%s", len(nodes), len(edges) + ) + for inter_edge in ini_graph_file_info["inter_edges"]: + + attribute_map = inter_edge["attribute_map"] + source_nodes_type = inter_edge["source"]["type"] + target_nodes_type = inter_edge["target"]["type"] + + # source node filter by source type + source_filtered_nodes = list( + self.filter_entities_by_attributes( + nodes, {"type": source_nodes_type}, type="node" + ) + ) + # target node filter by target type + target_filtered_nodes = list( + self.filter_entities_by_attributes( + nodes, {"type": target_nodes_type}, type="node" + ) + ) + + for id_source, attrs_source in source_filtered_nodes: + for id_target, attrs_target in target_filtered_nodes: + + attr_source = inter_edge["source"]["matching_attr"] + attr_source_oper = inter_edge["source"]["operation"] + attr_source_applied = str( + attrs_source[attr_source] + ) # force type to string (operation only on string) + if attr_source_oper != "": + + try: + # nb only methods in the way .dot are usable + attr_source_transf = ( + '"' + attr_source_applied + '".' + attr_source_oper + ) + + attr_source_mod = eval(attr_source_transf) + except Exception as e: + logging.error( + "exception on eval method source:%s,%s,%s", + attr_source_transf, + attr_source_mod, + e, + ) + else: + attr_source_mod = attr_source_applied + + attr_target = inter_edge["target"]["matching_attr"] + attr_target_oper = inter_edge["target"]["operation"] + + attr_target_applied = str( + attrs_target[attr_target] + ) # force type to string (operation only on string) + + if attr_target_oper != "": + try: + # nb only methods in the way .dot are usable + attr_target_transf = ( + '"' + attr_target_applied + '".' + attr_target_oper + ) + + attr_target_mod = eval(attr_target_transf) + except Exception as e: + logging.error("exception on eval method target:%s", e) + else: + attr_target_mod = attr_target_applied + + if attr_source_mod == attr_target_mod: + + attribute_map["source"] = id_source + attribute_map["target"] = id_target + + self.add_merge_edge( + graph=graph, + item_attributes=attribute_map, + policy_on_conflict="controlled_override", + ) + logging.debug( + "Added inter-edge between source node type:%s id:%s, target node type:%s id: %s, on attr source:%s, attr value:%s; attr target:%s, attr value:%s", + source_nodes_type, + id_source, + target_nodes_type, + id_target, + attr_source, + attr_source_mod, + attr_target, + attr_target_mod, + ) + # break # do not use "break" if match found because it is possible a relation one-to-many + + nodes = self.nodes(graph) + edges = self.edges(graph) + logging.info("Final graph counter, node:%s, edges:%s ", len(nodes), len(edges)) + + """ + def manage_inter_dataset_edges_noeval(self, ini_graph_file_info:dict, graph: nx.Graph ) ->nx.Graph: + + ''' this method avoid the use of eval but is less customizable. + ex:"split(' ')[-1].strip()" split is not usable + Also some formula has to be changed like upper()->upper + + ''' + + # work directly with the graph methods + logging.info("start working with inter-dataset edge definitions") + nodes = self.nodes(graph) + edges = self.edges(graph) + logging.info( + "Initial graph counter, nodes:%s, edge :%s", len(nodes), len(edges) + ) + for inter_edge in ini_graph_file_info["inter_edges"]: + + attribute_map = inter_edge["attribute_map"] + source_nodes_type = inter_edge["source"]["type"] + target_nodes_type = inter_edge["target"]["type"] + + #source node filter by source type + source_filtered_nodes = list( + self.filter_entities_by_attributes( + nodes, {"type": source_nodes_type}, type="node" + ) + ) + #target node filter by target type + target_filtered_nodes = list( + self.filter_entities_by_attributes( + nodes, {"type": target_nodes_type}, type="node" + ) + ) + + for id_source, attrs_source in source_filtered_nodes: + for id_target, attrs_target in target_filtered_nodes: + + attr_source = inter_edge["source"]["matching_attr"] + attr_source_oper = inter_edge["source"]["operation"] + + attr_source_applied = str(attrs_source[attr_source])# force type to string (operation only on string) + + + if attr_source_oper!="": + # Use getattr to dynamically apply the method on the string + try: + # getattr will get the method from the string object (attr_source_applied) + attr_source_mod = getattr(attr_source_applied, attr_source_oper)() + #print("attr_source_mod:", attr_source_mod) + except AttributeError: + logging.error("Error: %s is not a valid method for the type of 'attr_source_applied'",attr_source_oper) + else: + attr_source_mod=attr_source_applied + + + attr_target = inter_edge["target"]["matching_attr"] + attr_target_oper = inter_edge["target"]["operation"] + + attr_target_applied = str(attrs_target[attr_target])# force type to string (operation only on string) + + if attr_target_oper!="": + # Use getattr to dynamically apply the method on the string + try: + # getattr will get the method from the string object (attr_source_applied) + attr_target_mod = getattr(attr_target_applied, attr_target_oper)() + #print("attr_target_mod:", attr_target_mod) + except AttributeError: + logging.error("Error: %s is not a valid method for the type of 'attr_target_applied'",attr_target_oper) + else: + attr_target_mod =attr_target_applied + + if attr_source_mod == attr_target_mod: + + attribute_map["source"] = id_source + attribute_map["target"] = id_target + + self.add_merge_edge( + graph=graph, + item_attributes=attribute_map, + policy_on_conflict="controlled_override", + ) + logging.info( + "Added inter-edge between source node type:%s id:%s, target node type:%s id: %s, on attr source:%s, attr value:%s; attr target:%s, attr value:%s", + source_nodes_type, + id_source, + target_nodes_type, + id_target, + attr_source, + attr_source_mod, + attr_target, + attr_target_mod, + ) + # break # do not use "break" if match found because it is possible a relation one-to-many + + nodes = self.nodes(graph) + edges = self.edges(graph) + logging.info( + "Final graph counter, node:%s, edges:%s ", + len(nodes), + len(edges) + ) + """ + + def create_graph_from_df( + self, + df: pd.DataFrame, + graph: nx.Graph | None, + entities_type_list: List[str], + attribute_map_list: List[Dict[str, Any]], + graph_type: str = "undirected", + graph_name="my_graphname", + policy_on_conflict="controlled_override", + max_count_row=10**8, + ) -> nx.Graph: + + try: + if graph == None: + + graph = self.create_nx_graph( + graph_type=graph_type, graph_name=graph_name + ) + + else: + self.graphs[graph_name] = graph + + for cont_row, row in df.iterrows(): # for each row in the dataframe + + if cont_row < max_count_row: + + count_entity = 0 + for entity_type in entities_type_list: + + attribute_map = attribute_map_list[count_entity] + + if entity_type == "node": + + item_attributes = process_row( + row, attribute_map, unique_identifier_key="id" + ) + + self.add_merge_node( + graph, + item_attributes, + policy_on_conflict=policy_on_conflict, + ) + + elif entity_type == "edge": + + item_attributes = process_row( + row, + attribute_map, + unique_identifier_key="source", + unique_identifier_key2="target", + ) + + self.add_merge_edge( + graph, + item_attributes, + policy_on_conflict=policy_on_conflict, + ) + + else: + logging.error("Unknown entity type skipped:%s", entity_type) + continue + count_entity += 1 + else: + logging.info("processed max number of rows:%s", str(cont_row)) + break + return graph + + except Exception as e: + logging.error("exception on create_graph_from_df:%s", e) + + def create_graph_from_multiple_df( + self, + ini_file: str = "ini_graph_file.json", + graph: nx.Graph = None, + start_from_empty_graph: bool = True, + graph_type: str = "undirected", + graph_name: str = "my_graphname", + max_count_row: int = 10**8, + storage_options: dict = {}, + sep: str = ",", + encoding: str = "utf-8", + skipinitialspace: bool = True, + decimal: str = ".", + ) -> nx.Graph: + # in the file the nodes definition should be setted before edge definition because edges are added only if source and target nodes exists + + mandatory_attribute_list_node = ["type", "id", "title", "name", "color"] + mandatory_attribute_list_edge = ["type", "source", "target", "title"] + try: + with open(ini_file, "r", encoding="utf-8") as f: + ini_graph_file_info = json.load(f) + if start_from_empty_graph: + G = None + else: + G = graph + for file in ini_graph_file_info["files"]: + + try: + + attribute_map = {} + + if file["file"].split(".")[-1] == "json": + + if "s3://" in file["file"]: + df = pd.read_json( + file["file"], storage_options=storage_options + ) + + else: + df = pd.read_json(file["file"]) + + elif file["file"].split(".")[-1] == "csv": + + if "s3://" in file["file"]: + df = pd.read_csv( + file["file"], + storage_options=storage_options, + sep=sep, + encoding=encoding, + skipinitialspace=skipinitialspace, + decimal=decimal, + ) + + else: + df = pd.read_csv( + file["file"], + sep=sep, + encoding=encoding, + skipinitialspace=skipinitialspace, + decimal=decimal, + ) + + else: + logging.error("unsupported file format") + continue + + entities_type_list = [] + attribute_map_list = [] + for entity in file["entities"]: + + # check on entity type + if entity.get("entities_type") == None: + logging.warning( + "the ini for %s file does not contain the entities_type tag, skipped", + file["file"], + ) + continue + entities_type = entity["entities_type"] + if entities_type != "node" and entities_type != "edge": + + logging.warning( + "entities_type not managed:%s, skipped for file:%s", + entities_type, + file["file"], + ) + continue + + # check on mandatory attribute + passed_mandatory_attribute_list = list( + entity["mandatory_attribute_map"].keys() + ) + logging.info( + "passed_mandatory_attribute_list:%s for file:%s", + passed_mandatory_attribute_list, + file["file"], + ) + + if entities_type == "node": + mandatory_attribute_list_to_check = ( + mandatory_attribute_list_node + ) + else: + mandatory_attribute_list_to_check = ( + mandatory_attribute_list_edge + ) + + if sorted(passed_mandatory_attribute_list) == sorted( + mandatory_attribute_list_to_check + ): # check if all mandatory attributes are defined in the ini file + logging.info( + "the mandatory attributes map is valid for file:%s", + file["file"], + ) + pass + else: + logging.warning( + "the mandatory attributes map is not valid for file:%s, skipped", + file["file"], + ) + + continue + + attribute_map = {} + for att in entity["mandatory_attribute_map"]: + + attribute_map[att] = entity["mandatory_attribute_map"][ + att + ] + + for att in entity["custom_attribute_map"]: + attribute_map[att] = entity["custom_attribute_map"][att] + logging.info( + "attribute_map:%s for file:%s", + attribute_map, + file["file"], + ) + + # they should be aligned + entities_type_list.append(entities_type) + attribute_map_list.append(attribute_map) + + G = self.create_graph_from_df( + df=df, + graph=G, + entities_type_list=entities_type_list, + attribute_map_list=attribute_map_list, + graph_type=graph_type, + graph_name=graph_name, + max_count_row=max_count_row, + ) + except Exception as e: + logging.error( + "exception on create_graph_from_multiple_df read single file:%s", + e, + ) + continue + if ( + "inter_edges" in ini_graph_file_info + ): # if inter_edge section is defined in the ini file + + self.manage_inter_dataset_edges( + ini_graph_file_info=ini_graph_file_info, graph=G + ) + + return G + except Exception as e: + logging.error("exception on create_graph_from_multiple_df:%s", e) + raise graph_exception( + "exception on create_graph_from_multiple_df:" + str(e) + ) diff --git a/scripts/costruzione_grafo/neo4j_management/dependences/graph/neo4j_manager.py b/scripts/costruzione_grafo/neo4j_management/dependences/graph/neo4j_manager.py new file mode 100644 index 0000000..c775c4c --- /dev/null +++ b/scripts/costruzione_grafo/neo4j_management/dependences/graph/neo4j_manager.py @@ -0,0 +1,292 @@ +import networkx as nx +from neo4j import GraphDatabase +import json +import logging +import time + + +class neo4j_exception(Exception): + "Raised when a neo4j exception araise" + pass + + +class Neo4jManager: + + uri: str + user: str + password: str + database: str + + def __init__(self, cfg=dict) -> None: + self.uri = cfg["uri"] + self.user = cfg["user"] + self.password = cfg["password"] + self.database = cfg["database"] + + logging.info("try to connect to Neo4j for init testing purpose") + # just to wait for server startup and log its status + base = 2 + max_tries = 3 + wait_seconds = [base**i for i in range(max_tries)] + connection_success = False + for num_tries in range(max_tries): + try: + _ = self.count_nodes_neo4j() + + except Exception as e: + + logging.error("Problem with the Neo4j connection:%s", e) + logging.info("neo4j connection num_tries:%s", num_tries) + logging.info( + "neo4j waiting %s seconds before automatically trying again.", + wait_seconds[num_tries], + ) + time.sleep(wait_seconds[num_tries]) + else: + logging.info("The connection with Neo4j db is validated") + connection_success = True + break + logging.info( + "Tried %s times to create connection with Neo4j with final success:%s", + num_tries, + connection_success, + ) + + def save_graph_to_neo4j(self, graph_to_load: str | nx.Graph) -> None: + + try: + """_summary_ + the Function load a networkx graph (or the json file) and create a corresponding neo4j graph + """ + + if graph_to_load == "": + # Create the Karate Club graph using NetworkX + G = nx.karate_club_graph() + logging.info("ne4j use default graph") + create_undirected = True + + else: + + if isinstance(graph_to_load, str): + # To read the graph from file + with open(graph_to_load, "r") as f: + G = nx.node_link_graph(json.load(f)) + logging.info( + "ne4j graph correctly loaded from file:%s", graph_to_load + ) + + else: + G = graph_to_load + + create_undirected = not ( + G.is_directed() + ) # retrieve direct property from graph itself + + # Connect to Neo4j + + driver = GraphDatabase.driver(self.uri, auth=(self.user, self.password)) + + def create_graph(tx, create_undirected: bool) -> None: + + # Create nodes + for node in G.nodes(data=True): + + node_type = node[1].get( + "type", "Unknown" + ) # use the "type" feature to create node type and the other features as standard features + + # dictionary with all properties + node_properties = node[ + 1 + ] # the passed properties (also the "type" attribute is inside) + node_properties["id"] = node[ + 0 + ] # the id is not passed as property (is required to add the links) + + query = f"CREATE (n:{node_type} $props)" + tx.run(query, props=node_properties) + + # Create edges + for edge in G.edges(data=True): + + if isinstance(edge[0], int): + id_source = "{id:" + str(edge[0]) + "}" + else: + id_source = "{id:'" + str(edge[0]) + "'}" + + if isinstance(edge[1], int): + id_target = "{id:" + str(edge[1]) + "}" + else: + id_target = "{id:'" + str(edge[1]) + "'}" + + edge_type = edge[2].get( + "type", "Unknown" + ) # use the "type" feature to create node type and the other features as standard features + node_type_source = G.nodes[edge[0]].get( + "type", "Unknown" + ) # get the node type from the link itself + node_type_target = G.nodes[edge[1]].get("type", "Unknown") + + edge_properties = edge[ + 2 + ] # the passed properties (also the "type" attribute is inside) + + query = ( + """ + MATCH (a:""" + + node_type_source + + id_source + + """), (b:""" + + node_type_target + + id_target + + """) + CREATE (a)-[:""" + + edge_type + + """ $props]->(b) + """ + ) + + tx.run(query, props=edge_properties) + + if ( + create_undirected + ): # simulate Undirected Graph (double edge direction) NB. the edge type could be different from the other direction TBD + + query = ( + """ + MATCH (a:""" + + node_type_target + + id_target + + """), (b:""" + + node_type_source + + id_source + + """) + CREATE (a)-[:""" + + edge_type + + """ $props]->(b) + """ + ) + + tx.run(query, props=edge_properties) + + # Run the transaction to create the graph + with driver.session(database=self.database) as session: + session.execute_write(create_graph, create_undirected) + + except Exception as e: + logging.error("Problems saving graph to neo4j db:%s", e) + raise neo4j_exception("Problems saving graph to neo4j db:%s", e) + else: + # Close the driver connection + driver.close() + + def delete_graph_from_neo4j(self) -> None: + + try: + # Connect to Neo4j + driver = GraphDatabase.driver(self.uri, auth=(self.user, self.password)) + + def delete_graph(tx) -> None: + query = f"MATCH (n) DETACH DELETE n" + tx.run(query) + + # Run the transaction to create the graph + with driver.session(database=self.database) as session: + session.execute_write(delete_graph) + + except Exception as e: + logging.error("Problems deleting graph from neo4j db:%s", e) + raise neo4j_exception("Problems deleting graph from neo4j db:%s", e) + else: + # Close the driver connection + driver.close() + + def count_nodes_neo4j(self) -> int: + + try: + result = 0 + # Connect to Neo4j + driver = GraphDatabase.driver(self.uri, auth=(self.user, self.password)) + + def count_nodes(tx): + result = tx.run("MATCH (n) RETURN count(n) AS numberOfNodes") + return result.single()["numberOfNodes"] + + # Count the nodes + with driver.session(database=self.database) as session: + result = session.read_transaction(count_nodes) + + except Exception as e: + logging.error("Problems counting nodes from neo4j db:%s", e) + raise neo4j_exception("Problems counting nodes from neo4j db:%s", e) + + else: + # Close the driver connection + driver.close() + return result + + def count_edges_neo4j(self) -> int: + + try: + result = 0 + # Connect to Neo4j + driver = GraphDatabase.driver(self.uri, auth=(self.user, self.password)) + + def count_edges(tx): + result = tx.run("MATCH ()-[r]->()RETURN count(r) AS numberOfEdges") + return result.single()["numberOfEdges"] + + # Count the nodes + with driver.session(database=self.database) as session: + result = session.read_transaction(count_edges) + + except Exception as e: + logging.error("Problems counting edges from neo4j db:%s", e) + raise neo4j_exception("Problems counting edges from neo4j db:%s", e) + + else: + # Close the driver connection + driver.close() + return result + + def query_to_neo4j(self, passed_query: str) -> list: + + try: + results = [] + # Connect to Neo4j + driver = GraphDatabase.driver(self.uri, auth=(self.user, self.password)) + + # only read cmd allowed + if "CREATE" in passed_query.upper(): + logging.warning("The NEO4j query contains CREATE: skipped") + raise Exception("The NEO4j query contains CREATE: skipped") + elif "DELETE" in passed_query.upper(): + logging.warning("The NEO4j query contains DELETE: skipped") + raise Exception("The NEO4j query contains DELETE: skipped") + + def query_graph(tx, passed_query) -> list: + + # results = list(tx.run(passed_query)) + results = tx.run(passed_query) + + # Convert the result to a list of dictionaries + results_list = [ + record.data() for record in results + ] # record.data() method is only capturing the top-level structure without delving into the properties of the relationship. use for key, value in record.items(): instead + + return results_list + + with driver.session(database=self.database) as session: + + results = session.read_transaction( + query_graph, passed_query + ) # only read cmd allowed + + except Exception as e: + logging.error("Problems quering graph from neo4j db:%s", e) + raise neo4j_exception("Problems quering graph from neo4j db:%s", e) + + else: + # Close the driver connection + driver.close() + return results diff --git a/scripts/costruzione_grafo/neo4j_management/dependences/utils/__pycache__/utils.cpython-311.pyc b/scripts/costruzione_grafo/neo4j_management/dependences/utils/__pycache__/utils.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14151b218e0a068d4877f8d5ef4901fa6817b67c GIT binary patch literal 8356 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 +2026-06-18 15:49:31,711 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-18 15:49:31,712 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 15:49:31,714 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 15:49:31,714 INFO (MainThread) neo4j connection num_tries:0 +2026-06-18 15:49:31,715 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-18 15:49:32,715 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 15:49:32,715 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 15:49:32,715 INFO (MainThread) neo4j connection num_tries:1 +2026-06-18 15:49:32,715 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-18 15:49:34,718 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 15:49:34,718 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 15:49:34,718 INFO (MainThread) neo4j connection num_tries:2 +2026-06-18 15:49:34,718 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-18 15:49:38,719 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-18 15:49:38,720 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='graph.json') +2026-06-18 15:51:35,020 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-18 15:51:35,020 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-18 15:51:35,020 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 15:51:35,022 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 15:51:35,022 INFO (MainThread) neo4j connection num_tries:0 +2026-06-18 15:51:35,023 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-18 15:51:36,024 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 15:51:36,025 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 15:51:36,025 INFO (MainThread) neo4j connection num_tries:1 +2026-06-18 15:51:36,025 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-18 15:51:38,027 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 15:51:38,027 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 15:51:38,027 INFO (MainThread) neo4j connection num_tries:2 +2026-06-18 15:51:38,028 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-18 15:51:42,029 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-18 15:51:42,029 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='graph.json') +2026-06-18 15:51:42,029 INFO (MainThread) populate graph from a pre-existing one +2026-06-18 15:51:42,041 ERROR (MainThread) key error exception:'accessibility_graph' +2026-06-18 15:51:42,042 ERROR (MainThread) exception:Graph key-name error exception:'accessibility_graph' +2026-06-18 15:51:42,042 INFO (MainThread) saving graph to neo4j... +2026-06-18 15:51:57,269 INFO (MainThread) graph saved to neo4j +2026-06-18 15:51:57,269 INFO (MainThread) graph accessibility_graph correctly created +2026-06-18 16:02:53,105 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-18 16:02:53,106 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-18 16:02:53,106 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:02:53,108 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:02:53,108 INFO (MainThread) neo4j connection num_tries:0 +2026-06-18 16:02:53,109 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-18 16:02:54,111 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:02:54,111 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:02:54,111 INFO (MainThread) neo4j connection num_tries:1 +2026-06-18 16:02:54,112 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-18 16:02:56,113 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:02:56,114 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:02:56,114 INFO (MainThread) neo4j connection num_tries:2 +2026-06-18 16:02:56,114 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-18 16:03:00,116 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-18 16:03:00,116 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='graph.json') +2026-06-18 16:03:00,116 INFO (MainThread) populate graph from a pre-existing one +2026-06-18 16:03:00,123 ERROR (MainThread) key error exception:'accessibility_graph' +2026-06-18 16:03:00,124 ERROR (MainThread) exception:Graph key-name error exception:'accessibility_graph' +2026-06-18 16:03:00,124 INFO (MainThread) saving graph to neo4j... +2026-06-18 16:03:04,215 INFO (MainThread) graph saved to neo4j +2026-06-18 16:03:04,215 INFO (MainThread) graph accessibility_graph correctly created +2026-06-18 16:05:43,986 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-18 16:05:43,986 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-18 16:05:43,987 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:05:43,988 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:05:43,988 INFO (MainThread) neo4j connection num_tries:0 +2026-06-18 16:05:43,989 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-18 16:05:44,990 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:05:44,991 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:05:44,991 INFO (MainThread) neo4j connection num_tries:1 +2026-06-18 16:05:44,991 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-18 16:05:46,993 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:05:46,993 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:05:46,994 INFO (MainThread) neo4j connection num_tries:2 +2026-06-18 16:05:46,994 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-18 16:05:50,995 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-18 16:05:50,995 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph.json', save_to_neo4j=True, from_graph='graph.json') +2026-06-18 16:05:50,996 INFO (MainThread) populate graph from a pre-existing one +2026-06-18 16:05:51,012 ERROR (MainThread) key error exception:'accessibility_graph.json' +2026-06-18 16:05:51,012 ERROR (MainThread) exception:Graph key-name error exception:'accessibility_graph.json' +2026-06-18 16:05:51,012 INFO (MainThread) saving graph to neo4j... +2026-06-18 16:05:54,903 INFO (MainThread) graph saved to neo4j +2026-06-18 16:05:54,904 INFO (MainThread) graph accessibility_graph.json correctly created +2026-06-18 16:10:41,831 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-18 16:10:41,832 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-18 16:10:41,832 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:10:41,834 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:10:41,834 INFO (MainThread) neo4j connection num_tries:0 +2026-06-18 16:10:41,834 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-18 16:10:42,837 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:10:42,837 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:10:42,838 INFO (MainThread) neo4j connection num_tries:1 +2026-06-18 16:10:42,838 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-18 16:10:44,839 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:10:44,839 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:10:44,840 INFO (MainThread) neo4j connection num_tries:2 +2026-06-18 16:10:44,840 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-18 16:10:48,841 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-18 16:10:48,841 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='graph.json') +2026-06-18 16:10:48,842 INFO (MainThread) populate graph from a pre-existing one +2026-06-18 16:10:48,908 INFO (MainThread) saving graph to neo4j... +2026-06-18 16:10:52,256 INFO (MainThread) graph saved to neo4j +2026-06-18 16:10:52,256 INFO (MainThread) graph accessibility_graph correctly created +2026-06-18 16:17:40,681 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-18 16:17:40,682 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-18 16:17:40,682 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:17:40,685 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:17:40,685 INFO (MainThread) neo4j connection num_tries:0 +2026-06-18 16:17:40,685 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-18 16:17:41,686 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:17:41,686 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:17:41,686 INFO (MainThread) neo4j connection num_tries:1 +2026-06-18 16:17:41,686 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-18 16:17:43,689 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:17:43,689 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:17:43,689 INFO (MainThread) neo4j connection num_tries:2 +2026-06-18 16:17:43,689 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-18 16:17:47,691 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-18 16:17:47,691 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='graph.json') +2026-06-18 16:17:47,691 INFO (MainThread) populate graph from a pre-existing one +2026-06-18 16:17:47,756 INFO (MainThread) saving graph to neo4j... +2026-06-18 16:17:50,786 INFO (MainThread) graph saved to neo4j +2026-06-18 16:17:50,786 INFO (MainThread) graph accessibility_graph correctly created +2026-06-18 16:27:41,322 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-18 16:27:41,322 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-18 16:27:41,323 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:27:41,328 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:27:41,328 INFO (MainThread) neo4j connection num_tries:0 +2026-06-18 16:27:41,328 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-18 16:27:42,330 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:27:42,330 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:27:42,330 INFO (MainThread) neo4j connection num_tries:1 +2026-06-18 16:27:42,331 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-18 16:27:44,331 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:27:44,331 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:27:44,331 INFO (MainThread) neo4j connection num_tries:2 +2026-06-18 16:27:44,331 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-18 16:27:48,333 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-18 16:27:48,333 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='graph.json') +2026-06-18 16:27:48,333 INFO (MainThread) populate graph from a pre-existing one +2026-06-18 16:27:48,402 INFO (MainThread) saving graph to neo4j... +2026-06-18 16:27:59,845 INFO (MainThread) graph saved to neo4j +2026-06-18 16:27:59,846 INFO (MainThread) graph accessibility_graph correctly created +2026-06-18 16:41:07,811 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-18 16:41:07,812 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-18 16:41:07,812 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:41:07,814 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:41:07,814 INFO (MainThread) neo4j connection num_tries:0 +2026-06-18 16:41:07,815 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-18 16:41:08,816 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:41:08,816 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:41:08,817 INFO (MainThread) neo4j connection num_tries:1 +2026-06-18 16:41:08,817 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-18 16:41:10,819 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-18 16:41:10,819 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-18 16:41:10,819 INFO (MainThread) neo4j connection num_tries:2 +2026-06-18 16:41:10,819 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-18 16:41:14,820 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-18 16:41:14,820 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='graph.json') +2026-06-18 16:41:14,821 INFO (MainThread) populate graph from a pre-existing one +2026-06-18 16:41:14,905 INFO (MainThread) saving graph to neo4j... +2026-06-18 16:41:25,898 INFO (MainThread) graph saved to neo4j +2026-06-18 16:41:25,898 INFO (MainThread) graph accessibility_graph correctly created +2026-06-19 13:44:09,295 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-19 13:44:09,296 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-19 13:44:09,296 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-19 13:44:09,298 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-19 13:44:09,298 INFO (MainThread) neo4j connection num_tries:0 +2026-06-19 13:44:09,298 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-19 13:44:10,300 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-19 13:44:10,301 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-19 13:44:10,301 INFO (MainThread) neo4j connection num_tries:1 +2026-06-19 13:44:10,301 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-19 13:44:12,302 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-19 13:44:12,303 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-19 13:44:12,303 INFO (MainThread) neo4j connection num_tries:2 +2026-06-19 13:44:12,303 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-19 13:44:16,305 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-19 13:44:16,305 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='graph.json') +2026-06-19 13:44:16,305 INFO (MainThread) populate graph from a pre-existing one +2026-06-19 13:44:16,355 INFO (MainThread) saving graph to neo4j... +2026-06-19 13:44:40,038 INFO (MainThread) graph saved to neo4j +2026-06-19 13:44:40,038 INFO (MainThread) graph accessibility_graph correctly created +2026-06-20 09:14:34,331 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-20 09:14:34,331 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-20 09:14:34,332 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 09:14:34,334 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 09:14:34,334 INFO (MainThread) neo4j connection num_tries:0 +2026-06-20 09:14:34,334 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-20 09:14:35,337 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 09:14:35,338 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 09:14:35,338 INFO (MainThread) neo4j connection num_tries:1 +2026-06-20 09:14:35,338 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-20 09:14:37,340 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 09:14:37,340 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 09:14:37,341 INFO (MainThread) neo4j connection num_tries:2 +2026-06-20 09:14:37,341 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-20 09:14:41,343 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-20 09:14:41,343 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='../graph.json') +2026-06-20 09:14:41,344 INFO (MainThread) populate graph from a pre-existing one +2026-06-20 09:14:41,418 INFO (MainThread) saving graph to neo4j... +2026-06-20 09:15:22,264 INFO (MainThread) graph saved to neo4j +2026-06-20 09:15:22,265 INFO (MainThread) graph accessibility_graph correctly created +2026-06-20 09:16:58,519 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-20 09:16:58,519 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-20 09:16:58,520 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 09:16:58,523 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 09:16:58,523 INFO (MainThread) neo4j connection num_tries:0 +2026-06-20 09:16:58,523 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-20 09:16:59,533 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 09:16:59,533 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 09:16:59,533 INFO (MainThread) neo4j connection num_tries:1 +2026-06-20 09:16:59,533 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-20 09:17:01,535 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 09:17:01,535 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 09:17:01,535 INFO (MainThread) neo4j connection num_tries:2 +2026-06-20 09:17:01,535 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-20 09:17:05,537 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-20 09:17:05,537 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='../graph.json') +2026-06-20 09:17:05,539 INFO (MainThread) populate graph from a pre-existing one +2026-06-20 09:17:05,619 INFO (MainThread) saving graph to neo4j... +2026-06-20 09:17:30,646 INFO (MainThread) graph saved to neo4j +2026-06-20 09:17:30,646 INFO (MainThread) graph accessibility_graph correctly created +2026-06-20 09:49:00,961 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-20 09:49:00,961 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-20 09:49:00,962 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 09:49:00,964 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 09:49:00,964 INFO (MainThread) neo4j connection num_tries:0 +2026-06-20 09:49:00,964 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-20 09:49:01,965 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 09:49:01,966 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 09:49:01,966 INFO (MainThread) neo4j connection num_tries:1 +2026-06-20 09:49:01,966 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-20 09:49:03,966 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 09:49:03,966 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 09:49:03,967 INFO (MainThread) neo4j connection num_tries:2 +2026-06-20 09:49:03,967 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-20 09:49:07,968 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-20 09:49:07,968 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='../graph.json') +2026-06-20 09:49:07,968 INFO (MainThread) populate graph from a pre-existing one +2026-06-20 09:49:08,029 INFO (MainThread) saving graph to neo4j... +2026-06-20 09:49:30,129 INFO (MainThread) graph saved to neo4j +2026-06-20 09:49:30,130 INFO (MainThread) graph accessibility_graph correctly created +2026-06-20 13:34:35,193 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-20 13:34:35,194 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-20 13:34:35,195 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 13:34:35,197 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 13:34:35,197 INFO (MainThread) neo4j connection num_tries:0 +2026-06-20 13:34:35,197 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-20 13:34:36,198 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 13:34:36,198 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 13:34:36,198 INFO (MainThread) neo4j connection num_tries:1 +2026-06-20 13:34:36,198 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-20 13:34:38,199 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 13:34:38,199 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 13:34:38,199 INFO (MainThread) neo4j connection num_tries:2 +2026-06-20 13:34:38,199 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-20 13:34:42,201 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-20 13:34:42,201 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='../graph.json') +2026-06-20 13:34:42,201 INFO (MainThread) populate graph from a pre-existing one +2026-06-20 13:34:42,273 INFO (MainThread) saving graph to neo4j... +2026-06-20 13:34:59,859 INFO (MainThread) graph saved to neo4j +2026-06-20 13:34:59,859 INFO (MainThread) graph accessibility_graph correctly created +2026-06-20 15:31:25,130 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-20 15:31:25,130 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-20 15:31:25,130 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 15:31:25,133 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 15:31:25,133 INFO (MainThread) neo4j connection num_tries:0 +2026-06-20 15:31:25,133 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-20 15:31:26,140 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 15:31:26,140 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 15:31:26,140 INFO (MainThread) neo4j connection num_tries:1 +2026-06-20 15:31:26,140 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-20 15:31:28,258 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 15:31:28,258 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 15:31:28,258 INFO (MainThread) neo4j connection num_tries:2 +2026-06-20 15:31:28,258 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-20 15:31:32,260 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-20 15:31:32,260 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='../graph.json') +2026-06-20 15:31:32,260 INFO (MainThread) populate graph from a pre-existing one +2026-06-20 15:31:32,328 INFO (MainThread) saving graph to neo4j... +2026-06-20 15:31:47,530 INFO (MainThread) graph saved to neo4j +2026-06-20 15:31:47,530 INFO (MainThread) graph accessibility_graph correctly created +2026-06-20 15:56:18,557 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-20 15:56:18,558 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-20 15:56:18,558 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 15:56:18,560 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 15:56:18,561 INFO (MainThread) neo4j connection num_tries:0 +2026-06-20 15:56:18,561 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-20 15:56:19,562 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 15:56:19,563 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 15:56:19,563 INFO (MainThread) neo4j connection num_tries:1 +2026-06-20 15:56:19,563 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-20 15:56:21,563 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 15:56:21,563 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 15:56:21,563 INFO (MainThread) neo4j connection num_tries:2 +2026-06-20 15:56:21,563 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-20 15:56:25,564 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-20 15:56:25,564 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='../graph.json') +2026-06-20 15:56:25,564 INFO (MainThread) populate graph from a pre-existing one +2026-06-20 15:56:25,615 INFO (MainThread) saving graph to neo4j... +2026-06-20 15:56:38,180 INFO (MainThread) graph saved to neo4j +2026-06-20 15:56:38,181 INFO (MainThread) graph accessibility_graph correctly created +2026-06-20 16:18:36,059 INFO (MainThread) ### Knowledge Graph Service is starting with params: +2026-06-20 16:18:36,059 INFO (MainThread) try to connect to Neo4j for init testing purpose +2026-06-20 16:18:36,060 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 16:18:36,063 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 16:18:36,063 INFO (MainThread) neo4j connection num_tries:0 +2026-06-20 16:18:36,063 INFO (MainThread) neo4j waiting 1 seconds before automatically trying again. +2026-06-20 16:18:37,064 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 16:18:37,064 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 16:18:37,064 INFO (MainThread) neo4j connection num_tries:1 +2026-06-20 16:18:37,064 INFO (MainThread) neo4j waiting 2 seconds before automatically trying again. +2026-06-20 16:18:39,066 ERROR (MainThread) Problems counting nodes from neo4j db:'Session' object has no attribute 'read_transaction' +2026-06-20 16:18:39,066 ERROR (MainThread) Problem with the Neo4j connection:('Problems counting nodes from neo4j db:%s', AttributeError("'Session' object has no attribute 'read_transaction'")) +2026-06-20 16:18:39,066 INFO (MainThread) neo4j connection num_tries:2 +2026-06-20 16:18:39,066 INFO (MainThread) neo4j waiting 4 seconds before automatically trying again. +2026-06-20 16:18:43,100 INFO (MainThread) Tried 2 times to create connection with Neo4j with final success:False +2026-06-20 16:18:43,100 INFO (MainThread) kg manager started with cli args:Namespace(graph_type='directed', graph_name='accessibility_graph', save_to_neo4j=True, from_graph='../graph.json') +2026-06-20 16:18:43,101 INFO (MainThread) populate graph from a pre-existing one +2026-06-20 16:18:43,531 INFO (MainThread) saving graph to neo4j... +2026-06-20 16:18:54,946 INFO (MainThread) graph saved to neo4j +2026-06-20 16:18:54,946 INFO (MainThread) graph accessibility_graph correctly created diff --git a/scripts/costruzione_grafo/neo4j_management/persistence/accessibility_graph.json b/scripts/costruzione_grafo/neo4j_management/persistence/accessibility_graph.json new file mode 100644 index 0000000..cfa7943 --- /dev/null +++ b/scripts/costruzione_grafo/neo4j_management/persistence/accessibility_graph.json @@ -0,0 +1 @@ +{"directed": true, "multigraph": false, "graph": {}, "nodes": [{"node_id": "2", "ignored": false, "role": "RootWebArea", "chrome_role": 144, "name": "Bandi di concorso - Regione Toscana", "backend_dom_node_id": 2, "frame_id": "BC9891C8760DFBA000DA4D64E8F6CBC0", "type": "RootWebArea", "aria_focusable": true, "aria_focused": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/bandi-di-concorso", "id": "2"}, {"node_id": "36", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 36, "type": "none", "ignored_reasons": "uninteresting", "id": "36"}, {"node_id": "104", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 104, "type": "generic", "pw_role": "generic", "pw_depth": 0, "pw_box": [0, 0, 1920, 2106], "pw_active ref": "e1", "id": "104"}, {"node_id": "105", "ignored": false, "role": "banner", "chrome_role": 94, "name": "Header del sito", "backend_dom_node_id": 105, "type": "banner", "pw_role": "banner", "pw_name": "Header del sito", "pw_depth": 1, "pw_box": [0, 0, 1920, 183], "pw_ref": "e2", "id": "105"}, {"node_id": "495", "ignored": false, "role": "main", "chrome_role": 118, "backend_dom_node_id": 495, "type": "main", "pw_role": "main", "pw_depth": 1, "pw_box": [0, 183, 1920, 1570], "pw_ref": "e76", "id": "495"}, {"node_id": "668", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 668, "type": "generic", "id": "668"}, {"node_id": "723", "ignored": false, "role": "contentinfo", "chrome_role": 85, "backend_dom_node_id": 723, "type": "contentinfo", "pw_role": "contentinfo", "pw_depth": 1, "pw_box": [0, 1753, 1920, 354], "pw_ref": "e230", "id": "723"}, {"node_id": "811", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 811, "type": "generic", "id": "811"}, {"node_id": "106", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 106, "type": "none", "ignored_reasons": "uninteresting", "id": "106"}, {"node_id": "107", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 107, "type": "none", "ignored_reasons": "uninteresting", "id": "107"}, {"node_id": "108", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 108, "type": "none", "ignored_reasons": "uninteresting", "id": "108"}, {"node_id": "109", "ignored": false, "role": "generic", "chrome_role": 88, "name": "Secondaria", "backend_dom_node_id": 109, "type": "generic", "pw_role": "generic", "pw_name": "Secondaria", "pw_depth": 3, "pw_box": [192, 10, 561, 37], "pw_ref": "e6", "id": "109"}, {"node_id": "121", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 121, "type": "none", "ignored_reasons": "uninteresting", "id": "121"}, {"node_id": "122", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 122, "type": "none", "ignored_reasons": "uninteresting", "id": "122"}, {"node_id": "123", "ignored": false, "role": "list", "chrome_role": 111, "backend_dom_node_id": 123, "type": "list", "pw_role": "list", "pw_depth": 4, "pw_box": [192, 10, 561, 37], "pw_ref": "e7", "id": "123"}, {"node_id": "146", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 146, "type": "none", "ignored_reasons": "uninteresting", "id": "146"}, {"node_id": "9", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 9, "type": "none", "ignored_reasons": "emptyAlt", "id": "9"}, {"node_id": "147", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 147, "type": "none", "ignored_reasons": "uninteresting", "id": "147"}, {"node_id": "148", "ignored": false, "role": "link", "chrome_role": 110, "name": "Toscana Notizie", "backend_dom_node_id": 148, "type": "link", "aria_focusable": true, "aria_url": "https://www.toscana-notizie.it/", "pw_role": "link", "pw_name": "Toscana Notizie", "pw_depth": 4, "pw_box": [1517, 14, 147, 28], "pw_ref": "e40 cursor=pointer", "id": "148"}, {"node_id": "149", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 149, "type": "generic", "id": "149"}, {"node_id": "193", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 193, "type": "none", "ignored_reasons": "uninteresting", "id": "193"}, {"node_id": "194", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 194, "type": "none", "ignored_reasons": "uninteresting", "id": "194"}, {"node_id": "195", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 195, "type": "none", "ignored_reasons": "uninteresting", "id": "195"}, {"node_id": "196", "ignored": false, "role": "link", "chrome_role": 110, "name": "Regione Toscana", "backend_dom_node_id": 196, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/", "pw_role": "link", "pw_name": "Regione Toscana", "pw_depth": 3, "pw_box": [192, 72, 326, 95], "pw_ref": "e50 cursor=pointer", "id": "196"}, {"node_id": "197", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 197, "type": "none", "ignored_reasons": "uninteresting", "id": "197"}, {"node_id": "198", "ignored": false, "role": "generic", "chrome_role": 88, "name": "Principale", "backend_dom_node_id": 198, "type": "generic", "pw_role": "generic", "pw_name": "Principale", "pw_depth": 3, "pw_box": [518, 92, 1210, 56], "pw_ref": "e53", "id": "198"}, {"node_id": "497", "ignored": false, "role": "main", "chrome_role": 118, "backend_dom_node_id": 497, "type": "main", "id": "497"}, {"node_id": "657", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 657, "type": "generic", "id": "657"}, {"node_id": "669", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 669, "type": "generic", "id": "669"}, {"node_id": "724", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 724, "type": "generic", "id": "724"}, {"node_id": "785", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 785, "type": "none", "ignored_reasons": "uninteresting", "id": "785"}, {"node_id": "786", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 786, "type": "none", "ignored_reasons": "uninteresting", "id": "786"}, {"node_id": "787", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 787, "type": "none", "ignored_reasons": "uninteresting", "id": "787"}, {"node_id": "788", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 788, "type": "none", "ignored_reasons": "uninteresting", "id": "788"}, {"node_id": "789", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 789, "type": "generic", "id": "789"}, {"node_id": "790", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 790, "type": "none", "ignored_reasons": "uninteresting", "id": "790"}, {"node_id": "791", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 791, "type": "none", "ignored_reasons": "uninteresting", "id": "791"}, {"node_id": "3", "ignored": false, "role": "image", "chrome_role": 99, "name": "Regione Toscana", "backend_dom_node_id": 3, "type": "image", "aria_url": "https://www.regione.toscana.it/o/regione-toscana-theme/images/regione-toscana-logo-footer.png", "id": "3"}, {"node_id": "110", "ignored": false, "role": "list", "chrome_role": 111, "backend_dom_node_id": 110, "type": "list", "id": "110"}, {"node_id": "124", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 124, "type": "listitem", "aria_level": 1.0, "pw_role": "listitem", "pw_depth": 5, "pw_box": [192, 10, 49, 37], "pw_ref": "e8", "id": "124"}, {"node_id": "131", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 131, "type": "listitem", "aria_level": 1.0, "id": "131"}, {"node_id": "139", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 139, "type": "listitem", "aria_level": 1.0, "id": "139"}, {"node_id": "12", "ignored": false, "role": "image", "chrome_role": 99, "name": "Toscana Notizie", "backend_dom_node_id": 12, "type": "image", "aria_url": "https://www.regione.toscana.it/o/regione-toscana-theme/images/toscana-notizie.png", "id": "12"}, {"node_id": "150", "ignored": false, "role": "button", "chrome_role": 9, "name": "Cerca nel sito - apri la modale", "backend_dom_node_id": 150, "type": "button", "aria_invalid": "false", "aria_focusable": true, "pw_role": "button", "pw_name": "Cerca nel sito - apri la modale", "pw_depth": 4, "pw_box": [1688, 8, 40, 40], "pw_ref": "e43 cursor=pointer", "id": "150"}, {"node_id": "160", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 160, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "160"}, {"node_id": "827", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 827, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "827"}, {"node_id": "165", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 165, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "165"}, {"node_id": "176", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 176, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "176"}, {"node_id": "829", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 829, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "829"}, {"node_id": "180", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 180, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "180"}, {"node_id": "183", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 183, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "183"}, {"node_id": "184", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 184, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "184"}, {"node_id": "189", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 189, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "189"}, {"node_id": "11", "ignored": false, "role": "image", "chrome_role": 99, "name": "Regione Toscana", "backend_dom_node_id": 11, "type": "image", "aria_url": "https://www.regione.toscana.it/o/regione-toscana-theme/images/logo-regione.png", "id": "11"}, {"node_id": "202", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 202, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "202"}, {"node_id": "206", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 206, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "206"}, {"node_id": "20", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 20, "type": "generic", "id": "20"}, {"node_id": "498", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 498, "type": "none", "ignored_reasons": "uninteresting", "id": "498"}, {"node_id": "499", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 499, "type": "generic", "id": "499"}, {"node_id": "519", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 519, "type": "none", "ignored_reasons": "uninteresting", "id": "519"}, {"node_id": "520", "ignored": false, "role": "generic", "chrome_role": 211, "backend_dom_node_id": 520, "type": "generic", "id": "520"}, {"node_id": "658", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 658, "type": "generic", "id": "658"}, {"node_id": "35", "ignored": false, "role": "button", "chrome_role": 9, "name": "Preferenze dei cookie", "backend_dom_node_id": 35, "type": "button", "aria_focusable": true, "pw_role": "button", "pw_name": "Preferenze dei cookie", "pw_depth": 2, "pw_box": [1718, 1042, 187, 38], "pw_ref": "e220 cursor=pointer", "id": "35"}, {"node_id": "670", "ignored": false, "role": "dialog", "chrome_role": 35, "name": "Usiamo i cookie", "description": "Questo sito web utilizza cookie essenziali per garantire il suo corretto funzionamento ed eventuali cookie di tracciamento per capire come interagisci con esso. Questi ultimi saranno impostati solo dopo il consenso. Fammi scegliere", "backend_dom_node_id": 670, "type": "dialog", "aria_modal": true, "aria_describedby": "c-txt", "aria_labelledby": ["c-ttl"], "pw_role": "dialog", "pw_name": "Usiamo i cookie", "pw_depth": 1, "pw_box": [1513, 796, 387, 264], "pw_ref": "e221", "id": "670"}, {"node_id": "687", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 687, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "687"}, {"node_id": "934", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 934, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "934"}, {"node_id": "689", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 689, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "689"}, {"node_id": "698", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 698, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "698"}, {"node_id": "699", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 699, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "699"}, {"node_id": "700", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 700, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "700"}, {"node_id": "701", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 701, "type": "none", "ignored_reasons": "ariaHiddenElement", "id": "701"}, {"node_id": "702", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 702, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "702"}, {"node_id": "703", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 703, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "703"}, {"node_id": "704", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 704, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "704"}, {"node_id": "938", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 938, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "938"}, {"node_id": "709", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 709, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "709"}, {"node_id": "710", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 710, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "710"}, {"node_id": "711", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 711, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "711"}, {"node_id": "712", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 712, "type": "none", "ignored_reasons": "ariaHiddenElement", "id": "712"}, {"node_id": "713", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 713, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "713"}, {"node_id": "714", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 714, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "714"}, {"node_id": "715", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 715, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "715"}, {"node_id": "941", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 941, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "941"}, {"node_id": "725", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 725, "type": "generic", "id": "725"}, {"node_id": "726", "ignored": false, "role": "generic", "chrome_role": 211, "backend_dom_node_id": 726, "type": "generic", "id": "726"}, {"node_id": "973", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Partita IVA 01386030488", "backend_dom_node_id": 973, "type": "StaticText", "id": "973"}, {"node_id": "111", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 111, "type": "listitem", "aria_level": 1.0, "id": "111"}, {"node_id": "113", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 113, "type": "listitem", "aria_level": 1.0, "id": "113"}, {"node_id": "115", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 115, "type": "listitem", "aria_level": 1.0, "id": "115"}, {"node_id": "16", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 16, "type": "listitem", "aria_level": 1.0, "id": "16"}, {"node_id": "118", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 118, "type": "listitem", "aria_level": 1.0, "id": "118"}, {"node_id": "18", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 18, "type": "listitem", "aria_level": 1.0, "id": "18"}, {"node_id": "125", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai al profilo Facebook di Regione Toscana", "backend_dom_node_id": 125, "type": "link", "aria_focusable": true, "aria_url": "https://www.facebook.com/regionetoscana.paginaufficiale/", "pw_role": "link", "pw_name": "Vai al profilo Facebook di Regione Toscana", "pw_depth": 6, "pw_box": [1325, 12, 32, 32], "pw_ref": "e24 cursor=pointer", "id": "125"}, {"node_id": "132", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai al profilo Instagram di Regione Toscana", "backend_dom_node_id": 132, "type": "link", "aria_focusable": true, "aria_url": "https://www.instagram.com/regionetoscana/?hl=en", "pw_role": "link", "pw_name": "Vai al profilo Instagram di Regione Toscana", "pw_depth": 6, "pw_box": [1373, 12, 32, 32], "pw_ref": "e29 cursor=pointer", "id": "132"}, {"node_id": "140", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai al profilo Youtube di Regione Toscana", "backend_dom_node_id": 140, "type": "link", "aria_focusable": true, "aria_url": "https://www.youtube.com/c/RegioneToscanaUfficiale", "pw_role": "link", "pw_name": "Vai al profilo Youtube di Regione Toscana", "pw_depth": 6, "pw_box": [1421, 12, 32, 32], "pw_ref": "e34 cursor=pointer", "id": "140"}, {"node_id": "151", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 151, "type": "none", "ignored_reasons": "uninteresting", "id": "151"}, {"node_id": "826", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Cerca nel sito - apri la modale", "backend_dom_node_id": 826, "type": "StaticText", "id": "826"}, {"node_id": "154", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 154, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "154"}, {"node_id": "209", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 209, "type": "none", "ignored_reasons": "uninteresting", "id": "209"}, {"node_id": "210", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 210, "type": "generic", "id": "210"}, {"node_id": "477", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 477, "type": "none", "ignored_reasons": "notRendered", "id": "477"}, {"node_id": "890", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 890, "type": "none", "ignored_reasons": "notRendered", "id": "890"}, {"node_id": "481", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 481, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "481"}, {"node_id": "484", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 484, "type": "none", "ignored_reasons": "notRendered", "id": "484"}, {"node_id": "485", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 485, "type": "none", "ignored_reasons": "notRendered", "id": "485"}, {"node_id": "490", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 490, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "490"}, {"node_id": "500", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 500, "type": "generic", "id": "500"}, {"node_id": "521", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 521, "type": "none", "ignored_reasons": "uninteresting", "id": "521"}, {"node_id": "522", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 522, "type": "generic", "id": "522"}, {"node_id": "14", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 14, "type": "generic", "id": "14"}, {"node_id": "927", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Preferenze dei cookie", "backend_dom_node_id": 927, "type": "StaticText", "id": "927"}, {"node_id": "671", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 671, "type": "generic", "id": "671"}, {"node_id": "727", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 727, "type": "none", "ignored_reasons": "uninteresting", "id": "727"}, {"node_id": "728", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 728, "type": "generic", "id": "728"}, {"node_id": "732", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 732, "type": "none", "ignored_reasons": "uninteresting", "id": "732"}, {"node_id": "733", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 733, "type": "none", "ignored_reasons": "uninteresting", "id": "733"}, {"node_id": "734", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 734, "type": "none", "ignored_reasons": "uninteresting", "id": "734"}, {"node_id": "735", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 735, "type": "none", "ignored_reasons": "uninteresting", "id": "735"}, {"node_id": "736", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 736, "type": "none", "ignored_reasons": "uninteresting", "id": "736"}, {"node_id": "737", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 737, "type": "none", "ignored_reasons": "uninteresting", "id": "737"}, {"node_id": "738", "ignored": false, "role": "heading", "chrome_role": 96, "name": "Siti collegati", "backend_dom_node_id": 738, "type": "heading", "aria_level": 2.0, "pw_role": "heading", "pw_name": "Siti collegati", "pw_depth": 4, "pw_box": [192, 1786, 1536, 22], "pw_level": 2, "pw_ref": "e240", "id": "738"}, {"node_id": "739", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 739, "type": "none", "ignored_reasons": "uninteresting", "id": "739"}, {"node_id": "740", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 740, "type": "none", "ignored_reasons": "uninteresting", "id": "740"}, {"node_id": "741", "ignored": false, "role": "link", "chrome_role": 110, "name": "Muoversi in Toscana", "backend_dom_node_id": 741, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/speciali/muoversi-in-toscana", "pw_role": "link", "pw_name": "Muoversi in Toscana", "pw_depth": 5, "pw_box": [192, 1831, 146, 38], "pw_ref": "e243 cursor=pointer", "id": "741"}, {"node_id": "742", "ignored": false, "role": "link", "chrome_role": 110, "name": "Toscana Accessibile", "backend_dom_node_id": 742, "type": "link", "aria_focusable": true, "aria_url": "http://www.toscana-accessibile.it/home", "pw_role": "link", "pw_name": "Toscana Accessibile", "pw_depth": 5, "pw_box": [386, 1840, 138, 21], "pw_ref": "e245 cursor=pointer", "id": "742"}, {"node_id": "749", "ignored": false, "role": "link", "chrome_role": 110, "name": "GiovaniS\u00ec", "backend_dom_node_id": 749, "type": "link", "aria_focusable": true, "aria_url": "https://giovanisi.it/", "pw_role": "link", "pw_name": "GiovaniS\u00ec", "pw_depth": 5, "pw_box": [572, 1836, 94, 28], "pw_ref": "e248 cursor=pointer", "id": "749"}, {"node_id": "750", "ignored": false, "role": "link", "chrome_role": 110, "name": "Toscana Digitale", "backend_dom_node_id": 750, "type": "link", "aria_focusable": true, "aria_url": "https://digitale.toscana.it/", "pw_role": "link", "pw_name": "Toscana Digitale", "pw_depth": 5, "pw_box": [714, 1838, 129, 24], "pw_ref": "e250 cursor=pointer", "id": "750"}, {"node_id": "751", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 751, "type": "none", "ignored_reasons": "uninteresting", "id": "751"}, {"node_id": "752", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 752, "type": "none", "ignored_reasons": "uninteresting", "id": "752"}, {"node_id": "753", "ignored": false, "role": "navigation", "chrome_role": 130, "name": "Contatti e utilit\u00e0", "backend_dom_node_id": 753, "type": "navigation", "pw_role": "navigation", "pw_name": "Contatti e utilit\u00e0", "pw_depth": 3, "pw_box": [176, 1901, 1552, 53], "pw_ref": "e254", "id": "753"}, {"node_id": "765", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 765, "type": "none", "ignored_reasons": "uninteresting", "id": "765"}, {"node_id": "766", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 766, "type": "none", "ignored_reasons": "uninteresting", "id": "766"}, {"node_id": "767", "ignored": false, "role": "navigation", "chrome_role": 130, "name": "Altre informazioni", "backend_dom_node_id": 767, "type": "navigation", "pw_role": "navigation", "pw_name": "Altre informazioni", "pw_depth": 3, "pw_box": [176, 1955, 1552, 85], "pw_ref": "e268", "id": "767"}, {"node_id": "-1000000085", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Partita IVA 01386030488", "type": "InlineTextBox", "id": "-1000000085"}, {"node_id": "813", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 813, "type": "ListMarker", "id": "813"}, {"node_id": "112", "ignored": false, "role": "link", "chrome_role": 110, "name": "Uffici", "description": "Vai alla pagina Uffici", "backend_dom_node_id": 112, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/uffici", "pw_role": "link", "pw_name": "Uffici", "pw_depth": 6, "pw_box": [192, 10, 49, 37], "pw_ref": "e9 cursor=pointer", "id": "112"}, {"node_id": "815", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 815, "type": "ListMarker", "id": "815"}, {"node_id": "114", "ignored": false, "role": "link", "chrome_role": 110, "name": "URP", "description": "Vai alla pagina URP", "backend_dom_node_id": 114, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/urp", "pw_role": "link", "pw_name": "URP", "pw_depth": 6, "pw_box": [249, 10, 43, 37], "pw_ref": "e11 cursor=pointer", "id": "114"}, {"node_id": "817", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 817, "type": "ListMarker", "id": "817"}, {"node_id": "116", "ignored": false, "role": "link", "chrome_role": 110, "name": "PEC", "description": "Vai alla pagina PEC", "backend_dom_node_id": 116, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/-/posta-elettronica-certificata-pec", "pw_role": "link", "pw_name": "PEC", "pw_depth": 6, "pw_box": [301, 10, 41, 37], "pw_ref": "e13 cursor=pointer", "id": "116"}, {"node_id": "819", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 819, "type": "ListMarker", "id": "819"}, {"node_id": "117", "ignored": false, "role": "link", "chrome_role": 110, "name": "Mappa del sito", "description": "Vai alla pagina Mappa del sito", "backend_dom_node_id": 117, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/mappa", "pw_role": "link", "pw_name": "Mappa del sito", "pw_depth": 6, "pw_box": [350, 10, 112, 37], "pw_ref": "e15 cursor=pointer", "id": "117"}, {"node_id": "820", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 820, "type": "ListMarker", "id": "820"}, {"node_id": "119", "ignored": false, "role": "link", "chrome_role": 110, "name": "Amministrazione trasparente", "description": "Vai alla pagina Amministrazione trasparente", "backend_dom_node_id": 119, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente", "pw_role": "link", "pw_name": "Amministrazione trasparente", "pw_depth": 6, "pw_box": [470, 10, 207, 37], "pw_ref": "e17 cursor=pointer", "id": "119"}, {"node_id": "822", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 822, "type": "ListMarker", "id": "822"}, {"node_id": "120", "ignored": false, "role": "link", "chrome_role": 110, "name": "Intranet", "description": "Vai alla pagina Intranet", "backend_dom_node_id": 120, "type": "link", "aria_focusable": true, "aria_url": "https://intranet.regione.toscana.it/", "pw_role": "link", "pw_name": "Intranet", "pw_depth": 6, "pw_box": [685, 10, 68, 37], "pw_ref": "e19 cursor=pointer", "id": "120"}, {"node_id": "126", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 126, "type": "none", "ignored_reasons": "uninteresting", "id": "126"}, {"node_id": "823", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Vai al profilo Facebook di Regione Toscana", "backend_dom_node_id": 823, "type": "StaticText", "id": "823"}, {"node_id": "129", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 129, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "129"}, {"node_id": "133", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 133, "type": "none", "ignored_reasons": "uninteresting", "id": "133"}, {"node_id": "824", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Vai al profilo Instagram di Regione Toscana", "backend_dom_node_id": 824, "type": "StaticText", "id": "824"}, {"node_id": "136", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 136, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "136"}, {"node_id": "141", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 141, "type": "none", "ignored_reasons": "uninteresting", "id": "141"}, {"node_id": "825", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Vai al profilo Youtube di Regione Toscana", "backend_dom_node_id": 825, "type": "StaticText", "id": "825"}, {"node_id": "144", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 144, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "144"}, {"node_id": "-1000000011", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Cerca nel sito - apri la modale", "type": "InlineTextBox", "id": "-1000000011"}, {"node_id": "211", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 211, "type": "generic", "id": "211"}, {"node_id": "212", "ignored": false, "role": "generic", "chrome_role": 211, "backend_dom_node_id": 212, "type": "generic", "id": "212"}, {"node_id": "501", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 501, "type": "generic", "id": "501"}, {"node_id": "523", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 523, "type": "generic", "id": "523"}, {"node_id": "621", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 621, "type": "generic", "id": "621"}, {"node_id": "-1000000060", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Preferenze dei cookie", "type": "InlineTextBox", "id": "-1000000060"}, {"node_id": "672", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 672, "type": "generic", "id": "672"}, {"node_id": "677", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 677, "type": "generic", "id": "677"}, {"node_id": "729", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 729, "type": "generic", "id": "729"}, {"node_id": "946", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Siti collegati", "backend_dom_node_id": 946, "type": "StaticText", "id": "946"}, {"node_id": "5", "ignored": false, "role": "image", "chrome_role": 99, "name": "Muoversi in Toscana", "backend_dom_node_id": 5, "type": "image", "aria_url": "https://www.regione.toscana.it/o/regione-toscana-theme/images/muoversi-in-toscana.png", "id": "5"}, {"node_id": "6", "ignored": false, "role": "image", "chrome_role": 99, "name": "Toscana Accessibile", "backend_dom_node_id": 6, "type": "image", "aria_url": "https://www.regione.toscana.it/documents/d/guest/toscana-accessibile-grey", "id": "6"}, {"node_id": "7", "ignored": false, "role": "image", "chrome_role": 99, "name": "GiovaniS\u00ec", "backend_dom_node_id": 7, "type": "image", "aria_url": "https://www.regione.toscana.it/o/regione-toscana-theme/images/giovanisi.png", "id": "7"}, {"node_id": "8", "ignored": false, "role": "image", "chrome_role": 99, "name": "Toscana Digitale", "backend_dom_node_id": 8, "type": "image", "aria_url": "https://www.regione.toscana.it/o/regione-toscana-theme/images/toscana-digitale.png", "id": "8"}, {"node_id": "754", "ignored": false, "role": "list", "chrome_role": 111, "backend_dom_node_id": 754, "type": "list", "id": "754"}, {"node_id": "768", "ignored": false, "role": "list", "chrome_role": 111, "backend_dom_node_id": 768, "type": "list", "id": "768"}, {"node_id": "814", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Uffici", "backend_dom_node_id": 814, "type": "StaticText", "id": "814"}, {"node_id": "816", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "URP", "backend_dom_node_id": 816, "type": "StaticText", "id": "816"}, {"node_id": "818", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "PEC", "backend_dom_node_id": 818, "type": "StaticText", "id": "818"}, {"node_id": "17", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Mappa del sito", "backend_dom_node_id": 17, "type": "StaticText", "id": "17"}, {"node_id": "821", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Amministrazione trasparente", "backend_dom_node_id": 821, "type": "StaticText", "id": "821"}, {"node_id": "19", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Intranet", "backend_dom_node_id": 19, "type": "StaticText", "id": "19"}, {"node_id": "-1000000008", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Vai al profilo Facebook di Regione Toscana", "type": "InlineTextBox", "id": "-1000000008"}, {"node_id": "-1000000009", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Vai al profilo Instagram di Regione Toscana", "type": "InlineTextBox", "id": "-1000000009"}, {"node_id": "-1000000010", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Vai al profilo Youtube di Regione Toscana", "type": "InlineTextBox", "id": "-1000000010"}, {"node_id": "213", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 213, "type": "none", "ignored_reasons": "uninteresting", "id": "213"}, {"node_id": "214", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 214, "type": "none", "ignored_reasons": "uninteresting", "id": "214"}, {"node_id": "215", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 215, "type": "none", "ignored_reasons": "uninteresting", "id": "215"}, {"node_id": "216", "ignored": false, "role": "navigation", "chrome_role": 130, "backend_dom_node_id": 216, "type": "navigation", "pw_role": "navigation", "pw_depth": 4, "pw_box": [919, 92, 809, 56], "pw_ref": "e61", "id": "216"}, {"node_id": "502", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 502, "type": "generic", "id": "502"}, {"node_id": "503", "ignored": false, "role": "generic", "chrome_role": 211, "backend_dom_node_id": 503, "type": "generic", "id": "503"}, {"node_id": "524", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 524, "type": "generic", "id": "524"}, {"node_id": "622", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 622, "type": "generic", "id": "622"}, {"node_id": "673", "ignored": false, "role": "heading", "chrome_role": 96, "name": "Usiamo i cookie", "backend_dom_node_id": 673, "type": "heading", "aria_level": 2.0, "pw_role": "heading", "pw_name": "Usiamo i cookie", "pw_depth": 4, "pw_box": [1542, 814, 330, 20], "pw_level": 2, "pw_ref": "e224", "id": "673"}, {"node_id": "674", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 674, "type": "generic", "id": "674"}, {"node_id": "678", "ignored": false, "role": "button", "chrome_role": 9, "name": "Accetta tutti", "backend_dom_node_id": 678, "type": "button", "aria_invalid": "false", "aria_focusable": true, "pw_role": "button", "pw_name": "Accetta tutti", "pw_depth": 4, "pw_box": [1542, 996, 160, 42], "pw_ref": "e228 cursor=pointer", "id": "678"}, {"node_id": "679", "ignored": false, "role": "button", "chrome_role": 9, "name": "Rifiuta tutti", "backend_dom_node_id": 679, "type": "button", "aria_invalid": "false", "aria_focusable": true, "pw_role": "button", "pw_name": "Rifiuta tutti", "pw_depth": 4, "pw_box": [1711, 996, 160, 42], "pw_ref": "e229 cursor=pointer", "id": "679"}, {"node_id": "730", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 730, "type": "none", "ignored_reasons": "uninteresting", "id": "730"}, {"node_id": "-1000000071", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Siti collegati", "type": "InlineTextBox", "id": "-1000000071"}, {"node_id": "755", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 755, "type": "listitem", "aria_level": 1.0, "id": "755"}, {"node_id": "757", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 757, "type": "listitem", "aria_level": 1.0, "id": "757"}, {"node_id": "759", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 759, "type": "listitem", "aria_level": 1.0, "id": "759"}, {"node_id": "761", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 761, "type": "listitem", "aria_level": 1.0, "id": "761"}, {"node_id": "763", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 763, "type": "listitem", "aria_level": 1.0, "id": "763"}, {"node_id": "769", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 769, "type": "listitem", "aria_level": 1.0, "id": "769"}, {"node_id": "771", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 771, "type": "listitem", "aria_level": 1.0, "id": "771"}, {"node_id": "773", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 773, "type": "listitem", "aria_level": 1.0, "id": "773"}, {"node_id": "775", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 775, "type": "listitem", "aria_level": 1.0, "id": "775"}, {"node_id": "777", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 777, "type": "listitem", "aria_level": 1.0, "id": "777"}, {"node_id": "779", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 779, "type": "listitem", "aria_level": 1.0, "id": "779"}, {"node_id": "781", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 781, "type": "listitem", "aria_level": 1.0, "id": "781"}, {"node_id": "783", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 783, "type": "listitem", "aria_level": 1.0, "id": "783"}, {"node_id": "-1000000002", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Uffici", "type": "InlineTextBox", "id": "-1000000002"}, {"node_id": "-1000000003", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "URP", "type": "InlineTextBox", "id": "-1000000003"}, {"node_id": "-1000000004", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "PEC", "type": "InlineTextBox", "id": "-1000000004"}, {"node_id": "-1000000005", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Mappa del sito", "type": "InlineTextBox", "id": "-1000000005"}, {"node_id": "-1000000006", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Amministrazione trasparente", "type": "InlineTextBox", "id": "-1000000006"}, {"node_id": "-1000000007", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Intranet", "type": "InlineTextBox", "id": "-1000000007"}, {"node_id": "218", "ignored": false, "role": "button", "chrome_role": 9, "name": "Esplora i temi", "backend_dom_node_id": 218, "type": "button", "aria_invalid": "false", "aria_focusable": true, "aria_expanded": false, "pw_role": "button", "pw_name": "Esplora i temi", "pw_depth": 6, "pw_box": [919, 92, 175, 56], "pw_ref": "e63 cursor=pointer", "id": "218"}, {"node_id": "308", "ignored": false, "role": "button", "chrome_role": 9, "name": "La Regione", "backend_dom_node_id": 308, "type": "button", "aria_invalid": "false", "aria_focusable": true, "aria_expanded": false, "pw_role": "button", "pw_name": "La Regione", "pw_depth": 6, "pw_box": [1125, 92, 150, 56], "pw_ref": "e67 cursor=pointer", "id": "308"}, {"node_id": "386", "ignored": false, "role": "link", "chrome_role": 110, "name": "Bandi e opportunit\u00e0", "backend_dom_node_id": 386, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/bandi-aperti?sortBy=desc&orderBy=modifiedDate", "pw_role": "link", "pw_name": "Bandi e opportunit\u00e0", "pw_depth": 6, "pw_box": [1307, 92, 205, 56], "pw_ref": "e71 cursor=pointer", "id": "386"}, {"node_id": "388", "ignored": false, "role": "button", "chrome_role": 9, "name": "Accesso veloce", "backend_dom_node_id": 388, "type": "button", "aria_invalid": "false", "aria_focusable": true, "aria_expanded": false, "pw_role": "button", "pw_name": "Accesso veloce", "pw_depth": 6, "pw_box": [1543, 92, 185, 56], "pw_ref": "e73 cursor=pointer", "id": "388"}, {"node_id": "504", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 504, "type": "none", "ignored_reasons": "uninteresting", "id": "504"}, {"node_id": "505", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 505, "type": "generic", "id": "505"}, {"node_id": "509", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 509, "type": "none", "ignored_reasons": "uninteresting", "id": "509"}, {"node_id": "510", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 510, "type": "none", "ignored_reasons": "uninteresting", "id": "510"}, {"node_id": "511", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 511, "type": "none", "ignored_reasons": "uninteresting", "id": "511"}, {"node_id": "512", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 512, "type": "none", "ignored_reasons": "uninteresting", "id": "512"}, {"node_id": "4", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 4, "type": "none", "ignored_reasons": "uninteresting", "id": "4"}, {"node_id": "513", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 513, "type": "none", "ignored_reasons": "uninteresting", "id": "513"}, {"node_id": "514", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 514, "type": "none", "ignored_reasons": "uninteresting", "id": "514"}, {"node_id": "515", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 515, "type": "none", "ignored_reasons": "uninteresting", "id": "515"}, {"node_id": "516", "ignored": false, "role": "heading", "chrome_role": 96, "name": "Amministrazione Trasparente", "backend_dom_node_id": 516, "type": "heading", "aria_level": 1.0, "pw_role": "heading", "pw_name": "Amministrazione Trasparente", "pw_depth": 3, "pw_box": [224, 215, 1092, 58], "pw_level": 1, "pw_ref": "e92", "id": "516"}, {"node_id": "518", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 518, "type": "none", "ignored_reasons": "uninteresting", "id": "518"}, {"node_id": "525", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 525, "type": "generic", "id": "525"}, {"node_id": "526", "ignored": false, "role": "generic", "chrome_role": 211, "backend_dom_node_id": 526, "type": "generic", "id": "526"}, {"node_id": "623", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 623, "type": "generic", "id": "623"}, {"node_id": "624", "ignored": false, "role": "generic", "chrome_role": 211, "backend_dom_node_id": 624, "type": "generic", "id": "624"}, {"node_id": "929", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Usiamo i cookie", "backend_dom_node_id": 929, "type": "StaticText", "id": "929"}, {"node_id": "930", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Questo sito web utilizza cookie essenziali per garantire il suo corretto funzionamento ed eventuali cookie di tracciamento per capire come interagisci con esso. Questi ultimi saranno impostati solo dopo il consenso.", "backend_dom_node_id": 930, "type": "StaticText", "id": "930"}, {"node_id": "675", "ignored": false, "role": "LineBreak", "chrome_role": 109, "name": "\n", "backend_dom_node_id": 675, "type": "LineBreak", "id": "675"}, {"node_id": "676", "ignored": false, "role": "button", "chrome_role": 9, "name": "Fammi scegliere", "backend_dom_node_id": 676, "type": "button", "aria_invalid": "false", "aria_focusable": true, "aria_hasPopup": "dialog", "pw_role": "button", "pw_name": "Fammi scegliere", "pw_depth": 5, "pw_box": [1542, 956, 105, 18], "pw_ref": "e226 cursor=pointer", "id": "676"}, {"node_id": "932", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Accetta tutti", "backend_dom_node_id": 932, "type": "StaticText", "id": "932"}, {"node_id": "933", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Rifiuta tutti", "backend_dom_node_id": 933, "type": "StaticText", "id": "933"}, {"node_id": "947", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 947, "type": "ListMarker", "id": "947"}, {"node_id": "756", "ignored": false, "role": "link", "chrome_role": 110, "name": "UFFICI", "backend_dom_node_id": 756, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/uffici", "pw_role": "link", "pw_name": "UFFICI", "pw_depth": 6, "pw_box": [176, 1901, 76, 37], "pw_ref": "e257 cursor=pointer", "id": "756"}, {"node_id": "949", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 949, "type": "ListMarker", "id": "949"}, {"node_id": "758", "ignored": false, "role": "link", "chrome_role": 110, "name": "URP", "backend_dom_node_id": 758, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/urp", "id": "758"}, {"node_id": "951", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 951, "type": "ListMarker", "id": "951"}, {"node_id": "760", "ignored": false, "role": "link", "chrome_role": 110, "name": "PEC", "backend_dom_node_id": 760, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/posta-elettronica-certificata-pec", "id": "760"}, {"node_id": "953", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 953, "type": "ListMarker", "id": "953"}, {"node_id": "762", "ignored": false, "role": "link", "chrome_role": 110, "name": "MAPPA DEL SITO", "backend_dom_node_id": 762, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/mappa", "pw_role": "link", "pw_name": "MAPPA DEL SITO", "pw_depth": 6, "pw_box": [373, 1901, 147, 37], "pw_ref": "e263 cursor=pointer", "id": "762"}, {"node_id": "955", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 955, "type": "ListMarker", "id": "955"}, {"node_id": "764", "ignored": false, "role": "link", "chrome_role": 110, "name": "INTRANET", "backend_dom_node_id": 764, "type": "link", "aria_focusable": true, "aria_url": "https://intranet.regione.toscana.it/", "pw_role": "link", "pw_name": "INTRANET", "pw_depth": 6, "pw_box": [521, 1901, 102, 37], "pw_ref": "e265 cursor=pointer", "id": "764"}, {"node_id": "957", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 957, "type": "ListMarker", "id": "957"}, {"node_id": "770", "ignored": false, "role": "link", "chrome_role": 110, "name": "Accessibilit\u00e0", "backend_dom_node_id": 770, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/-/accessibilita-e-uso-del-sito", "pw_role": "link", "pw_name": "Accessibilit\u00e0", "pw_depth": 6, "pw_box": [176, 1979, 119, 37], "pw_ref": "e271 cursor=pointer", "id": "770"}, {"node_id": "959", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 959, "type": "ListMarker", "id": "959"}, {"node_id": "772", "ignored": false, "role": "link", "chrome_role": 110, "name": "Atti di notifica", "backend_dom_node_id": 772, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/-/atti-di-notifica", "pw_role": "link", "pw_name": "Atti di notifica", "pw_depth": 6, "pw_box": [295, 1979, 132, 37], "pw_ref": "e273 cursor=pointer", "id": "772"}, {"node_id": "961", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 961, "type": "ListMarker", "id": "961"}, {"node_id": "774", "ignored": false, "role": "link", "chrome_role": 110, "name": "Note legali", "backend_dom_node_id": 774, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/note-legali", "pw_role": "link", "pw_name": "Note legali", "pw_depth": 6, "pw_box": [427, 1979, 108, 37], "pw_ref": "e275 cursor=pointer", "id": "774"}, {"node_id": "963", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 963, "type": "ListMarker", "id": "963"}, {"node_id": "776", "ignored": false, "role": "link", "chrome_role": 110, "name": "Amministrazione Trasparente", "backend_dom_node_id": 776, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente", "pw_role": "link", "pw_name": "Amministrazione Trasparente", "pw_depth": 4, "pw_box": [224, 211, 717, 65], "pw_ref": "e93 cursor=pointer", "id": "776"}, {"node_id": "965", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 965, "type": "ListMarker", "id": "965"}, {"node_id": "778", "ignored": false, "role": "link", "chrome_role": 110, "name": "Segnala illeciti", "backend_dom_node_id": 778, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/-/tutela-del-dipendente-che-segnala-illeciti-whistleblower-la-disciplina-dal-15-luglio-2023", "pw_role": "link", "pw_name": "Segnala illeciti", "pw_depth": 6, "pw_box": [775, 1979, 133, 37], "pw_ref": "e279 cursor=pointer", "id": "778"}, {"node_id": "967", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 967, "type": "ListMarker", "id": "967"}, {"node_id": "780", "ignored": false, "role": "link", "chrome_role": 110, "name": "Pubblicit\u00e0 legale", "backend_dom_node_id": 780, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/pubblicit%C3%A0-legale", "pw_role": "link", "pw_name": "Pubblicit\u00e0 legale", "pw_depth": 6, "pw_box": [908, 1979, 147, 37], "pw_ref": "e281 cursor=pointer", "id": "780"}, {"node_id": "969", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 969, "type": "ListMarker", "id": "969"}, {"node_id": "782", "ignored": false, "role": "link", "chrome_role": 110, "name": "Privacy", "backend_dom_node_id": 782, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/privacy", "pw_role": "link", "pw_name": "Privacy", "pw_depth": 6, "pw_box": [1056, 1979, 83, 37], "pw_ref": "e283 cursor=pointer", "id": "782"}, {"node_id": "971", "ignored": false, "role": "ListMarker", "chrome_role": 116, "backend_dom_node_id": 971, "type": "ListMarker", "id": "971"}, {"node_id": "784", "ignored": false, "role": "link", "chrome_role": 110, "name": "Redazione web", "backend_dom_node_id": 784, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/redazione-web", "pw_role": "link", "pw_name": "Redazione web", "pw_depth": 6, "pw_box": [1139, 1979, 137, 37], "pw_ref": "e285 cursor=pointer", "id": "784"}, {"node_id": "832", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Esplora i temi", "backend_dom_node_id": 832, "type": "StaticText", "id": "832"}, {"node_id": "221", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 221, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "221"}, {"node_id": "224", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 224, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "224"}, {"node_id": "853", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "La Regione", "backend_dom_node_id": 853, "type": "StaticText", "id": "853"}, {"node_id": "311", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 311, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "311"}, {"node_id": "314", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 314, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "314"}, {"node_id": "871", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Bandi e opportunit\u00e0", "backend_dom_node_id": 871, "type": "StaticText", "id": "871"}, {"node_id": "872", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Accesso veloce", "backend_dom_node_id": 872, "type": "StaticText", "id": "872"}, {"node_id": "391", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 391, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "391"}, {"node_id": "395", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 395, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "395"}, {"node_id": "506", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 506, "type": "generic", "id": "506"}, {"node_id": "517", "ignored": false, "role": "link", "chrome_role": 110, "name": "Amministrazione Trasparente", "backend_dom_node_id": 517, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente", "id": "517"}, {"node_id": "527", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 527, "type": "none", "ignored_reasons": "uninteresting", "id": "527"}, {"node_id": "528", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 528, "type": "none", "ignored_reasons": "uninteresting", "id": "528"}, {"node_id": "529", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 529, "type": "none", "ignored_reasons": "uninteresting", "id": "529"}, {"node_id": "530", "ignored": false, "role": "navigation", "chrome_role": 130, "name": "Indice delle pagine", "backend_dom_node_id": 530, "type": "navigation", "aria_labelledby": ["sidebarLabel"], "pw_role": "navigation", "pw_name": "Indice delle pagine", "pw_depth": 4, "pw_box": [192, 325, 336, 1380], "pw_ref": "e104", "id": "530"}, {"node_id": "625", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 625, "type": "none", "ignored_reasons": "uninteresting", "id": "625"}, {"node_id": "626", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 626, "type": "none", "ignored_reasons": "uninteresting", "id": "626"}, {"node_id": "627", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 627, "type": "none", "ignored_reasons": "uninteresting", "id": "627"}, {"node_id": "628", "ignored": false, "role": "generic", "chrome_role": 211, "backend_dom_node_id": 628, "type": "generic", "id": "628"}, {"node_id": "-1000000061", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Usiamo i cookie", "type": "InlineTextBox", "id": "-1000000061"}, {"node_id": "-1000000062", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Questo sito web utilizza cookie essenziali per ", "type": "InlineTextBox", "id": "-1000000062"}, {"node_id": "-1000000063", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "garantire il suo corretto funzionamento ed ", "type": "InlineTextBox", "id": "-1000000063"}, {"node_id": "-1000000064", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "eventuali cookie di tracciamento per capire come ", "type": "InlineTextBox", "id": "-1000000064"}, {"node_id": "-1000000065", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "interagisci con esso. Questi ultimi saranno ", "type": "InlineTextBox", "id": "-1000000065"}, {"node_id": "-1000000066", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "impostati solo dopo il consenso.", "type": "InlineTextBox", "id": "-1000000066"}, {"node_id": "-1000000067", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "\n", "type": "InlineTextBox", "id": "-1000000067"}, {"node_id": "931", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Fammi scegliere", "backend_dom_node_id": 931, "type": "StaticText", "id": "931"}, {"node_id": "-1000000069", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Accetta tutti", "type": "InlineTextBox", "id": "-1000000069"}, {"node_id": "-1000000070", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Rifiuta tutti", "type": "InlineTextBox", "id": "-1000000070"}, {"node_id": "948", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "UFFICI", "backend_dom_node_id": 948, "type": "StaticText", "id": "948"}, {"node_id": "950", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "URP", "backend_dom_node_id": 950, "type": "StaticText", "id": "950"}, {"node_id": "952", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "PEC", "backend_dom_node_id": 952, "type": "StaticText", "id": "952"}, {"node_id": "954", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "MAPPA DEL SITO", "backend_dom_node_id": 954, "type": "StaticText", "id": "954"}, {"node_id": "956", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "INTRANET", "backend_dom_node_id": 956, "type": "StaticText", "id": "956"}, {"node_id": "958", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Accessibilit\u00e0", "backend_dom_node_id": 958, "type": "StaticText", "id": "958"}, {"node_id": "960", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Atti di notifica", "backend_dom_node_id": 960, "type": "StaticText", "id": "960"}, {"node_id": "962", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Note legali", "backend_dom_node_id": 962, "type": "StaticText", "id": "962"}, {"node_id": "964", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Amministrazione Trasparente", "backend_dom_node_id": 964, "type": "StaticText", "id": "964"}, {"node_id": "966", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Segnala illeciti", "backend_dom_node_id": 966, "type": "StaticText", "id": "966"}, {"node_id": "968", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Pubblicit\u00e0 legale", "backend_dom_node_id": 968, "type": "StaticText", "id": "968"}, {"node_id": "970", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Privacy", "backend_dom_node_id": 970, "type": "StaticText", "id": "970"}, {"node_id": "972", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Redazione web", "backend_dom_node_id": 972, "type": "StaticText", "id": "972"}, {"node_id": "-1000000012", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Esplora i temi", "type": "InlineTextBox", "id": "-1000000012"}, {"node_id": "-1000000013", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "La Regione", "type": "InlineTextBox", "id": "-1000000013"}, {"node_id": "-1000000014", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Bandi e opportunit\u00e0", "type": "InlineTextBox", "id": "-1000000014"}, {"node_id": "-1000000015", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Accesso veloce", "type": "InlineTextBox", "id": "-1000000015"}, {"node_id": "507", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 507, "type": "none", "ignored_reasons": "uninteresting", "id": "507"}, {"node_id": "25", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Amministrazione Trasparente", "backend_dom_node_id": 25, "type": "StaticText", "id": "25"}, {"node_id": "531", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 531, "type": "generic", "id": "531"}, {"node_id": "538", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 538, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "538"}, {"node_id": "540", "ignored": false, "role": "list", "chrome_role": 111, "backend_dom_node_id": 540, "type": "list", "id": "540"}, {"node_id": "629", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 629, "type": "none", "ignored_reasons": "uninteresting", "id": "629"}, {"node_id": "630", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 630, "type": "none", "ignored_reasons": "uninteresting", "id": "630"}, {"node_id": "631", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 631, "type": "none", "ignored_reasons": "uninteresting", "id": "631"}, {"node_id": "632", "ignored": false, "role": "heading", "chrome_role": 96, "name": "Bandi di concorso e avvisi sul personale", "backend_dom_node_id": 632, "type": "heading", "aria_level": 2.0, "pw_role": "heading", "pw_name": "Bandi di concorso e avvisi sul personale", "pw_depth": 6, "pw_box": [592, 373, 1136, 38], "pw_level": 2, "pw_ref": "e197", "id": "632"}, {"node_id": "633", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 633, "type": "none", "ignored_reasons": "uninteresting", "id": "633"}, {"node_id": "634", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 634, "type": "none", "ignored_reasons": "uninteresting", "id": "634"}, {"node_id": "635", "ignored": false, "role": "paragraph", "chrome_role": 133, "backend_dom_node_id": 635, "type": "paragraph", "pw_role": "paragraph", "pw_depth": 7, "pw_box": [592, 435, 1026, 0], "id": "635"}, {"node_id": "638", "ignored": false, "role": "list", "chrome_role": 111, "backend_dom_node_id": 638, "type": "list", "id": "638"}, {"node_id": "643", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 643, "type": "none", "ignored_reasons": "uninteresting", "id": "643"}, {"node_id": "644", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 644, "type": "none", "ignored_reasons": "uninteresting", "id": "644"}, {"node_id": "645", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 645, "type": "none", "ignored_reasons": "uninteresting", "id": "645"}, {"node_id": "646", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 646, "type": "none", "ignored_reasons": "uninteresting", "id": "646"}, {"node_id": "647", "ignored": false, "role": "button", "chrome_role": 9, "name": "Condividi", "backend_dom_node_id": 647, "type": "button", "aria_invalid": "false", "aria_focusable": true, "pw_role": "button", "pw_name": "Condividi", "pw_depth": 6, "pw_box": [1590, 623, 138, 44], "pw_ref": "e210 cursor=pointer", "id": "647"}, {"node_id": "652", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 652, "type": "none", "ignored_reasons": "uninteresting", "id": "652"}, {"node_id": "653", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 653, "type": "none", "ignored_reasons": "uninteresting", "id": "653"}, {"node_id": "30", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 30, "type": "none", "ignored_reasons": "uninteresting", "id": "30"}, {"node_id": "654", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 654, "type": "generic", "id": "654"}, {"node_id": "33", "ignored": false, "role": "generic", "chrome_role": 88, "backend_dom_node_id": 33, "type": "generic", "id": "33"}, {"node_id": "-1000000068", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Fammi scegliere", "type": "InlineTextBox", "id": "-1000000068"}, {"node_id": "-1000000072", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "UFFICI", "type": "InlineTextBox", "id": "-1000000072"}, {"node_id": "-1000000073", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "URP", "type": "InlineTextBox", "id": "-1000000073"}, {"node_id": "-1000000074", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "PEC", "type": "InlineTextBox", "id": "-1000000074"}, {"node_id": "-1000000075", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "MAPPA DEL SITO", "type": "InlineTextBox", "id": "-1000000075"}, {"node_id": "-1000000076", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "INTRANET", "type": "InlineTextBox", "id": "-1000000076"}, {"node_id": "-1000000077", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Accessibilit\u00e0", "type": "InlineTextBox", "id": "-1000000077"}, {"node_id": "-1000000078", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Atti di notifica", "type": "InlineTextBox", "id": "-1000000078"}, {"node_id": "-1000000079", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Note legali", "type": "InlineTextBox", "id": "-1000000079"}, {"node_id": "-1000000080", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Amministrazione Trasparente", "type": "InlineTextBox", "id": "-1000000080"}, {"node_id": "-1000000081", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Segnala illeciti", "type": "InlineTextBox", "id": "-1000000081"}, {"node_id": "-1000000082", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Pubblicit\u00e0 legale", "type": "InlineTextBox", "id": "-1000000082"}, {"node_id": "-1000000083", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Privacy", "type": "InlineTextBox", "id": "-1000000083"}, {"node_id": "-1000000084", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Redazione web", "type": "InlineTextBox", "id": "-1000000084"}, {"node_id": "-1000000016", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Amministrazione Trasparente", "type": "InlineTextBox", "id": "-1000000016"}, {"node_id": "532", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 532, "type": "none", "ignored_reasons": "uninteresting", "id": "532"}, {"node_id": "892", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Indice delle pagine", "backend_dom_node_id": 892, "type": "StaticText", "id": "892"}, {"node_id": "541", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 541, "type": "listitem", "aria_level": 1.0, "id": "541"}, {"node_id": "26", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Bandi di concorso e avvisi sul personale", "backend_dom_node_id": 26, "type": "StaticText", "id": "26"}, {"node_id": "636", "ignored": false, "role": "strong", "chrome_role": 160, "backend_dom_node_id": 636, "type": "strong", "pw_role": "strong", "pw_depth": 8, "pw_box": [592, 439, 546, 24], "pw_ref": "e200", "id": "636"}, {"node_id": "637", "ignored": false, "role": "link", "chrome_role": 110, "name": "decreto legislativo 33/2013", "backend_dom_node_id": 637, "type": "link", "aria_focusable": true, "aria_url": "https://www.normattiva.it/uri-res/N2Ls?urn:nir:stato:decreto.legislativo:2013-03-14;33!vig=", "pw_role": "link", "pw_name": "decreto legislativo 33/2013", "pw_depth": 8, "pw_box": [1138, 439, 229, 24], "pw_ref": "e201 cursor=pointer", "id": "637"}, {"node_id": "13", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 13, "type": "listitem", "aria_level": 1.0, "id": "13"}, {"node_id": "641", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 641, "type": "listitem", "aria_level": 1.0, "id": "641"}, {"node_id": "925", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Condividi", "backend_dom_node_id": 925, "type": "StaticText", "id": "925"}, {"node_id": "650", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 650, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "650"}, {"node_id": "31", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Aggiornato al: ", "backend_dom_node_id": 31, "type": "StaticText", "id": "31"}, {"node_id": "655", "ignored": false, "role": "time", "chrome_role": 172, "backend_dom_node_id": 655, "type": "time", "pw_role": "time", "pw_depth": 8, "pw_box": [1464, 697, 82, 22], "pw_ref": "e217", "id": "655"}, {"node_id": "34", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Article ID: ", "backend_dom_node_id": 34, "type": "StaticText", "id": "34"}, {"node_id": "656", "ignored": false, "role": "strong", "chrome_role": 160, "backend_dom_node_id": 656, "type": "strong", "id": "656"}, {"node_id": "-1000000017", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Indice delle pagine", "type": "InlineTextBox", "id": "-1000000017"}, {"node_id": "542", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 542, "type": "none", "ignored_reasons": "uninteresting", "id": "542"}, {"node_id": "543", "ignored": false, "role": "link", "chrome_role": 110, "name": "Amministrazione Trasparente", "backend_dom_node_id": 543, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente", "id": "543"}, {"node_id": "545", "ignored": false, "role": "button", "chrome_role": 9, "name": "Amministrazione Trasparente", "backend_dom_node_id": 545, "type": "button", "aria_invalid": "false", "aria_focusable": true, "aria_expanded": true, "aria_controls": "sideNav-subnav-0", "pw_role": "button", "pw_name": "Amministrazione Trasparente", "pw_depth": 7, "pw_box": [496, 325, 32, 62], "pw_expanded ref": "e112 cursor=pointer", "id": "545"}, {"node_id": "551", "ignored": false, "role": "list", "chrome_role": 111, "backend_dom_node_id": 551, "type": "list", "id": "551"}, {"node_id": "-1000000044", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Bandi di concorso e avvisi sul personale", "type": "InlineTextBox", "id": "-1000000044"}, {"node_id": "919", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Pubblicazioni ai sensi dell'articolo 19 \"Bandi di concorso\" del ", "backend_dom_node_id": 919, "type": "StaticText", "id": "919"}, {"node_id": "27", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "decreto legislativo 33/2013", "backend_dom_node_id": 27, "type": "StaticText", "id": "27"}, {"node_id": "920", "ignored": false, "role": "ListMarker", "chrome_role": 116, "name": "\u2022 ", "backend_dom_node_id": 920, "type": "ListMarker", "id": "920"}, {"node_id": "639", "ignored": false, "role": "link", "chrome_role": 110, "name": "Bandi di concorso\u00a0e avvisi di selezione ", "backend_dom_node_id": 639, "type": "link", "aria_focusable": true, "aria_url": "http://www.regione.toscana.it/-/bandi-di-concorso-e-avvisi-selezioni-esterne-", "id": "639"}, {"node_id": "28", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "(Selezioni esterne)", "backend_dom_node_id": 28, "type": "StaticText", "id": "28"}, {"node_id": "640", "ignored": false, "role": "LineBreak", "chrome_role": 109, "name": "\n", "backend_dom_node_id": 640, "type": "LineBreak", "id": "640"}, {"node_id": "922", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "\u00a0", "backend_dom_node_id": 922, "type": "StaticText", "id": "922"}, {"node_id": "923", "ignored": false, "role": "ListMarker", "chrome_role": 116, "name": "\u2022 ", "backend_dom_node_id": 923, "type": "ListMarker", "id": "923"}, {"node_id": "642", "ignored": false, "role": "link", "chrome_role": 110, "name": "Avvisi di selezione interna", "backend_dom_node_id": 642, "type": "link", "aria_focusable": true, "aria_url": "http://www.regione.toscana.it/-/avvisi-di-selezione-interna", "pw_role": "link", "pw_name": "Avvisi di selezione interna", "pw_depth": 9, "pw_box": [628, 571, 220, 24], "pw_ref": "e206 cursor=pointer", "id": "642"}, {"node_id": "29", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": " (Selezioni interne)", "backend_dom_node_id": 29, "type": "StaticText", "id": "29"}, {"node_id": "-1000000055", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Condividi", "type": "InlineTextBox", "id": "-1000000055"}, {"node_id": "-1000000056", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Aggiornato al: ", "type": "InlineTextBox", "id": "-1000000056"}, {"node_id": "32", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "12.10.2025", "backend_dom_node_id": 32, "type": "StaticText", "id": "32"}, {"node_id": "-1000000058", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Article ID: ", "type": "InlineTextBox", "id": "-1000000058"}, {"node_id": "926", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "186899351", "backend_dom_node_id": 926, "type": "StaticText", "id": "926"}, {"node_id": "544", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 544, "type": "none", "ignored_reasons": "uninteresting", "id": "544"}, {"node_id": "894", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Amministrazione Trasparente", "backend_dom_node_id": 894, "type": "StaticText", "id": "894"}, {"node_id": "546", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 546, "type": "none", "ignored_reasons": "uninteresting", "id": "546"}, {"node_id": "895", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Amministrazione Trasparente", "backend_dom_node_id": 895, "type": "StaticText", "id": "895"}, {"node_id": "549", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 549, "type": "none", "ignored_reasons": "ariaHiddenSubtree", "id": "549"}, {"node_id": "552", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 552, "type": "listitem", "aria_level": 2.0, "id": "552"}, {"node_id": "555", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 555, "type": "listitem", "aria_level": 2.0, "id": "555"}, {"node_id": "558", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 558, "type": "listitem", "aria_level": 2.0, "id": "558"}, {"node_id": "561", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 561, "type": "listitem", "aria_level": 2.0, "id": "561"}, {"node_id": "564", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 564, "type": "listitem", "aria_level": 2.0, "id": "564"}, {"node_id": "567", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 567, "type": "listitem", "aria_level": 2.0, "id": "567"}, {"node_id": "570", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 570, "type": "listitem", "aria_level": 2.0, "id": "570"}, {"node_id": "573", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 573, "type": "listitem", "aria_level": 2.0, "id": "573"}, {"node_id": "576", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 576, "type": "listitem", "aria_level": 2.0, "id": "576"}, {"node_id": "579", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 579, "type": "listitem", "aria_level": 2.0, "id": "579"}, {"node_id": "582", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 582, "type": "listitem", "aria_level": 2.0, "id": "582"}, {"node_id": "585", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 585, "type": "listitem", "aria_level": 2.0, "id": "585"}, {"node_id": "588", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 588, "type": "listitem", "aria_level": 2.0, "id": "588"}, {"node_id": "591", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 591, "type": "listitem", "aria_level": 2.0, "id": "591"}, {"node_id": "594", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 594, "type": "listitem", "aria_level": 2.0, "id": "594"}, {"node_id": "597", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 597, "type": "listitem", "aria_level": 2.0, "id": "597"}, {"node_id": "600", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 600, "type": "listitem", "aria_level": 2.0, "id": "600"}, {"node_id": "603", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 603, "type": "listitem", "aria_level": 2.0, "id": "603"}, {"node_id": "606", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 606, "type": "listitem", "aria_level": 2.0, "id": "606"}, {"node_id": "609", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 609, "type": "listitem", "aria_level": 2.0, "id": "609"}, {"node_id": "612", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 612, "type": "listitem", "aria_level": 2.0, "id": "612"}, {"node_id": "615", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 615, "type": "listitem", "aria_level": 2.0, "id": "615"}, {"node_id": "618", "ignored": false, "role": "listitem", "chrome_role": 115, "backend_dom_node_id": 618, "type": "listitem", "aria_level": 2.0, "id": "618"}, {"node_id": "-1000000045", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Pubblicazioni ai sensi dell'articolo 19 \"Bandi di concorso\" del ", "type": "InlineTextBox", "id": "-1000000045"}, {"node_id": "-1000000046", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "decreto legislativo 33/2013", "type": "InlineTextBox", "id": "-1000000046"}, {"node_id": "-1000000047", "ignored": true, "role": "none", "chrome_role": 0, "type": "none", "ignored_reasons": "presentationalRole", "id": "-1000000047"}, {"node_id": "921", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Bandi di concorso\u00a0e avvisi di selezione ", "backend_dom_node_id": 921, "type": "StaticText", "id": "921"}, {"node_id": "-1000000049", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "(Selezioni esterne)", "type": "InlineTextBox", "id": "-1000000049"}, {"node_id": "-1000000050", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "\n", "type": "InlineTextBox", "id": "-1000000050"}, {"node_id": "-1000000051", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "\u00a0", "type": "InlineTextBox", "id": "-1000000051"}, {"node_id": "-1000000052", "ignored": true, "role": "none", "chrome_role": 0, "type": "none", "ignored_reasons": "presentationalRole", "id": "-1000000052"}, {"node_id": "924", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Avvisi di selezione interna", "backend_dom_node_id": 924, "type": "StaticText", "id": "924"}, {"node_id": "-1000000054", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": " (Selezioni interne)", "type": "InlineTextBox", "id": "-1000000054"}, {"node_id": "-1000000057", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "12.10.2025", "type": "InlineTextBox", "id": "-1000000057"}, {"node_id": "-1000000059", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "186899351", "type": "InlineTextBox", "id": "-1000000059"}, {"node_id": "-1000000018", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Amministrazione Trasparente", "type": "InlineTextBox", "id": "-1000000018"}, {"node_id": "-1000000019", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Amministrazione Trasparente", "type": "InlineTextBox", "id": "-1000000019"}, {"node_id": "553", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Disposizioni generali", "description": "Vai a Disposizioni generali", "backend_dom_node_id": 553, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/disposizioni-generali", "pw_role": "link", "pw_name": "Vai a Disposizioni generali", "pw_depth": 9, "pw_box": [208, 387, 320, 56], "pw_ref": "e118 cursor=pointer", "id": "553"}, {"node_id": "556", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Organizzazione", "description": "Vai a Organizzazione", "backend_dom_node_id": 556, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/organizzazione", "pw_role": "link", "pw_name": "Vai a Organizzazione", "pw_depth": 9, "pw_box": [208, 443, 320, 56], "pw_ref": "e121 cursor=pointer", "id": "556"}, {"node_id": "559", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Consulenti e collaboratori", "description": "Vai a Consulenti e collaboratori", "backend_dom_node_id": 559, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/consulenti-e-collaboratori", "pw_role": "link", "pw_name": "Vai a Consulenti e collaboratori", "pw_depth": 9, "pw_box": [208, 499, 320, 56], "pw_ref": "e124 cursor=pointer", "id": "559"}, {"node_id": "562", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Personale", "description": "Vai a Personale", "backend_dom_node_id": 562, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/personale", "pw_role": "link", "pw_name": "Vai a Personale", "pw_depth": 9, "pw_box": [208, 555, 320, 56], "pw_ref": "e127 cursor=pointer", "id": "562"}, {"node_id": "565", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Bandi di concorso", "description": "Vai a Bandi di concorso", "backend_dom_node_id": 565, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/bandi-di-concorso", "pw_role": "link", "pw_name": "Vai a Bandi di concorso", "pw_depth": 9, "pw_box": [208, 611, 320, 62], "pw_ref": "e130 cursor=pointer", "id": "565"}, {"node_id": "568", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Performance", "description": "Vai a Performance", "backend_dom_node_id": 568, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/performance", "pw_role": "link", "pw_name": "Vai a Performance", "pw_depth": 9, "pw_box": [208, 673, 320, 56], "pw_ref": "e133 cursor=pointer", "id": "568"}, {"node_id": "571", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Enti controllati", "description": "Vai a Enti controllati", "backend_dom_node_id": 571, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/enti-controllati", "pw_role": "link", "pw_name": "Vai a Enti controllati", "pw_depth": 9, "pw_box": [208, 729, 320, 56], "pw_ref": "e136 cursor=pointer", "id": "571"}, {"node_id": "574", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Attivit\u00e0 e procedimenti", "description": "Vai a Attivit\u00e0 e procedimenti", "backend_dom_node_id": 574, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/attivita-e-procedimenti", "pw_role": "link", "pw_name": "Vai a Attivit\u00e0 e procedimenti", "pw_depth": 9, "pw_box": [208, 785, 320, 56], "pw_ref": "e139 cursor=pointer", "id": "574"}, {"node_id": "577", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Provvedimenti", "description": "Vai a Provvedimenti", "backend_dom_node_id": 577, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/provvedimenti", "pw_role": "link", "pw_name": "Vai a Provvedimenti", "pw_depth": 9, "pw_box": [208, 841, 320, 56], "pw_ref": "e142 cursor=pointer", "id": "577"}, {"node_id": "580", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Controlli sulle attivit\u00e0 economiche", "description": "Vai a Controlli sulle attivit\u00e0 economiche", "backend_dom_node_id": 580, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/amministrazione-trasparente/controlli-sulle-attivit%C3%A0-economiche", "pw_role": "link", "pw_name": "Vai a Controlli sulle attivit\u00e0 economiche", "pw_depth": 9, "pw_box": [208, 897, 320, 56], "pw_ref": "e145 cursor=pointer", "id": "580"}, {"node_id": "583", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Bandi di gara e contratti", "description": "Vai a Bandi di gara e contratti", "backend_dom_node_id": 583, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/bandi-di-gara-e-contratti", "pw_role": "link", "pw_name": "Vai a Bandi di gara e contratti", "pw_depth": 9, "pw_box": [208, 953, 320, 56], "pw_ref": "e148 cursor=pointer", "id": "583"}, {"node_id": "586", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Sovvenzioni, contributi, sussidi, vantaggi economici", "description": "Vai a Sovvenzioni, contributi, sussidi, vantaggi economici", "backend_dom_node_id": 586, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/sovvenzioni-contributi-sussidi-vantaggi-economici", "pw_role": "link", "pw_name": "Vai a Sovvenzioni, contributi, sussidi, vantaggi economici", "pw_depth": 9, "pw_box": [208, 1009, 320, 80], "pw_ref": "e151 cursor=pointer", "id": "586"}, {"node_id": "589", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Bilanci", "description": "Vai a Bilanci", "backend_dom_node_id": 589, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/bilanci", "pw_role": "link", "pw_name": "Vai a Bilanci", "pw_depth": 9, "pw_box": [208, 1089, 320, 56], "pw_ref": "e154 cursor=pointer", "id": "589"}, {"node_id": "592", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Beni immobili e gestione patrimonio", "description": "Vai a Beni immobili e gestione patrimonio", "backend_dom_node_id": 592, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/beni-immobili-e-gestione-patrimonio", "pw_role": "link", "pw_name": "Vai a Beni immobili e gestione patrimonio", "pw_depth": 9, "pw_box": [208, 1145, 320, 56], "pw_ref": "e157 cursor=pointer", "id": "592"}, {"node_id": "595", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Controlli e rilievi sull'amministrazione", "description": "Vai a Controlli e rilievi sull'amministrazione", "backend_dom_node_id": 595, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/controlli-e-rilievi-sull-amministrazione", "pw_role": "link", "pw_name": "Vai a Controlli e rilievi sull'amministrazione", "pw_depth": 9, "pw_box": [208, 1201, 320, 56], "pw_ref": "e160 cursor=pointer", "id": "595"}, {"node_id": "598", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Servizi erogati", "description": "Vai a Servizi erogati", "backend_dom_node_id": 598, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/servizi-erogati", "pw_role": "link", "pw_name": "Vai a Servizi erogati", "pw_depth": 9, "pw_box": [208, 1257, 320, 56], "pw_ref": "e163 cursor=pointer", "id": "598"}, {"node_id": "601", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Pagamenti dell'amministrazione", "description": "Vai a Pagamenti dell'amministrazione", "backend_dom_node_id": 601, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/pagamenti-dell-amministrazione", "pw_role": "link", "pw_name": "Vai a Pagamenti dell'amministrazione", "pw_depth": 9, "pw_box": [208, 1313, 320, 56], "pw_ref": "e166 cursor=pointer", "id": "601"}, {"node_id": "604", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Opere pubbliche", "description": "Vai a Opere pubbliche", "backend_dom_node_id": 604, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/opere-pubbliche", "pw_role": "link", "pw_name": "Vai a Opere pubbliche", "pw_depth": 9, "pw_box": [208, 1369, 320, 56], "pw_ref": "e169 cursor=pointer", "id": "604"}, {"node_id": "607", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Pianificazione e governo del territorio", "description": "Vai a Pianificazione e governo del territorio", "backend_dom_node_id": 607, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/pianificazione-e-governo-del-territorio", "pw_role": "link", "pw_name": "Vai a Pianificazione e governo del territorio", "pw_depth": 9, "pw_box": [208, 1425, 320, 56], "pw_ref": "e172 cursor=pointer", "id": "607"}, {"node_id": "610", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Informazioni ambientali", "description": "Vai a Informazioni ambientali", "backend_dom_node_id": 610, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/informazioni-ambientali", "pw_role": "link", "pw_name": "Vai a Informazioni ambientali", "pw_depth": 9, "pw_box": [208, 1481, 320, 56], "pw_ref": "e175 cursor=pointer", "id": "610"}, {"node_id": "613", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Strutture sanitarie private accreditate", "description": "Vai a Strutture sanitarie private accreditate", "backend_dom_node_id": 613, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/strutture-sanitarie-private-accreditate", "pw_role": "link", "pw_name": "Vai a Strutture sanitarie private accreditate", "pw_depth": 9, "pw_box": [208, 1537, 320, 56], "pw_ref": "e178 cursor=pointer", "id": "613"}, {"node_id": "616", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Interventi straordinari e di emergenza", "description": "Vai a Interventi straordinari e di emergenza", "backend_dom_node_id": 616, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/regione/amministrazione-trasparente/interventi-straordinari-e-di-emergenza", "pw_role": "link", "pw_name": "Vai a Interventi straordinari e di emergenza", "pw_depth": 9, "pw_box": [208, 1593, 320, 56], "pw_ref": "e181 cursor=pointer", "id": "616"}, {"node_id": "619", "ignored": false, "role": "link", "chrome_role": 110, "name": "Vai a Altri contenuti", "description": "Vai a Altri contenuti", "backend_dom_node_id": 619, "type": "link", "aria_focusable": true, "aria_url": "https://www.regione.toscana.it/altri-contenuti", "pw_role": "link", "pw_name": "Vai a Altri contenuti", "pw_depth": 9, "pw_box": [208, 1649, 320, 56], "pw_ref": "e184 cursor=pointer", "id": "619"}, {"node_id": "-1000000048", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Bandi di concorso\u00a0e avvisi di selezione ", "type": "InlineTextBox", "id": "-1000000048"}, {"node_id": "-1000000053", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Avvisi di selezione interna", "type": "InlineTextBox", "id": "-1000000053"}, {"node_id": "554", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 554, "type": "none", "ignored_reasons": "uninteresting", "id": "554"}, {"node_id": "896", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Disposizioni generali", "backend_dom_node_id": 896, "type": "StaticText", "id": "896"}, {"node_id": "557", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 557, "type": "none", "ignored_reasons": "uninteresting", "id": "557"}, {"node_id": "897", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Organizzazione", "backend_dom_node_id": 897, "type": "StaticText", "id": "897"}, {"node_id": "560", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 560, "type": "none", "ignored_reasons": "uninteresting", "id": "560"}, {"node_id": "898", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Consulenti e collaboratori", "backend_dom_node_id": 898, "type": "StaticText", "id": "898"}, {"node_id": "563", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 563, "type": "none", "ignored_reasons": "uninteresting", "id": "563"}, {"node_id": "899", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Personale", "backend_dom_node_id": 899, "type": "StaticText", "id": "899"}, {"node_id": "566", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 566, "type": "none", "ignored_reasons": "uninteresting", "id": "566"}, {"node_id": "900", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Bandi di concorso", "backend_dom_node_id": 900, "type": "StaticText", "id": "900"}, {"node_id": "569", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 569, "type": "none", "ignored_reasons": "uninteresting", "id": "569"}, {"node_id": "901", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Performance", "backend_dom_node_id": 901, "type": "StaticText", "id": "901"}, {"node_id": "572", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 572, "type": "none", "ignored_reasons": "uninteresting", "id": "572"}, {"node_id": "902", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Enti controllati", "backend_dom_node_id": 902, "type": "StaticText", "id": "902"}, {"node_id": "575", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 575, "type": "none", "ignored_reasons": "uninteresting", "id": "575"}, {"node_id": "903", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Attivit\u00e0 e procedimenti", "backend_dom_node_id": 903, "type": "StaticText", "id": "903"}, {"node_id": "578", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 578, "type": "none", "ignored_reasons": "uninteresting", "id": "578"}, {"node_id": "904", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Provvedimenti", "backend_dom_node_id": 904, "type": "StaticText", "id": "904"}, {"node_id": "581", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 581, "type": "none", "ignored_reasons": "uninteresting", "id": "581"}, {"node_id": "905", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Controlli sulle attivit\u00e0 economiche", "backend_dom_node_id": 905, "type": "StaticText", "id": "905"}, {"node_id": "584", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 584, "type": "none", "ignored_reasons": "uninteresting", "id": "584"}, {"node_id": "906", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Bandi di gara e contratti", "backend_dom_node_id": 906, "type": "StaticText", "id": "906"}, {"node_id": "587", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 587, "type": "none", "ignored_reasons": "uninteresting", "id": "587"}, {"node_id": "907", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Sovvenzioni, contributi, sussidi, vantaggi economici", "backend_dom_node_id": 907, "type": "StaticText", "id": "907"}, {"node_id": "590", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 590, "type": "none", "ignored_reasons": "uninteresting", "id": "590"}, {"node_id": "908", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Bilanci", "backend_dom_node_id": 908, "type": "StaticText", "id": "908"}, {"node_id": "593", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 593, "type": "none", "ignored_reasons": "uninteresting", "id": "593"}, {"node_id": "909", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Beni immobili e gestione patrimonio", "backend_dom_node_id": 909, "type": "StaticText", "id": "909"}, {"node_id": "596", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 596, "type": "none", "ignored_reasons": "uninteresting", "id": "596"}, {"node_id": "910", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Controlli e rilievi sull'amministrazione", "backend_dom_node_id": 910, "type": "StaticText", "id": "910"}, {"node_id": "599", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 599, "type": "none", "ignored_reasons": "uninteresting", "id": "599"}, {"node_id": "911", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Servizi erogati", "backend_dom_node_id": 911, "type": "StaticText", "id": "911"}, {"node_id": "602", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 602, "type": "none", "ignored_reasons": "uninteresting", "id": "602"}, {"node_id": "912", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Pagamenti dell'amministrazione", "backend_dom_node_id": 912, "type": "StaticText", "id": "912"}, {"node_id": "605", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 605, "type": "none", "ignored_reasons": "uninteresting", "id": "605"}, {"node_id": "913", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Opere pubbliche", "backend_dom_node_id": 913, "type": "StaticText", "id": "913"}, {"node_id": "608", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 608, "type": "none", "ignored_reasons": "uninteresting", "id": "608"}, {"node_id": "914", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Pianificazione e governo del territorio", "backend_dom_node_id": 914, "type": "StaticText", "id": "914"}, {"node_id": "611", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 611, "type": "none", "ignored_reasons": "uninteresting", "id": "611"}, {"node_id": "915", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Informazioni ambientali", "backend_dom_node_id": 915, "type": "StaticText", "id": "915"}, {"node_id": "614", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 614, "type": "none", "ignored_reasons": "uninteresting", "id": "614"}, {"node_id": "916", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Strutture sanitarie private accreditate", "backend_dom_node_id": 916, "type": "StaticText", "id": "916"}, {"node_id": "617", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 617, "type": "none", "ignored_reasons": "uninteresting", "id": "617"}, {"node_id": "917", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Interventi straordinari e di emergenza", "backend_dom_node_id": 917, "type": "StaticText", "id": "917"}, {"node_id": "620", "ignored": true, "role": "none", "chrome_role": 0, "backend_dom_node_id": 620, "type": "none", "ignored_reasons": "uninteresting", "id": "620"}, {"node_id": "918", "ignored": false, "role": "StaticText", "chrome_role": 158, "name": "Altri contenuti", "backend_dom_node_id": 918, "type": "StaticText", "id": "918"}, {"node_id": "-1000000020", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Disposizioni generali", "type": "InlineTextBox", "id": "-1000000020"}, {"node_id": "-1000000021", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Organizzazione", "type": "InlineTextBox", "id": "-1000000021"}, {"node_id": "-1000000022", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Consulenti e collaboratori", "type": "InlineTextBox", "id": "-1000000022"}, {"node_id": "-1000000023", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Personale", "type": "InlineTextBox", "id": "-1000000023"}, {"node_id": "-1000000024", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Bandi di concorso", "type": "InlineTextBox", "id": "-1000000024"}, {"node_id": "-1000000025", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Performance", "type": "InlineTextBox", "id": "-1000000025"}, {"node_id": "-1000000026", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Enti controllati", "type": "InlineTextBox", "id": "-1000000026"}, {"node_id": "-1000000027", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Attivit\u00e0 e procedimenti", "type": "InlineTextBox", "id": "-1000000027"}, {"node_id": "-1000000028", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Provvedimenti", "type": "InlineTextBox", "id": "-1000000028"}, {"node_id": "-1000000029", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Controlli sulle attivit\u00e0 economiche", "type": "InlineTextBox", "id": "-1000000029"}, {"node_id": "-1000000030", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Bandi di gara e contratti", "type": "InlineTextBox", "id": "-1000000030"}, {"node_id": "-1000000031", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Sovvenzioni, contributi, sussidi, ", "type": "InlineTextBox", "id": "-1000000031"}, {"node_id": "-1000000032", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "vantaggi economici", "type": "InlineTextBox", "id": "-1000000032"}, {"node_id": "-1000000033", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Bilanci", "type": "InlineTextBox", "id": "-1000000033"}, {"node_id": "-1000000034", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Beni immobili e gestione patrimonio", "type": "InlineTextBox", "id": "-1000000034"}, {"node_id": "-1000000035", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Controlli e rilievi sull'amministrazione", "type": "InlineTextBox", "id": "-1000000035"}, {"node_id": "-1000000036", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Servizi erogati", "type": "InlineTextBox", "id": "-1000000036"}, {"node_id": "-1000000037", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Pagamenti dell'amministrazione", "type": "InlineTextBox", "id": "-1000000037"}, {"node_id": "-1000000038", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Opere pubbliche", "type": "InlineTextBox", "id": "-1000000038"}, {"node_id": "-1000000039", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Pianificazione e governo del territorio", "type": "InlineTextBox", "id": "-1000000039"}, {"node_id": "-1000000040", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Informazioni ambientali", "type": "InlineTextBox", "id": "-1000000040"}, {"node_id": "-1000000041", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Strutture sanitarie private accreditate", "type": "InlineTextBox", "id": "-1000000041"}, {"node_id": "-1000000042", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Interventi straordinari e di emergenza", "type": "InlineTextBox", "id": "-1000000042"}, {"node_id": "-1000000043", "ignored": false, "role": "InlineTextBox", "chrome_role": 101, "name": "Altri contenuti", "type": "InlineTextBox", "id": "-1000000043"}], "edges": [{"relation": "hasChild", "type": "hasChild", "source": "2", "target": "36"}, {"relation": "hasParent", "type": "hasParent", "source": "36", "target": "2"}, {"relation": "hasChild", "type": "hasChild", "source": "36", "target": "104"}, {"relation": "hasParent", "type": "hasParent", "source": "104", "target": "36"}, {"relation": "hasChild", "type": "hasChild", "source": "104", "target": "105"}, {"relation": "hasChild", "type": "hasChild", "source": "104", "target": "495"}, {"relation": "hasChild", "type": "hasChild", "source": "104", "target": "668"}, {"relation": "hasChild", "type": "hasChild", "source": "104", "target": "723"}, {"relation": "hasChild", "type": "hasChild", "source": "104", "target": "811"}, {"relation": "hasParent", "type": "hasParent", "source": "105", "target": "104"}, {"relation": "hasChild", "type": "hasChild", "source": "105", "target": "106"}, {"relation": "hasChild", "type": "hasChild", "source": "105", "target": "193"}, {"relation": "hasParent", "type": "hasParent", "source": "495", "target": "104"}, {"relation": "hasChild", "type": "hasChild", "source": "495", "target": "497"}, {"relation": "hasChild", "type": "hasChild", "source": "495", "target": "657"}, {"relation": "hasParent", "type": "hasParent", "source": "668", "target": "104"}, {"relation": "hasChild", "type": "hasChild", "source": "668", "target": "669"}, {"relation": "hasParent", "type": "hasParent", "source": "723", "target": "104"}, {"relation": "hasChild", "type": "hasChild", "source": "723", "target": "724"}, {"relation": "hasChild", "type": "hasChild", "source": "723", "target": "785"}, {"relation": "hasParent", "type": "hasParent", "source": "811", "target": "104"}, {"relation": "hasParent", "type": "hasParent", "source": "106", "target": "105"}, {"relation": "hasChild", "type": "hasChild", "source": "106", "target": "107"}, {"relation": "hasParent", "type": "hasParent", "source": "107", "target": "106"}, {"relation": "hasChild", "type": "hasChild", "source": "107", "target": "108"}, {"relation": "hasChild", "type": "hasChild", "source": "107", "target": "121"}, {"relation": "hasParent", "type": "hasParent", "source": "108", "target": "107"}, {"relation": "hasChild", "type": "hasChild", "source": "108", "target": "109"}, {"relation": "hasParent", "type": "hasParent", "source": "109", "target": "108"}, {"relation": "hasChild", "type": "hasChild", "source": "109", "target": "110"}, {"relation": "hasParent", "type": "hasParent", "source": "121", "target": "107"}, {"relation": "hasChild", "type": "hasChild", "source": "121", "target": "122"}, {"relation": "hasChild", "type": "hasChild", "source": "121", "target": "146"}, {"relation": "hasChild", "type": "hasChild", "source": "121", "target": "147"}, {"relation": "hasChild", "type": "hasChild", "source": "121", "target": "149"}, {"relation": "hasParent", "type": "hasParent", "source": "122", "target": "121"}, {"relation": "hasChild", "type": "hasChild", "source": "122", "target": "123"}, {"relation": "hasParent", "type": "hasParent", "source": "123", "target": "122"}, {"relation": "hasChild", "type": "hasChild", "source": "123", "target": "124"}, {"relation": "hasChild", "type": "hasChild", "source": "123", "target": "131"}, {"relation": "hasChild", "type": "hasChild", "source": "123", "target": "139"}, {"relation": "hasParent", "type": "hasParent", "source": "146", "target": "121"}, {"relation": "hasChild", "type": "hasChild", "source": "146", "target": "9"}, {"relation": "hasParent", "type": "hasParent", "source": "9", "target": "146"}, {"relation": "hasParent", "type": "hasParent", "source": "147", "target": "121"}, {"relation": "hasChild", "type": "hasChild", "source": "147", "target": "148"}, {"relation": "hasParent", "type": "hasParent", "source": "148", "target": "147"}, {"relation": "hasChild", "type": "hasChild", "source": "148", "target": "12"}, {"relation": "hasParent", "type": "hasParent", "source": "149", "target": "121"}, {"relation": "hasChild", "type": "hasChild", "source": "149", "target": "150"}, {"relation": "hasChild", "type": "hasChild", "source": "149", "target": "160"}, {"relation": "hasChild", "type": "hasChild", "source": "149", "target": "165"}, {"relation": "hasChild", "type": "hasChild", "source": "149", "target": "176"}, {"relation": "hasChild", "type": "hasChild", "source": "149", "target": "180"}, {"relation": "hasChild", "type": "hasChild", "source": "149", "target": "183"}, {"relation": "hasChild", "type": "hasChild", "source": "149", "target": "184"}, {"relation": "hasChild", "type": "hasChild", "source": "149", "target": "189"}, {"relation": "hasParent", "type": "hasParent", "source": "193", "target": "105"}, {"relation": "hasChild", "type": "hasChild", "source": "193", "target": "194"}, {"relation": "hasParent", "type": "hasParent", "source": "194", "target": "193"}, {"relation": "hasChild", "type": "hasChild", "source": "194", "target": "195"}, {"relation": "hasChild", "type": "hasChild", "source": "194", "target": "197"}, {"relation": "hasParent", "type": "hasParent", "source": "195", "target": "194"}, {"relation": "hasChild", "type": "hasChild", "source": "195", "target": "196"}, {"relation": "hasParent", "type": "hasParent", "source": "196", "target": "195"}, {"relation": "hasChild", "type": "hasChild", "source": "196", "target": "11"}, {"relation": "hasParent", "type": "hasParent", "source": "197", "target": "194"}, {"relation": "hasChild", "type": "hasChild", "source": "197", "target": "198"}, {"relation": "hasParent", "type": "hasParent", "source": "198", "target": "197"}, {"relation": "hasChild", "type": "hasChild", "source": "198", "target": "202"}, {"relation": "hasChild", "type": "hasChild", "source": "198", "target": "206"}, {"relation": "hasChild", "type": "hasChild", "source": "198", "target": "20"}, {"relation": "hasParent", "type": "hasParent", "source": "497", "target": "495"}, {"relation": "hasChild", "type": "hasChild", "source": "497", "target": "498"}, {"relation": "hasChild", "type": "hasChild", "source": "497", "target": "519"}, {"relation": "hasParent", "type": "hasParent", "source": "657", "target": "495"}, {"relation": "hasChild", "type": "hasChild", "source": "657", "target": "658"}, {"relation": "hasChild", "type": "hasChild", "source": "657", "target": "35"}, {"relation": "hasParent", "type": "hasParent", "source": "669", "target": "668"}, {"relation": "hasChild", "type": "hasChild", "source": "669", "target": "670"}, {"relation": "hasChild", "type": "hasChild", "source": "669", "target": "687"}, {"relation": "hasChild", "type": "hasChild", "source": "669", "target": "689"}, {"relation": "hasChild", "type": "hasChild", "source": "669", "target": "698"}, {"relation": "hasChild", "type": "hasChild", "source": "669", "target": "699"}, {"relation": "hasChild", "type": "hasChild", "source": "669", "target": "709"}, {"relation": "hasChild", "type": "hasChild", "source": "669", "target": "710"}, {"relation": "hasParent", "type": "hasParent", "source": "724", "target": "723"}, {"relation": "hasChild", "type": "hasChild", "source": "724", "target": "725"}, {"relation": "hasChild", "type": "hasChild", "source": "724", "target": "726"}, {"relation": "hasParent", "type": "hasParent", "source": "785", "target": "723"}, {"relation": "hasChild", "type": "hasChild", "source": "785", "target": "786"}, {"relation": "hasParent", "type": "hasParent", "source": "786", "target": "785"}, {"relation": "hasChild", "type": "hasChild", "source": "786", "target": "787"}, {"relation": "hasChild", "type": "hasChild", "source": "786", "target": "790"}, {"relation": "hasParent", "type": "hasParent", "source": "787", "target": "786"}, {"relation": "hasChild", "type": "hasChild", "source": "787", "target": "788"}, {"relation": "hasParent", "type": "hasParent", "source": "788", "target": "787"}, {"relation": "hasChild", "type": "hasChild", "source": "788", "target": "789"}, {"relation": "hasParent", "type": "hasParent", "source": "789", "target": "788"}, {"relation": "hasChild", "type": "hasChild", "source": "789", "target": "973"}, {"relation": "hasParent", "type": "hasParent", "source": "790", "target": "786"}, {"relation": "hasChild", "type": "hasChild", "source": "790", "target": "791"}, {"relation": "hasParent", "type": "hasParent", "source": "791", "target": "790"}, {"relation": "hasChild", "type": "hasChild", "source": "791", "target": "3"}, {"relation": "hasParent", "type": "hasParent", "source": "3", "target": "791"}, {"relation": "hasParent", "type": "hasParent", "source": "110", "target": "109"}, {"relation": "hasChild", "type": "hasChild", "source": "110", "target": "111"}, {"relation": "hasChild", "type": "hasChild", "source": "110", "target": "113"}, {"relation": "hasChild", "type": "hasChild", "source": "110", "target": "115"}, {"relation": "hasChild", "type": "hasChild", "source": "110", "target": "16"}, {"relation": "hasChild", "type": "hasChild", "source": "110", "target": "118"}, {"relation": "hasChild", "type": "hasChild", "source": "110", "target": "18"}, {"relation": "hasParent", "type": "hasParent", "source": "124", "target": "123"}, {"relation": "hasChild", "type": "hasChild", "source": "124", "target": "125"}, {"relation": "hasParent", "type": "hasParent", "source": "131", "target": "123"}, {"relation": "hasChild", "type": "hasChild", "source": "131", "target": "132"}, {"relation": "hasParent", "type": "hasParent", "source": "139", "target": "123"}, {"relation": "hasChild", "type": "hasChild", "source": "139", "target": "140"}, {"relation": "hasParent", "type": "hasParent", "source": "12", "target": "148"}, {"relation": "hasParent", "type": "hasParent", "source": "150", "target": "149"}, {"relation": "hasChild", "type": "hasChild", "source": "150", "target": "151"}, {"relation": "hasChild", "type": "hasChild", "source": "150", "target": "154"}, {"relation": "hasParent", "type": "hasParent", "source": "160", "target": "149"}, {"relation": "hasChild", "type": "hasChild", "source": "160", "target": "827"}, {"relation": "hasParent", "type": "hasParent", "source": "827", "target": "160"}, {"relation": "hasParent", "type": "hasParent", "source": "165", "target": "149"}, {"relation": "hasParent", "type": "hasParent", "source": "176", "target": "149"}, {"relation": "hasChild", "type": "hasChild", "source": "176", "target": "829"}, {"relation": "hasParent", "type": "hasParent", "source": "829", "target": "176"}, {"relation": "hasParent", "type": "hasParent", "source": "180", "target": "149"}, {"relation": "hasParent", "type": "hasParent", "source": "183", "target": "149"}, {"relation": "hasParent", "type": "hasParent", "source": "184", "target": "149"}, {"relation": "hasParent", "type": "hasParent", "source": "189", "target": "149"}, {"relation": "hasParent", "type": "hasParent", "source": "11", "target": "196"}, {"relation": "hasParent", "type": "hasParent", "source": "202", "target": "198"}, {"relation": "hasParent", "type": "hasParent", "source": "206", "target": "198"}, {"relation": "hasParent", "type": "hasParent", "source": "20", "target": "198"}, {"relation": "hasChild", "type": "hasChild", "source": "20", "target": "209"}, {"relation": "hasChild", "type": "hasChild", "source": "20", "target": "477"}, {"relation": "hasChild", "type": "hasChild", "source": "20", "target": "481"}, {"relation": "hasChild", "type": "hasChild", "source": "20", "target": "484"}, {"relation": "hasChild", "type": "hasChild", "source": "20", "target": "485"}, {"relation": "hasChild", "type": "hasChild", "source": "20", "target": "490"}, {"relation": "hasParent", "type": "hasParent", "source": "498", "target": "497"}, {"relation": "hasChild", "type": "hasChild", "source": "498", "target": "499"}, {"relation": "hasParent", "type": "hasParent", "source": "499", "target": "498"}, {"relation": "hasChild", "type": "hasChild", "source": "499", "target": "500"}, {"relation": "hasParent", "type": "hasParent", "source": "519", "target": "497"}, {"relation": "hasChild", "type": "hasChild", "source": "519", "target": "520"}, {"relation": "hasParent", "type": "hasParent", "source": "520", "target": "519"}, {"relation": "hasChild", "type": "hasChild", "source": "520", "target": "521"}, {"relation": "hasParent", "type": "hasParent", "source": "658", "target": "657"}, {"relation": "hasParent", "type": "hasParent", "source": "35", "target": "657"}, {"relation": "hasChild", "type": "hasChild", "source": "35", "target": "927"}, {"relation": "hasParent", "type": "hasParent", "source": "670", "target": "669"}, {"relation": "hasChild", "type": "hasChild", "source": "670", "target": "671"}, {"relation": "describedby", "type": "describedby", "source": "670", "target": "674"}, {"relation": "labelledby", "type": "labelledby", "source": "670", "target": "673"}, {"relation": "hasParent", "type": "hasParent", "source": "687", "target": "669"}, {"relation": "hasChild", "type": "hasChild", "source": "687", "target": "934"}, {"relation": "hasParent", "type": "hasParent", "source": "934", "target": "687"}, {"relation": "hasParent", "type": "hasParent", "source": "689", "target": "669"}, {"relation": "hasParent", "type": "hasParent", "source": "698", "target": "669"}, {"relation": "hasParent", "type": "hasParent", "source": "699", "target": "669"}, {"relation": "hasChild", "type": "hasChild", "source": "699", "target": "700"}, {"relation": "hasChild", "type": "hasChild", "source": "699", "target": "701"}, {"relation": "hasChild", "type": "hasChild", "source": "699", "target": "704"}, {"relation": "hasParent", "type": "hasParent", "source": "700", "target": "699"}, {"relation": "hasParent", "type": "hasParent", "source": "701", "target": "699"}, {"relation": "hasChild", "type": "hasChild", "source": "701", "target": "702"}, {"relation": "hasChild", "type": "hasChild", "source": "701", "target": "703"}, {"relation": "hasParent", "type": "hasParent", "source": "702", "target": "701"}, {"relation": "hasParent", "type": "hasParent", "source": "703", "target": "701"}, {"relation": "hasParent", "type": "hasParent", "source": "704", "target": "699"}, {"relation": "hasChild", "type": "hasChild", "source": "704", "target": "938"}, {"relation": "hasParent", "type": "hasParent", "source": "938", "target": "704"}, {"relation": "hasParent", "type": "hasParent", "source": "709", "target": "669"}, {"relation": "hasParent", "type": "hasParent", "source": "710", "target": "669"}, {"relation": "hasChild", "type": "hasChild", "source": "710", "target": "711"}, {"relation": "hasChild", "type": "hasChild", "source": "710", "target": "712"}, {"relation": "hasChild", "type": "hasChild", "source": "710", "target": "715"}, {"relation": "hasParent", "type": "hasParent", "source": "711", "target": "710"}, {"relation": "hasParent", "type": "hasParent", "source": "712", "target": "710"}, {"relation": "hasChild", "type": "hasChild", "source": "712", "target": "713"}, {"relation": "hasChild", "type": "hasChild", "source": "712", "target": "714"}, {"relation": "hasParent", "type": "hasParent", "source": "713", "target": "712"}, {"relation": "hasParent", "type": "hasParent", "source": "714", "target": "712"}, {"relation": "hasParent", "type": "hasParent", "source": "715", "target": "710"}, {"relation": "hasChild", "type": "hasChild", "source": "715", "target": "941"}, {"relation": "hasParent", "type": "hasParent", "source": "941", "target": "715"}, {"relation": "hasParent", "type": "hasParent", "source": "725", "target": "724"}, {"relation": "hasParent", "type": "hasParent", "source": "726", "target": "724"}, {"relation": "hasChild", "type": "hasChild", "source": "726", "target": "727"}, {"relation": "hasParent", "type": "hasParent", "source": "973", "target": "789"}, {"relation": "hasChild", "type": "hasChild", "source": "973", "target": "-1000000085"}, {"relation": "hasParent", "type": "hasParent", "source": "111", "target": "110"}, {"relation": "hasChild", "type": "hasChild", "source": "111", "target": "813"}, {"relation": "hasChild", "type": "hasChild", "source": "111", "target": "112"}, {"relation": "hasParent", "type": "hasParent", "source": "113", "target": "110"}, {"relation": "hasChild", "type": "hasChild", "source": "113", "target": "815"}, {"relation": "hasChild", "type": "hasChild", "source": "113", "target": "114"}, {"relation": "hasParent", "type": "hasParent", "source": "115", "target": "110"}, {"relation": "hasChild", "type": "hasChild", "source": "115", "target": "817"}, {"relation": "hasChild", "type": "hasChild", "source": "115", "target": "116"}, {"relation": "hasParent", "type": "hasParent", "source": "16", "target": "110"}, {"relation": "hasChild", "type": "hasChild", "source": "16", "target": "819"}, {"relation": "hasChild", "type": "hasChild", "source": "16", "target": "117"}, {"relation": "hasParent", "type": "hasParent", "source": "118", "target": "110"}, {"relation": "hasChild", "type": "hasChild", "source": "118", "target": "820"}, {"relation": "hasChild", "type": "hasChild", "source": "118", "target": "119"}, {"relation": "hasParent", "type": "hasParent", "source": "18", "target": "110"}, {"relation": "hasChild", "type": "hasChild", "source": "18", "target": "822"}, {"relation": "hasChild", "type": "hasChild", "source": "18", "target": "120"}, {"relation": "hasParent", "type": "hasParent", "source": "125", "target": "124"}, {"relation": "hasChild", "type": "hasChild", "source": "125", "target": "126"}, {"relation": "hasChild", "type": "hasChild", "source": "125", "target": "129"}, {"relation": "hasParent", "type": "hasParent", "source": "132", "target": "131"}, {"relation": "hasChild", "type": "hasChild", "source": "132", "target": "133"}, {"relation": "hasChild", "type": "hasChild", "source": "132", "target": "136"}, {"relation": "hasParent", "type": "hasParent", "source": "140", "target": "139"}, {"relation": "hasChild", "type": "hasChild", "source": "140", "target": "141"}, {"relation": "hasChild", "type": "hasChild", "source": "140", "target": "144"}, {"relation": "hasParent", "type": "hasParent", "source": "151", "target": "150"}, {"relation": "hasChild", "type": "hasChild", "source": "151", "target": "826"}, {"relation": "hasParent", "type": "hasParent", "source": "826", "target": "151"}, {"relation": "hasChild", "type": "hasChild", "source": "826", "target": "-1000000011"}, {"relation": "hasParent", "type": "hasParent", "source": "154", "target": "150"}, {"relation": "hasParent", "type": "hasParent", "source": "209", "target": "20"}, {"relation": "hasChild", "type": "hasChild", "source": "209", "target": "210"}, {"relation": "hasParent", "type": "hasParent", "source": "210", "target": "209"}, {"relation": "hasChild", "type": "hasChild", "source": "210", "target": "211"}, {"relation": "hasChild", "type": "hasChild", "source": "210", "target": "212"}, {"relation": "hasParent", "type": "hasParent", "source": "477", "target": "20"}, {"relation": "hasChild", "type": "hasChild", "source": "477", "target": "890"}, {"relation": "hasParent", "type": "hasParent", "source": "890", "target": "477"}, {"relation": "hasParent", "type": "hasParent", "source": "481", "target": "20"}, {"relation": "hasParent", "type": "hasParent", "source": "484", "target": "20"}, {"relation": "hasParent", "type": "hasParent", "source": "485", "target": "20"}, {"relation": "hasParent", "type": "hasParent", "source": "490", "target": "20"}, {"relation": "hasParent", "type": "hasParent", "source": "500", "target": "499"}, {"relation": "hasChild", "type": "hasChild", "source": "500", "target": "501"}, {"relation": "hasParent", "type": "hasParent", "source": "521", "target": "520"}, {"relation": "hasChild", "type": "hasChild", "source": "521", "target": "522"}, {"relation": "hasChild", "type": "hasChild", "source": "521", "target": "14"}, {"relation": "hasParent", "type": "hasParent", "source": "522", "target": "521"}, {"relation": "hasChild", "type": "hasChild", "source": "522", "target": "523"}, {"relation": "hasParent", "type": "hasParent", "source": "14", "target": "521"}, {"relation": "hasChild", "type": "hasChild", "source": "14", "target": "621"}, {"relation": "hasParent", "type": "hasParent", "source": "927", "target": "35"}, {"relation": "hasChild", "type": "hasChild", "source": "927", "target": "-1000000060"}, {"relation": "hasParent", "type": "hasParent", "source": "671", "target": "670"}, {"relation": "hasChild", "type": "hasChild", "source": "671", "target": "672"}, {"relation": "hasChild", "type": "hasChild", "source": "671", "target": "677"}, {"relation": "hasParent", "type": "hasParent", "source": "727", "target": "726"}, {"relation": "hasChild", "type": "hasChild", "source": "727", "target": "728"}, {"relation": "hasChild", "type": "hasChild", "source": "727", "target": "732"}, {"relation": "hasParent", "type": "hasParent", "source": "728", "target": "727"}, {"relation": "hasChild", "type": "hasChild", "source": "728", "target": "729"}, {"relation": "hasParent", "type": "hasParent", "source": "732", "target": "727"}, {"relation": "hasChild", "type": "hasChild", "source": "732", "target": "733"}, {"relation": "hasParent", "type": "hasParent", "source": "733", "target": "732"}, {"relation": "hasChild", "type": "hasChild", "source": "733", "target": "734"}, {"relation": "hasParent", "type": "hasParent", "source": "734", "target": "733"}, {"relation": "hasChild", "type": "hasChild", "source": "734", "target": "735"}, {"relation": "hasParent", "type": "hasParent", "source": "735", "target": "734"}, {"relation": "hasChild", "type": "hasChild", "source": "735", "target": "736"}, {"relation": "hasChild", "type": "hasChild", "source": "735", "target": "751"}, {"relation": "hasChild", "type": "hasChild", "source": "735", "target": "765"}, {"relation": "hasParent", "type": "hasParent", "source": "736", "target": "735"}, {"relation": "hasChild", "type": "hasChild", "source": "736", "target": "737"}, {"relation": "hasParent", "type": "hasParent", "source": "737", "target": "736"}, {"relation": "hasChild", "type": "hasChild", "source": "737", "target": "738"}, {"relation": "hasChild", "type": "hasChild", "source": "737", "target": "739"}, {"relation": "hasParent", "type": "hasParent", "source": "738", "target": "737"}, {"relation": "hasChild", "type": "hasChild", "source": "738", "target": "946"}, {"relation": "hasParent", "type": "hasParent", "source": "739", "target": "737"}, {"relation": "hasChild", "type": "hasChild", "source": "739", "target": "740"}, {"relation": "hasParent", "type": "hasParent", "source": "740", "target": "739"}, {"relation": "hasChild", "type": "hasChild", "source": "740", "target": "741"}, {"relation": "hasChild", "type": "hasChild", "source": "740", "target": "742"}, {"relation": "hasChild", "type": "hasChild", "source": "740", "target": "749"}, {"relation": "hasChild", "type": "hasChild", "source": "740", "target": "750"}, {"relation": "hasParent", "type": "hasParent", "source": "741", "target": "740"}, {"relation": "hasChild", "type": "hasChild", "source": "741", "target": "5"}, {"relation": "hasParent", "type": "hasParent", "source": "742", "target": "740"}, {"relation": "hasChild", "type": "hasChild", "source": "742", "target": "6"}, {"relation": "hasParent", "type": "hasParent", "source": "749", "target": "740"}, {"relation": "hasChild", "type": "hasChild", "source": "749", "target": "7"}, {"relation": "hasParent", "type": "hasParent", "source": "750", "target": "740"}, {"relation": "hasChild", "type": "hasChild", "source": "750", "target": "8"}, {"relation": "hasParent", "type": "hasParent", "source": "751", "target": "735"}, {"relation": "hasChild", "type": "hasChild", "source": "751", "target": "752"}, {"relation": "hasParent", "type": "hasParent", "source": "752", "target": "751"}, {"relation": "hasChild", "type": "hasChild", "source": "752", "target": "753"}, {"relation": "hasParent", "type": "hasParent", "source": "753", "target": "752"}, {"relation": "hasChild", "type": "hasChild", "source": "753", "target": "754"}, {"relation": "hasParent", "type": "hasParent", "source": "765", "target": "735"}, {"relation": "hasChild", "type": "hasChild", "source": "765", "target": "766"}, {"relation": "hasParent", "type": "hasParent", "source": "766", "target": "765"}, {"relation": "hasChild", "type": "hasChild", "source": "766", "target": "767"}, {"relation": "hasParent", "type": "hasParent", "source": "767", "target": "766"}, {"relation": "hasChild", "type": "hasChild", "source": "767", "target": "768"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000085", "target": "973"}, {"relation": "hasParent", "type": "hasParent", "source": "813", "target": "111"}, {"relation": "hasParent", "type": "hasParent", "source": "112", "target": "111"}, {"relation": "hasChild", "type": "hasChild", "source": "112", "target": "814"}, {"relation": "hasParent", "type": "hasParent", "source": "815", "target": "113"}, {"relation": "hasParent", "type": "hasParent", "source": "114", "target": "113"}, {"relation": "hasChild", "type": "hasChild", "source": "114", "target": "816"}, {"relation": "hasParent", "type": "hasParent", "source": "817", "target": "115"}, {"relation": "hasParent", "type": "hasParent", "source": "116", "target": "115"}, {"relation": "hasChild", "type": "hasChild", "source": "116", "target": "818"}, {"relation": "hasParent", "type": "hasParent", "source": "819", "target": "16"}, {"relation": "hasParent", "type": "hasParent", "source": "117", "target": "16"}, {"relation": "hasChild", "type": "hasChild", "source": "117", "target": "17"}, {"relation": "hasParent", "type": "hasParent", "source": "820", "target": "118"}, {"relation": "hasParent", "type": "hasParent", "source": "119", "target": "118"}, {"relation": "hasChild", "type": "hasChild", "source": "119", "target": "821"}, {"relation": "hasParent", "type": "hasParent", "source": "822", "target": "18"}, {"relation": "hasParent", "type": "hasParent", "source": "120", "target": "18"}, {"relation": "hasChild", "type": "hasChild", "source": "120", "target": "19"}, {"relation": "hasParent", "type": "hasParent", "source": "126", "target": "125"}, {"relation": "hasChild", "type": "hasChild", "source": "126", "target": "823"}, {"relation": "hasParent", "type": "hasParent", "source": "823", "target": "126"}, {"relation": "hasChild", "type": "hasChild", "source": "823", "target": "-1000000008"}, {"relation": "hasParent", "type": "hasParent", "source": "129", "target": "125"}, {"relation": "hasParent", "type": "hasParent", "source": "133", "target": "132"}, {"relation": "hasChild", "type": "hasChild", "source": "133", "target": "824"}, {"relation": "hasParent", "type": "hasParent", "source": "824", "target": "133"}, {"relation": "hasChild", "type": "hasChild", "source": "824", "target": "-1000000009"}, {"relation": "hasParent", "type": "hasParent", "source": "136", "target": "132"}, {"relation": "hasParent", "type": "hasParent", "source": "141", "target": "140"}, {"relation": "hasChild", "type": "hasChild", "source": "141", "target": "825"}, {"relation": "hasParent", "type": "hasParent", "source": "825", "target": "141"}, {"relation": "hasChild", "type": "hasChild", "source": "825", "target": "-1000000010"}, {"relation": "hasParent", "type": "hasParent", "source": "144", "target": "140"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000011", "target": "826"}, {"relation": "hasParent", "type": "hasParent", "source": "211", "target": "210"}, {"relation": "hasParent", "type": "hasParent", "source": "212", "target": "210"}, {"relation": "hasChild", "type": "hasChild", "source": "212", "target": "213"}, {"relation": "hasParent", "type": "hasParent", "source": "501", "target": "500"}, {"relation": "hasChild", "type": "hasChild", "source": "501", "target": "502"}, {"relation": "hasChild", "type": "hasChild", "source": "501", "target": "503"}, {"relation": "hasParent", "type": "hasParent", "source": "523", "target": "522"}, {"relation": "hasChild", "type": "hasChild", "source": "523", "target": "524"}, {"relation": "hasParent", "type": "hasParent", "source": "621", "target": "14"}, {"relation": "hasChild", "type": "hasChild", "source": "621", "target": "622"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000060", "target": "927"}, {"relation": "hasParent", "type": "hasParent", "source": "672", "target": "671"}, {"relation": "hasChild", "type": "hasChild", "source": "672", "target": "673"}, {"relation": "hasChild", "type": "hasChild", "source": "672", "target": "674"}, {"relation": "hasParent", "type": "hasParent", "source": "677", "target": "671"}, {"relation": "hasChild", "type": "hasChild", "source": "677", "target": "678"}, {"relation": "hasChild", "type": "hasChild", "source": "677", "target": "679"}, {"relation": "hasParent", "type": "hasParent", "source": "729", "target": "728"}, {"relation": "hasChild", "type": "hasChild", "source": "729", "target": "730"}, {"relation": "hasParent", "type": "hasParent", "source": "946", "target": "738"}, {"relation": "hasChild", "type": "hasChild", "source": "946", "target": "-1000000071"}, {"relation": "hasParent", "type": "hasParent", "source": "5", "target": "741"}, {"relation": "hasParent", "type": "hasParent", "source": "6", "target": "742"}, {"relation": "hasParent", "type": "hasParent", "source": "7", "target": "749"}, {"relation": "hasParent", "type": "hasParent", "source": "8", "target": "750"}, {"relation": "hasParent", "type": "hasParent", "source": "754", "target": "753"}, {"relation": "hasChild", "type": "hasChild", "source": "754", "target": "755"}, {"relation": "hasChild", "type": "hasChild", "source": "754", "target": "757"}, {"relation": "hasChild", "type": "hasChild", "source": "754", "target": "759"}, {"relation": "hasChild", "type": "hasChild", "source": "754", "target": "761"}, {"relation": "hasChild", "type": "hasChild", "source": "754", "target": "763"}, {"relation": "hasParent", "type": "hasParent", "source": "768", "target": "767"}, {"relation": "hasChild", "type": "hasChild", "source": "768", "target": "769"}, {"relation": "hasChild", "type": "hasChild", "source": "768", "target": "771"}, {"relation": "hasChild", "type": "hasChild", "source": "768", "target": "773"}, {"relation": "hasChild", "type": "hasChild", "source": "768", "target": "775"}, {"relation": "hasChild", "type": "hasChild", "source": "768", "target": "777"}, {"relation": "hasChild", "type": "hasChild", "source": "768", "target": "779"}, {"relation": "hasChild", "type": "hasChild", "source": "768", "target": "781"}, {"relation": "hasChild", "type": "hasChild", "source": "768", "target": "783"}, {"relation": "hasParent", "type": "hasParent", "source": "814", "target": "112"}, {"relation": "hasChild", "type": "hasChild", "source": "814", "target": "-1000000002"}, {"relation": "hasParent", "type": "hasParent", "source": "816", "target": "114"}, {"relation": "hasChild", "type": "hasChild", "source": "816", "target": "-1000000003"}, {"relation": "hasParent", "type": "hasParent", "source": "818", "target": "116"}, {"relation": "hasChild", "type": "hasChild", "source": "818", "target": "-1000000004"}, {"relation": "hasParent", "type": "hasParent", "source": "17", "target": "117"}, {"relation": "hasChild", "type": "hasChild", "source": "17", "target": "-1000000005"}, {"relation": "hasParent", "type": "hasParent", "source": "821", "target": "119"}, {"relation": "hasChild", "type": "hasChild", "source": "821", "target": "-1000000006"}, {"relation": "hasParent", "type": "hasParent", "source": "19", "target": "120"}, {"relation": "hasChild", "type": "hasChild", "source": "19", "target": "-1000000007"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000008", "target": "823"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000009", "target": "824"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000010", "target": "825"}, {"relation": "hasParent", "type": "hasParent", "source": "213", "target": "212"}, {"relation": "hasChild", "type": "hasChild", "source": "213", "target": "214"}, {"relation": "hasParent", "type": "hasParent", "source": "214", "target": "213"}, {"relation": "hasChild", "type": "hasChild", "source": "214", "target": "215"}, {"relation": "hasParent", "type": "hasParent", "source": "215", "target": "214"}, {"relation": "hasChild", "type": "hasChild", "source": "215", "target": "216"}, {"relation": "hasParent", "type": "hasParent", "source": "216", "target": "215"}, {"relation": "hasChild", "type": "hasChild", "source": "216", "target": "218"}, {"relation": "hasChild", "type": "hasChild", "source": "216", "target": "308"}, {"relation": "hasChild", "type": "hasChild", "source": "216", "target": "386"}, {"relation": "hasChild", "type": "hasChild", "source": "216", "target": "388"}, {"relation": "hasParent", "type": "hasParent", "source": "502", "target": "501"}, {"relation": "hasParent", "type": "hasParent", "source": "503", "target": "501"}, {"relation": "hasChild", "type": "hasChild", "source": "503", "target": "504"}, {"relation": "hasParent", "type": "hasParent", "source": "524", "target": "523"}, {"relation": "hasChild", "type": "hasChild", "source": "524", "target": "525"}, {"relation": "hasChild", "type": "hasChild", "source": "524", "target": "526"}, {"relation": "hasParent", "type": "hasParent", "source": "622", "target": "621"}, {"relation": "hasChild", "type": "hasChild", "source": "622", "target": "623"}, {"relation": "hasChild", "type": "hasChild", "source": "622", "target": "624"}, {"relation": "hasParent", "type": "hasParent", "source": "673", "target": "672"}, {"relation": "hasChild", "type": "hasChild", "source": "673", "target": "929"}, {"relation": "hasParent", "type": "hasParent", "source": "674", "target": "672"}, {"relation": "hasChild", "type": "hasChild", "source": "674", "target": "930"}, {"relation": "hasChild", "type": "hasChild", "source": "674", "target": "675"}, {"relation": "hasChild", "type": "hasChild", "source": "674", "target": "676"}, {"relation": "hasParent", "type": "hasParent", "source": "678", "target": "677"}, {"relation": "hasChild", "type": "hasChild", "source": "678", "target": "932"}, {"relation": "hasParent", "type": "hasParent", "source": "679", "target": "677"}, {"relation": "hasChild", "type": "hasChild", "source": "679", "target": "933"}, {"relation": "hasParent", "type": "hasParent", "source": "730", "target": "729"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000071", "target": "946"}, {"relation": "hasParent", "type": "hasParent", "source": "755", "target": "754"}, {"relation": "hasChild", "type": "hasChild", "source": "755", "target": "947"}, {"relation": "hasChild", "type": "hasChild", "source": "755", "target": "756"}, {"relation": "hasParent", "type": "hasParent", "source": "757", "target": "754"}, {"relation": "hasChild", "type": "hasChild", "source": "757", "target": "949"}, {"relation": "hasChild", "type": "hasChild", "source": "757", "target": "758"}, {"relation": "hasParent", "type": "hasParent", "source": "759", "target": "754"}, {"relation": "hasChild", "type": "hasChild", "source": "759", "target": "951"}, {"relation": "hasChild", "type": "hasChild", "source": "759", "target": "760"}, {"relation": "hasParent", "type": "hasParent", "source": "761", "target": "754"}, {"relation": "hasChild", "type": "hasChild", "source": "761", "target": "953"}, {"relation": "hasChild", "type": "hasChild", "source": "761", "target": "762"}, {"relation": "hasParent", "type": "hasParent", "source": "763", "target": "754"}, {"relation": "hasChild", "type": "hasChild", "source": "763", "target": "955"}, {"relation": "hasChild", "type": "hasChild", "source": "763", "target": "764"}, {"relation": "hasParent", "type": "hasParent", "source": "769", "target": "768"}, {"relation": "hasChild", "type": "hasChild", "source": "769", "target": "957"}, {"relation": "hasChild", "type": "hasChild", "source": "769", "target": "770"}, {"relation": "hasParent", "type": "hasParent", "source": "771", "target": "768"}, {"relation": "hasChild", "type": "hasChild", "source": "771", "target": "959"}, {"relation": "hasChild", "type": "hasChild", "source": "771", "target": "772"}, {"relation": "hasParent", "type": "hasParent", "source": "773", "target": "768"}, {"relation": "hasChild", "type": "hasChild", "source": "773", "target": "961"}, {"relation": "hasChild", "type": "hasChild", "source": "773", "target": "774"}, {"relation": "hasParent", "type": "hasParent", "source": "775", "target": "768"}, {"relation": "hasChild", "type": "hasChild", "source": "775", "target": "963"}, {"relation": "hasChild", "type": "hasChild", "source": "775", "target": "776"}, {"relation": "hasParent", "type": "hasParent", "source": "777", "target": "768"}, {"relation": "hasChild", "type": "hasChild", "source": "777", "target": "965"}, {"relation": "hasChild", "type": "hasChild", "source": "777", "target": "778"}, {"relation": "hasParent", "type": "hasParent", "source": "779", "target": "768"}, {"relation": "hasChild", "type": "hasChild", "source": "779", "target": "967"}, {"relation": "hasChild", "type": "hasChild", "source": "779", "target": "780"}, {"relation": "hasParent", "type": "hasParent", "source": "781", "target": "768"}, {"relation": "hasChild", "type": "hasChild", "source": "781", "target": "969"}, {"relation": "hasChild", "type": "hasChild", "source": "781", "target": "782"}, {"relation": "hasParent", "type": "hasParent", "source": "783", "target": "768"}, {"relation": "hasChild", "type": "hasChild", "source": "783", "target": "971"}, {"relation": "hasChild", "type": "hasChild", "source": "783", "target": "784"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000002", "target": "814"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000003", "target": "816"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000004", "target": "818"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000005", "target": "17"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000006", "target": "821"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000007", "target": "19"}, {"relation": "hasParent", "type": "hasParent", "source": "218", "target": "216"}, {"relation": "hasChild", "type": "hasChild", "source": "218", "target": "832"}, {"relation": "hasChild", "type": "hasChild", "source": "218", "target": "221"}, {"relation": "hasChild", "type": "hasChild", "source": "218", "target": "224"}, {"relation": "hasParent", "type": "hasParent", "source": "308", "target": "216"}, {"relation": "hasChild", "type": "hasChild", "source": "308", "target": "853"}, {"relation": "hasChild", "type": "hasChild", "source": "308", "target": "311"}, {"relation": "hasChild", "type": "hasChild", "source": "308", "target": "314"}, {"relation": "hasParent", "type": "hasParent", "source": "386", "target": "216"}, {"relation": "hasChild", "type": "hasChild", "source": "386", "target": "871"}, {"relation": "hasParent", "type": "hasParent", "source": "388", "target": "216"}, {"relation": "hasChild", "type": "hasChild", "source": "388", "target": "872"}, {"relation": "hasChild", "type": "hasChild", "source": "388", "target": "391"}, {"relation": "hasChild", "type": "hasChild", "source": "388", "target": "395"}, {"relation": "hasParent", "type": "hasParent", "source": "504", "target": "503"}, {"relation": "hasChild", "type": "hasChild", "source": "504", "target": "505"}, {"relation": "hasChild", "type": "hasChild", "source": "504", "target": "509"}, {"relation": "hasParent", "type": "hasParent", "source": "505", "target": "504"}, {"relation": "hasChild", "type": "hasChild", "source": "505", "target": "506"}, {"relation": "hasParent", "type": "hasParent", "source": "509", "target": "504"}, {"relation": "hasChild", "type": "hasChild", "source": "509", "target": "510"}, {"relation": "hasParent", "type": "hasParent", "source": "510", "target": "509"}, {"relation": "hasChild", "type": "hasChild", "source": "510", "target": "511"}, {"relation": "hasParent", "type": "hasParent", "source": "511", "target": "510"}, {"relation": "hasChild", "type": "hasChild", "source": "511", "target": "512"}, {"relation": "hasParent", "type": "hasParent", "source": "512", "target": "511"}, {"relation": "hasChild", "type": "hasChild", "source": "512", "target": "4"}, {"relation": "hasParent", "type": "hasParent", "source": "4", "target": "512"}, {"relation": "hasChild", "type": "hasChild", "source": "4", "target": "513"}, {"relation": "hasParent", "type": "hasParent", "source": "513", "target": "4"}, {"relation": "hasChild", "type": "hasChild", "source": "513", "target": "514"}, {"relation": "hasParent", "type": "hasParent", "source": "514", "target": "513"}, {"relation": "hasChild", "type": "hasChild", "source": "514", "target": "515"}, {"relation": "hasChild", "type": "hasChild", "source": "514", "target": "518"}, {"relation": "hasParent", "type": "hasParent", "source": "515", "target": "514"}, {"relation": "hasChild", "type": "hasChild", "source": "515", "target": "516"}, {"relation": "hasParent", "type": "hasParent", "source": "516", "target": "515"}, {"relation": "hasChild", "type": "hasChild", "source": "516", "target": "517"}, {"relation": "hasParent", "type": "hasParent", "source": "518", "target": "514"}, {"relation": "hasParent", "type": "hasParent", "source": "525", "target": "524"}, {"relation": "hasParent", "type": "hasParent", "source": "526", "target": "524"}, {"relation": "hasChild", "type": "hasChild", "source": "526", "target": "527"}, {"relation": "hasParent", "type": "hasParent", "source": "623", "target": "622"}, {"relation": "hasParent", "type": "hasParent", "source": "624", "target": "622"}, {"relation": "hasChild", "type": "hasChild", "source": "624", "target": "625"}, {"relation": "hasParent", "type": "hasParent", "source": "929", "target": "673"}, {"relation": "hasChild", "type": "hasChild", "source": "929", "target": "-1000000061"}, {"relation": "hasParent", "type": "hasParent", "source": "930", "target": "674"}, {"relation": "hasChild", "type": "hasChild", "source": "930", "target": "-1000000062"}, {"relation": "hasChild", "type": "hasChild", "source": "930", "target": "-1000000063"}, {"relation": "hasChild", "type": "hasChild", "source": "930", "target": "-1000000064"}, {"relation": "hasChild", "type": "hasChild", "source": "930", "target": "-1000000065"}, {"relation": "hasChild", "type": "hasChild", "source": "930", "target": "-1000000066"}, {"relation": "hasParent", "type": "hasParent", "source": "675", "target": "674"}, {"relation": "hasChild", "type": "hasChild", "source": "675", "target": "-1000000067"}, {"relation": "hasParent", "type": "hasParent", "source": "676", "target": "674"}, {"relation": "hasChild", "type": "hasChild", "source": "676", "target": "931"}, {"relation": "hasParent", "type": "hasParent", "source": "932", "target": "678"}, {"relation": "hasChild", "type": "hasChild", "source": "932", "target": "-1000000069"}, {"relation": "hasParent", "type": "hasParent", "source": "933", "target": "679"}, {"relation": "hasChild", "type": "hasChild", "source": "933", "target": "-1000000070"}, {"relation": "hasParent", "type": "hasParent", "source": "947", "target": "755"}, {"relation": "hasParent", "type": "hasParent", "source": "756", "target": "755"}, {"relation": "hasChild", "type": "hasChild", "source": "756", "target": "948"}, {"relation": "hasParent", "type": "hasParent", "source": "949", "target": "757"}, {"relation": "hasParent", "type": "hasParent", "source": "758", "target": "757"}, {"relation": "hasChild", "type": "hasChild", "source": "758", "target": "950"}, {"relation": "hasParent", "type": "hasParent", "source": "951", "target": "759"}, {"relation": "hasParent", "type": "hasParent", "source": "760", "target": "759"}, {"relation": "hasChild", "type": "hasChild", "source": "760", "target": "952"}, {"relation": "hasParent", "type": "hasParent", "source": "953", "target": "761"}, {"relation": "hasParent", "type": "hasParent", "source": "762", "target": "761"}, {"relation": "hasChild", "type": "hasChild", "source": "762", "target": "954"}, {"relation": "hasParent", "type": "hasParent", "source": "955", "target": "763"}, {"relation": "hasParent", "type": "hasParent", "source": "764", "target": "763"}, {"relation": "hasChild", "type": "hasChild", "source": "764", "target": "956"}, {"relation": "hasParent", "type": "hasParent", "source": "957", "target": "769"}, {"relation": "hasParent", "type": "hasParent", "source": "770", "target": "769"}, {"relation": "hasChild", "type": "hasChild", "source": "770", "target": "958"}, {"relation": "hasParent", "type": "hasParent", "source": "959", "target": "771"}, {"relation": "hasParent", "type": "hasParent", "source": "772", "target": "771"}, {"relation": "hasChild", "type": "hasChild", "source": "772", "target": "960"}, {"relation": "hasParent", "type": "hasParent", "source": "961", "target": "773"}, {"relation": "hasParent", "type": "hasParent", "source": "774", "target": "773"}, {"relation": "hasChild", "type": "hasChild", "source": "774", "target": "962"}, {"relation": "hasParent", "type": "hasParent", "source": "963", "target": "775"}, {"relation": "hasParent", "type": "hasParent", "source": "776", "target": "775"}, {"relation": "hasChild", "type": "hasChild", "source": "776", "target": "964"}, {"relation": "hasParent", "type": "hasParent", "source": "965", "target": "777"}, {"relation": "hasParent", "type": "hasParent", "source": "778", "target": "777"}, {"relation": "hasChild", "type": "hasChild", "source": "778", "target": "966"}, {"relation": "hasParent", "type": "hasParent", "source": "967", "target": "779"}, {"relation": "hasParent", "type": "hasParent", "source": "780", "target": "779"}, {"relation": "hasChild", "type": "hasChild", "source": "780", "target": "968"}, {"relation": "hasParent", "type": "hasParent", "source": "969", "target": "781"}, {"relation": "hasParent", "type": "hasParent", "source": "782", "target": "781"}, {"relation": "hasChild", "type": "hasChild", "source": "782", "target": "970"}, {"relation": "hasParent", "type": "hasParent", "source": "971", "target": "783"}, {"relation": "hasParent", "type": "hasParent", "source": "784", "target": "783"}, {"relation": "hasChild", "type": "hasChild", "source": "784", "target": "972"}, {"relation": "hasParent", "type": "hasParent", "source": "832", "target": "218"}, {"relation": "hasChild", "type": "hasChild", "source": "832", "target": "-1000000012"}, {"relation": "hasParent", "type": "hasParent", "source": "221", "target": "218"}, {"relation": "hasParent", "type": "hasParent", "source": "224", "target": "218"}, {"relation": "hasParent", "type": "hasParent", "source": "853", "target": "308"}, {"relation": "hasChild", "type": "hasChild", "source": "853", "target": "-1000000013"}, {"relation": "hasParent", "type": "hasParent", "source": "311", "target": "308"}, {"relation": "hasParent", "type": "hasParent", "source": "314", "target": "308"}, {"relation": "hasParent", "type": "hasParent", "source": "871", "target": "386"}, {"relation": "hasChild", "type": "hasChild", "source": "871", "target": "-1000000014"}, {"relation": "hasParent", "type": "hasParent", "source": "872", "target": "388"}, {"relation": "hasChild", "type": "hasChild", "source": "872", "target": "-1000000015"}, {"relation": "hasParent", "type": "hasParent", "source": "391", "target": "388"}, {"relation": "hasParent", "type": "hasParent", "source": "395", "target": "388"}, {"relation": "hasParent", "type": "hasParent", "source": "506", "target": "505"}, {"relation": "hasChild", "type": "hasChild", "source": "506", "target": "507"}, {"relation": "hasParent", "type": "hasParent", "source": "517", "target": "516"}, {"relation": "hasChild", "type": "hasChild", "source": "517", "target": "25"}, {"relation": "hasParent", "type": "hasParent", "source": "527", "target": "526"}, {"relation": "hasChild", "type": "hasChild", "source": "527", "target": "528"}, {"relation": "hasParent", "type": "hasParent", "source": "528", "target": "527"}, {"relation": "hasChild", "type": "hasChild", "source": "528", "target": "529"}, {"relation": "hasParent", "type": "hasParent", "source": "529", "target": "528"}, {"relation": "hasChild", "type": "hasChild", "source": "529", "target": "530"}, {"relation": "hasParent", "type": "hasParent", "source": "530", "target": "529"}, {"relation": "labelledby", "type": "labelledby", "source": "530", "target": "531"}, {"relation": "hasChild", "type": "hasChild", "source": "530", "target": "538"}, {"relation": "hasChild", "type": "hasChild", "source": "530", "target": "540"}, {"relation": "hasParent", "type": "hasParent", "source": "625", "target": "624"}, {"relation": "hasChild", "type": "hasChild", "source": "625", "target": "626"}, {"relation": "hasParent", "type": "hasParent", "source": "626", "target": "625"}, {"relation": "hasChild", "type": "hasChild", "source": "626", "target": "627"}, {"relation": "hasParent", "type": "hasParent", "source": "627", "target": "626"}, {"relation": "hasChild", "type": "hasChild", "source": "627", "target": "628"}, {"relation": "hasParent", "type": "hasParent", "source": "628", "target": "627"}, {"relation": "hasChild", "type": "hasChild", "source": "628", "target": "629"}, {"relation": "hasChild", "type": "hasChild", "source": "628", "target": "644"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000061", "target": "929"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000062", "target": "930"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000063", "target": "930"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000064", "target": "930"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000065", "target": "930"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000066", "target": "930"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000067", "target": "675"}, {"relation": "hasParent", "type": "hasParent", "source": "931", "target": "676"}, {"relation": "hasChild", "type": "hasChild", "source": "931", "target": "-1000000068"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000069", "target": "932"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000070", "target": "933"}, {"relation": "hasParent", "type": "hasParent", "source": "948", "target": "756"}, {"relation": "hasChild", "type": "hasChild", "source": "948", "target": "-1000000072"}, {"relation": "hasParent", "type": "hasParent", "source": "950", "target": "758"}, {"relation": "hasChild", "type": "hasChild", "source": "950", "target": "-1000000073"}, {"relation": "hasParent", "type": "hasParent", "source": "952", "target": "760"}, {"relation": "hasChild", "type": "hasChild", "source": "952", "target": "-1000000074"}, {"relation": "hasParent", "type": "hasParent", "source": "954", "target": "762"}, {"relation": "hasChild", "type": "hasChild", "source": "954", "target": "-1000000075"}, {"relation": "hasParent", "type": "hasParent", "source": "956", "target": "764"}, {"relation": "hasChild", "type": "hasChild", "source": "956", "target": "-1000000076"}, {"relation": "hasParent", "type": "hasParent", "source": "958", "target": "770"}, {"relation": "hasChild", "type": "hasChild", "source": "958", "target": "-1000000077"}, {"relation": "hasParent", "type": "hasParent", "source": "960", "target": "772"}, {"relation": "hasChild", "type": "hasChild", "source": "960", "target": "-1000000078"}, {"relation": "hasParent", "type": "hasParent", "source": "962", "target": "774"}, {"relation": "hasChild", "type": "hasChild", "source": "962", "target": "-1000000079"}, {"relation": "hasParent", "type": "hasParent", "source": "964", "target": "776"}, {"relation": "hasChild", "type": "hasChild", "source": "964", "target": "-1000000080"}, {"relation": "hasParent", "type": "hasParent", "source": "966", "target": "778"}, {"relation": "hasChild", "type": "hasChild", "source": "966", "target": "-1000000081"}, {"relation": "hasParent", "type": "hasParent", "source": "968", "target": "780"}, {"relation": "hasChild", "type": "hasChild", "source": "968", "target": "-1000000082"}, {"relation": "hasParent", "type": "hasParent", "source": "970", "target": "782"}, {"relation": "hasChild", "type": "hasChild", "source": "970", "target": "-1000000083"}, {"relation": "hasParent", "type": "hasParent", "source": "972", "target": "784"}, {"relation": "hasChild", "type": "hasChild", "source": "972", "target": "-1000000084"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000012", "target": "832"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000013", "target": "853"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000014", "target": "871"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000015", "target": "872"}, {"relation": "hasParent", "type": "hasParent", "source": "507", "target": "506"}, {"relation": "hasParent", "type": "hasParent", "source": "25", "target": "517"}, {"relation": "hasChild", "type": "hasChild", "source": "25", "target": "-1000000016"}, {"relation": "hasParent", "type": "hasParent", "source": "531", "target": "530"}, {"relation": "hasChild", "type": "hasChild", "source": "531", "target": "532"}, {"relation": "hasParent", "type": "hasParent", "source": "538", "target": "530"}, {"relation": "hasParent", "type": "hasParent", "source": "540", "target": "530"}, {"relation": "hasChild", "type": "hasChild", "source": "540", "target": "541"}, {"relation": "hasParent", "type": "hasParent", "source": "629", "target": "628"}, {"relation": "hasChild", "type": "hasChild", "source": "629", "target": "630"}, {"relation": "hasParent", "type": "hasParent", "source": "630", "target": "629"}, {"relation": "hasChild", "type": "hasChild", "source": "630", "target": "631"}, {"relation": "hasParent", "type": "hasParent", "source": "631", "target": "630"}, {"relation": "hasChild", "type": "hasChild", "source": "631", "target": "632"}, {"relation": "hasChild", "type": "hasChild", "source": "631", "target": "633"}, {"relation": "hasParent", "type": "hasParent", "source": "632", "target": "631"}, {"relation": "hasChild", "type": "hasChild", "source": "632", "target": "26"}, {"relation": "hasParent", "type": "hasParent", "source": "633", "target": "631"}, {"relation": "hasChild", "type": "hasChild", "source": "633", "target": "634"}, {"relation": "hasChild", "type": "hasChild", "source": "633", "target": "635"}, {"relation": "hasChild", "type": "hasChild", "source": "633", "target": "638"}, {"relation": "hasChild", "type": "hasChild", "source": "633", "target": "643"}, {"relation": "hasParent", "type": "hasParent", "source": "634", "target": "633"}, {"relation": "hasParent", "type": "hasParent", "source": "635", "target": "633"}, {"relation": "hasChild", "type": "hasChild", "source": "635", "target": "636"}, {"relation": "hasChild", "type": "hasChild", "source": "635", "target": "637"}, {"relation": "hasParent", "type": "hasParent", "source": "638", "target": "633"}, {"relation": "hasChild", "type": "hasChild", "source": "638", "target": "13"}, {"relation": "hasChild", "type": "hasChild", "source": "638", "target": "641"}, {"relation": "hasParent", "type": "hasParent", "source": "643", "target": "633"}, {"relation": "hasParent", "type": "hasParent", "source": "644", "target": "628"}, {"relation": "hasChild", "type": "hasChild", "source": "644", "target": "645"}, {"relation": "hasParent", "type": "hasParent", "source": "645", "target": "644"}, {"relation": "hasChild", "type": "hasChild", "source": "645", "target": "646"}, {"relation": "hasChild", "type": "hasChild", "source": "645", "target": "652"}, {"relation": "hasChild", "type": "hasChild", "source": "645", "target": "653"}, {"relation": "hasParent", "type": "hasParent", "source": "646", "target": "645"}, {"relation": "hasChild", "type": "hasChild", "source": "646", "target": "647"}, {"relation": "hasParent", "type": "hasParent", "source": "647", "target": "646"}, {"relation": "hasChild", "type": "hasChild", "source": "647", "target": "925"}, {"relation": "hasChild", "type": "hasChild", "source": "647", "target": "650"}, {"relation": "hasParent", "type": "hasParent", "source": "652", "target": "645"}, {"relation": "hasParent", "type": "hasParent", "source": "653", "target": "645"}, {"relation": "hasChild", "type": "hasChild", "source": "653", "target": "30"}, {"relation": "hasParent", "type": "hasParent", "source": "30", "target": "653"}, {"relation": "hasChild", "type": "hasChild", "source": "30", "target": "654"}, {"relation": "hasChild", "type": "hasChild", "source": "30", "target": "33"}, {"relation": "hasParent", "type": "hasParent", "source": "654", "target": "30"}, {"relation": "hasChild", "type": "hasChild", "source": "654", "target": "31"}, {"relation": "hasChild", "type": "hasChild", "source": "654", "target": "655"}, {"relation": "hasParent", "type": "hasParent", "source": "33", "target": "30"}, {"relation": "hasChild", "type": "hasChild", "source": "33", "target": "34"}, {"relation": "hasChild", "type": "hasChild", "source": "33", "target": "656"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000068", "target": "931"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000072", "target": "948"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000073", "target": "950"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000074", "target": "952"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000075", "target": "954"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000076", "target": "956"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000077", "target": "958"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000078", "target": "960"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000079", "target": "962"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000080", "target": "964"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000081", "target": "966"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000082", "target": "968"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000083", "target": "970"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000084", "target": "972"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000016", "target": "25"}, {"relation": "hasParent", "type": "hasParent", "source": "532", "target": "531"}, {"relation": "hasChild", "type": "hasChild", "source": "532", "target": "892"}, {"relation": "hasParent", "type": "hasParent", "source": "892", "target": "532"}, {"relation": "hasChild", "type": "hasChild", "source": "892", "target": "-1000000017"}, {"relation": "hasParent", "type": "hasParent", "source": "541", "target": "540"}, {"relation": "hasChild", "type": "hasChild", "source": "541", "target": "542"}, {"relation": "hasChild", "type": "hasChild", "source": "541", "target": "545"}, {"relation": "hasChild", "type": "hasChild", "source": "541", "target": "551"}, {"relation": "hasParent", "type": "hasParent", "source": "26", "target": "632"}, {"relation": "hasChild", "type": "hasChild", "source": "26", "target": "-1000000044"}, {"relation": "hasParent", "type": "hasParent", "source": "636", "target": "635"}, {"relation": "hasChild", "type": "hasChild", "source": "636", "target": "919"}, {"relation": "hasParent", "type": "hasParent", "source": "637", "target": "635"}, {"relation": "hasChild", "type": "hasChild", "source": "637", "target": "27"}, {"relation": "hasParent", "type": "hasParent", "source": "13", "target": "638"}, {"relation": "hasChild", "type": "hasChild", "source": "13", "target": "920"}, {"relation": "hasChild", "type": "hasChild", "source": "13", "target": "639"}, {"relation": "hasChild", "type": "hasChild", "source": "13", "target": "28"}, {"relation": "hasChild", "type": "hasChild", "source": "13", "target": "640"}, {"relation": "hasChild", "type": "hasChild", "source": "13", "target": "922"}, {"relation": "hasParent", "type": "hasParent", "source": "641", "target": "638"}, {"relation": "hasChild", "type": "hasChild", "source": "641", "target": "923"}, {"relation": "hasChild", "type": "hasChild", "source": "641", "target": "642"}, {"relation": "hasChild", "type": "hasChild", "source": "641", "target": "29"}, {"relation": "hasParent", "type": "hasParent", "source": "925", "target": "647"}, {"relation": "hasChild", "type": "hasChild", "source": "925", "target": "-1000000055"}, {"relation": "hasParent", "type": "hasParent", "source": "650", "target": "647"}, {"relation": "hasParent", "type": "hasParent", "source": "31", "target": "654"}, {"relation": "hasChild", "type": "hasChild", "source": "31", "target": "-1000000056"}, {"relation": "hasParent", "type": "hasParent", "source": "655", "target": "654"}, {"relation": "hasChild", "type": "hasChild", "source": "655", "target": "32"}, {"relation": "hasParent", "type": "hasParent", "source": "34", "target": "33"}, {"relation": "hasChild", "type": "hasChild", "source": "34", "target": "-1000000058"}, {"relation": "hasParent", "type": "hasParent", "source": "656", "target": "33"}, {"relation": "hasChild", "type": "hasChild", "source": "656", "target": "926"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000017", "target": "892"}, {"relation": "hasParent", "type": "hasParent", "source": "542", "target": "541"}, {"relation": "hasChild", "type": "hasChild", "source": "542", "target": "543"}, {"relation": "hasParent", "type": "hasParent", "source": "543", "target": "542"}, {"relation": "hasChild", "type": "hasChild", "source": "543", "target": "544"}, {"relation": "hasParent", "type": "hasParent", "source": "545", "target": "541"}, {"relation": "hasChild", "type": "hasChild", "source": "545", "target": "546"}, {"relation": "hasChild", "type": "hasChild", "source": "545", "target": "549"}, {"relation": "controls", "type": "controls", "source": "545", "target": "551"}, {"relation": "hasParent", "type": "hasParent", "source": "551", "target": "541"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "552"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "555"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "558"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "561"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "564"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "567"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "570"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "573"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "576"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "579"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "582"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "585"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "588"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "591"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "594"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "597"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "600"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "603"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "606"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "609"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "612"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "615"}, {"relation": "hasChild", "type": "hasChild", "source": "551", "target": "618"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000044", "target": "26"}, {"relation": "hasParent", "type": "hasParent", "source": "919", "target": "636"}, {"relation": "hasChild", "type": "hasChild", "source": "919", "target": "-1000000045"}, {"relation": "hasParent", "type": "hasParent", "source": "27", "target": "637"}, {"relation": "hasChild", "type": "hasChild", "source": "27", "target": "-1000000046"}, {"relation": "hasParent", "type": "hasParent", "source": "920", "target": "13"}, {"relation": "hasChild", "type": "hasChild", "source": "920", "target": "-1000000047"}, {"relation": "hasParent", "type": "hasParent", "source": "639", "target": "13"}, {"relation": "hasChild", "type": "hasChild", "source": "639", "target": "921"}, {"relation": "hasParent", "type": "hasParent", "source": "28", "target": "13"}, {"relation": "hasChild", "type": "hasChild", "source": "28", "target": "-1000000049"}, {"relation": "hasParent", "type": "hasParent", "source": "640", "target": "13"}, {"relation": "hasChild", "type": "hasChild", "source": "640", "target": "-1000000050"}, {"relation": "hasParent", "type": "hasParent", "source": "922", "target": "13"}, {"relation": "hasChild", "type": "hasChild", "source": "922", "target": "-1000000051"}, {"relation": "hasParent", "type": "hasParent", "source": "923", "target": "641"}, {"relation": "hasChild", "type": "hasChild", "source": "923", "target": "-1000000052"}, {"relation": "hasParent", "type": "hasParent", "source": "642", "target": "641"}, {"relation": "hasChild", "type": "hasChild", "source": "642", "target": "924"}, {"relation": "hasParent", "type": "hasParent", "source": "29", "target": "641"}, {"relation": "hasChild", "type": "hasChild", "source": "29", "target": "-1000000054"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000055", "target": "925"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000056", "target": "31"}, {"relation": "hasParent", "type": "hasParent", "source": "32", "target": "655"}, {"relation": "hasChild", "type": "hasChild", "source": "32", "target": "-1000000057"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000058", "target": "34"}, {"relation": "hasParent", "type": "hasParent", "source": "926", "target": "656"}, {"relation": "hasChild", "type": "hasChild", "source": "926", "target": "-1000000059"}, {"relation": "hasParent", "type": "hasParent", "source": "544", "target": "543"}, {"relation": "hasChild", "type": "hasChild", "source": "544", "target": "894"}, {"relation": "hasParent", "type": "hasParent", "source": "894", "target": "544"}, {"relation": "hasChild", "type": "hasChild", "source": "894", "target": "-1000000018"}, {"relation": "hasParent", "type": "hasParent", "source": "546", "target": "545"}, {"relation": "hasChild", "type": "hasChild", "source": "546", "target": "895"}, {"relation": "hasParent", "type": "hasParent", "source": "895", "target": "546"}, {"relation": "hasChild", "type": "hasChild", "source": "895", "target": "-1000000019"}, {"relation": "hasParent", "type": "hasParent", "source": "549", "target": "545"}, {"relation": "hasParent", "type": "hasParent", "source": "552", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "552", "target": "553"}, {"relation": "hasParent", "type": "hasParent", "source": "555", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "555", "target": "556"}, {"relation": "hasParent", "type": "hasParent", "source": "558", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "558", "target": "559"}, {"relation": "hasParent", "type": "hasParent", "source": "561", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "561", "target": "562"}, {"relation": "hasParent", "type": "hasParent", "source": "564", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "564", "target": "565"}, {"relation": "hasParent", "type": "hasParent", "source": "567", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "567", "target": "568"}, {"relation": "hasParent", "type": "hasParent", "source": "570", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "570", "target": "571"}, {"relation": "hasParent", "type": "hasParent", "source": "573", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "573", "target": "574"}, {"relation": "hasParent", "type": "hasParent", "source": "576", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "576", "target": "577"}, {"relation": "hasParent", "type": "hasParent", "source": "579", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "579", "target": "580"}, {"relation": "hasParent", "type": "hasParent", "source": "582", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "582", "target": "583"}, {"relation": "hasParent", "type": "hasParent", "source": "585", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "585", "target": "586"}, {"relation": "hasParent", "type": "hasParent", "source": "588", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "588", "target": "589"}, {"relation": "hasParent", "type": "hasParent", "source": "591", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "591", "target": "592"}, {"relation": "hasParent", "type": "hasParent", "source": "594", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "594", "target": "595"}, {"relation": "hasParent", "type": "hasParent", "source": "597", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "597", "target": "598"}, {"relation": "hasParent", "type": "hasParent", "source": "600", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "600", "target": "601"}, {"relation": "hasParent", "type": "hasParent", "source": "603", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "603", "target": "604"}, {"relation": "hasParent", "type": "hasParent", "source": "606", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "606", "target": "607"}, {"relation": "hasParent", "type": "hasParent", "source": "609", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "609", "target": "610"}, {"relation": "hasParent", "type": "hasParent", "source": "612", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "612", "target": "613"}, {"relation": "hasParent", "type": "hasParent", "source": "615", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "615", "target": "616"}, {"relation": "hasParent", "type": "hasParent", "source": "618", "target": "551"}, {"relation": "hasChild", "type": "hasChild", "source": "618", "target": "619"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000045", "target": "919"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000046", "target": "27"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000047", "target": "920"}, {"relation": "hasParent", "type": "hasParent", "source": "921", "target": "639"}, {"relation": "hasChild", "type": "hasChild", "source": "921", "target": "-1000000048"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000049", "target": "28"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000050", "target": "640"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000051", "target": "922"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000052", "target": "923"}, {"relation": "hasParent", "type": "hasParent", "source": "924", "target": "642"}, {"relation": "hasChild", "type": "hasChild", "source": "924", "target": "-1000000053"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000054", "target": "29"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000057", "target": "32"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000059", "target": "926"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000018", "target": "894"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000019", "target": "895"}, {"relation": "hasParent", "type": "hasParent", "source": "553", "target": "552"}, {"relation": "hasChild", "type": "hasChild", "source": "553", "target": "554"}, {"relation": "hasParent", "type": "hasParent", "source": "556", "target": "555"}, {"relation": "hasChild", "type": "hasChild", "source": "556", "target": "557"}, {"relation": "hasParent", "type": "hasParent", "source": "559", "target": "558"}, {"relation": "hasChild", "type": "hasChild", "source": "559", "target": "560"}, {"relation": "hasParent", "type": "hasParent", "source": "562", "target": "561"}, {"relation": "hasChild", "type": "hasChild", "source": "562", "target": "563"}, {"relation": "hasParent", "type": "hasParent", "source": "565", "target": "564"}, {"relation": "hasChild", "type": "hasChild", "source": "565", "target": "566"}, {"relation": "hasParent", "type": "hasParent", "source": "568", "target": "567"}, {"relation": "hasChild", "type": "hasChild", "source": "568", "target": "569"}, {"relation": "hasParent", "type": "hasParent", "source": "571", "target": "570"}, {"relation": "hasChild", "type": "hasChild", "source": "571", "target": "572"}, {"relation": "hasParent", "type": "hasParent", "source": "574", "target": "573"}, {"relation": "hasChild", "type": "hasChild", "source": "574", "target": "575"}, {"relation": "hasParent", "type": "hasParent", "source": "577", "target": "576"}, {"relation": "hasChild", "type": "hasChild", "source": "577", "target": "578"}, {"relation": "hasParent", "type": "hasParent", "source": "580", "target": "579"}, {"relation": "hasChild", "type": "hasChild", "source": "580", "target": "581"}, {"relation": "hasParent", "type": "hasParent", "source": "583", "target": "582"}, {"relation": "hasChild", "type": "hasChild", "source": "583", "target": "584"}, {"relation": "hasParent", "type": "hasParent", "source": "586", "target": "585"}, {"relation": "hasChild", "type": "hasChild", "source": "586", "target": "587"}, {"relation": "hasParent", "type": "hasParent", "source": "589", "target": "588"}, {"relation": "hasChild", "type": "hasChild", "source": "589", "target": "590"}, {"relation": "hasParent", "type": "hasParent", "source": "592", "target": "591"}, {"relation": "hasChild", "type": "hasChild", "source": "592", "target": "593"}, {"relation": "hasParent", "type": "hasParent", "source": "595", "target": "594"}, {"relation": "hasChild", "type": "hasChild", "source": "595", "target": "596"}, {"relation": "hasParent", "type": "hasParent", "source": "598", "target": "597"}, {"relation": "hasChild", "type": "hasChild", "source": "598", "target": "599"}, {"relation": "hasParent", "type": "hasParent", "source": "601", "target": "600"}, {"relation": "hasChild", "type": "hasChild", "source": "601", "target": "602"}, {"relation": "hasParent", "type": "hasParent", "source": "604", "target": "603"}, {"relation": "hasChild", "type": "hasChild", "source": "604", "target": "605"}, {"relation": "hasParent", "type": "hasParent", "source": "607", "target": "606"}, {"relation": "hasChild", "type": "hasChild", "source": "607", "target": "608"}, {"relation": "hasParent", "type": "hasParent", "source": "610", "target": "609"}, {"relation": "hasChild", "type": "hasChild", "source": "610", "target": "611"}, {"relation": "hasParent", "type": "hasParent", "source": "613", "target": "612"}, {"relation": "hasChild", "type": "hasChild", "source": "613", "target": "614"}, {"relation": "hasParent", "type": "hasParent", "source": "616", "target": "615"}, {"relation": "hasChild", "type": "hasChild", "source": "616", "target": "617"}, {"relation": "hasParent", "type": "hasParent", "source": "619", "target": "618"}, {"relation": "hasChild", "type": "hasChild", "source": "619", "target": "620"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000048", "target": "921"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000053", "target": "924"}, {"relation": "hasParent", "type": "hasParent", "source": "554", "target": "553"}, {"relation": "hasChild", "type": "hasChild", "source": "554", "target": "896"}, {"relation": "hasParent", "type": "hasParent", "source": "896", "target": "554"}, {"relation": "hasChild", "type": "hasChild", "source": "896", "target": "-1000000020"}, {"relation": "hasParent", "type": "hasParent", "source": "557", "target": "556"}, {"relation": "hasChild", "type": "hasChild", "source": "557", "target": "897"}, {"relation": "hasParent", "type": "hasParent", "source": "897", "target": "557"}, {"relation": "hasChild", "type": "hasChild", "source": "897", "target": "-1000000021"}, {"relation": "hasParent", "type": "hasParent", "source": "560", "target": "559"}, {"relation": "hasChild", "type": "hasChild", "source": "560", "target": "898"}, {"relation": "hasParent", "type": "hasParent", "source": "898", "target": "560"}, {"relation": "hasChild", "type": "hasChild", "source": "898", "target": "-1000000022"}, {"relation": "hasParent", "type": "hasParent", "source": "563", "target": "562"}, {"relation": "hasChild", "type": "hasChild", "source": "563", "target": "899"}, {"relation": "hasParent", "type": "hasParent", "source": "899", "target": "563"}, {"relation": "hasChild", "type": "hasChild", "source": "899", "target": "-1000000023"}, {"relation": "hasParent", "type": "hasParent", "source": "566", "target": "565"}, {"relation": "hasChild", "type": "hasChild", "source": "566", "target": "900"}, {"relation": "hasParent", "type": "hasParent", "source": "900", "target": "566"}, {"relation": "hasChild", "type": "hasChild", "source": "900", "target": "-1000000024"}, {"relation": "hasParent", "type": "hasParent", "source": "569", "target": "568"}, {"relation": "hasChild", "type": "hasChild", "source": "569", "target": "901"}, {"relation": "hasParent", "type": "hasParent", "source": "901", "target": "569"}, {"relation": "hasChild", "type": "hasChild", "source": "901", "target": "-1000000025"}, {"relation": "hasParent", "type": "hasParent", "source": "572", "target": "571"}, {"relation": "hasChild", "type": "hasChild", "source": "572", "target": "902"}, {"relation": "hasParent", "type": "hasParent", "source": "902", "target": "572"}, {"relation": "hasChild", "type": "hasChild", "source": "902", "target": "-1000000026"}, {"relation": "hasParent", "type": "hasParent", "source": "575", "target": "574"}, {"relation": "hasChild", "type": "hasChild", "source": "575", "target": "903"}, {"relation": "hasParent", "type": "hasParent", "source": "903", "target": "575"}, {"relation": "hasChild", "type": "hasChild", "source": "903", "target": "-1000000027"}, {"relation": "hasParent", "type": "hasParent", "source": "578", "target": "577"}, {"relation": "hasChild", "type": "hasChild", "source": "578", "target": "904"}, {"relation": "hasParent", "type": "hasParent", "source": "904", "target": "578"}, {"relation": "hasChild", "type": "hasChild", "source": "904", "target": "-1000000028"}, {"relation": "hasParent", "type": "hasParent", "source": "581", "target": "580"}, {"relation": "hasChild", "type": "hasChild", "source": "581", "target": "905"}, {"relation": "hasParent", "type": "hasParent", "source": "905", "target": "581"}, {"relation": "hasChild", "type": "hasChild", "source": "905", "target": "-1000000029"}, {"relation": "hasParent", "type": "hasParent", "source": "584", "target": "583"}, {"relation": "hasChild", "type": "hasChild", "source": "584", "target": "906"}, {"relation": "hasParent", "type": "hasParent", "source": "906", "target": "584"}, {"relation": "hasChild", "type": "hasChild", "source": "906", "target": "-1000000030"}, {"relation": "hasParent", "type": "hasParent", "source": "587", "target": "586"}, {"relation": "hasChild", "type": "hasChild", "source": "587", "target": "907"}, {"relation": "hasParent", "type": "hasParent", "source": "907", "target": "587"}, {"relation": "hasChild", "type": "hasChild", "source": "907", "target": "-1000000031"}, {"relation": "hasChild", "type": "hasChild", "source": "907", "target": "-1000000032"}, {"relation": "hasParent", "type": "hasParent", "source": "590", "target": "589"}, {"relation": "hasChild", "type": "hasChild", "source": "590", "target": "908"}, {"relation": "hasParent", "type": "hasParent", "source": "908", "target": "590"}, {"relation": "hasChild", "type": "hasChild", "source": "908", "target": "-1000000033"}, {"relation": "hasParent", "type": "hasParent", "source": "593", "target": "592"}, {"relation": "hasChild", "type": "hasChild", "source": "593", "target": "909"}, {"relation": "hasParent", "type": "hasParent", "source": "909", "target": "593"}, {"relation": "hasChild", "type": "hasChild", "source": "909", "target": "-1000000034"}, {"relation": "hasParent", "type": "hasParent", "source": "596", "target": "595"}, {"relation": "hasChild", "type": "hasChild", "source": "596", "target": "910"}, {"relation": "hasParent", "type": "hasParent", "source": "910", "target": "596"}, {"relation": "hasChild", "type": "hasChild", "source": "910", "target": "-1000000035"}, {"relation": "hasParent", "type": "hasParent", "source": "599", "target": "598"}, {"relation": "hasChild", "type": "hasChild", "source": "599", "target": "911"}, {"relation": "hasParent", "type": "hasParent", "source": "911", "target": "599"}, {"relation": "hasChild", "type": "hasChild", "source": "911", "target": "-1000000036"}, {"relation": "hasParent", "type": "hasParent", "source": "602", "target": "601"}, {"relation": "hasChild", "type": "hasChild", "source": "602", "target": "912"}, {"relation": "hasParent", "type": "hasParent", "source": "912", "target": "602"}, {"relation": "hasChild", "type": "hasChild", "source": "912", "target": "-1000000037"}, {"relation": "hasParent", "type": "hasParent", "source": "605", "target": "604"}, {"relation": "hasChild", "type": "hasChild", "source": "605", "target": "913"}, {"relation": "hasParent", "type": "hasParent", "source": "913", "target": "605"}, {"relation": "hasChild", "type": "hasChild", "source": "913", "target": "-1000000038"}, {"relation": "hasParent", "type": "hasParent", "source": "608", "target": "607"}, {"relation": "hasChild", "type": "hasChild", "source": "608", "target": "914"}, {"relation": "hasParent", "type": "hasParent", "source": "914", "target": "608"}, {"relation": "hasChild", "type": "hasChild", "source": "914", "target": "-1000000039"}, {"relation": "hasParent", "type": "hasParent", "source": "611", "target": "610"}, {"relation": "hasChild", "type": "hasChild", "source": "611", "target": "915"}, {"relation": "hasParent", "type": "hasParent", "source": "915", "target": "611"}, {"relation": "hasChild", "type": "hasChild", "source": "915", "target": "-1000000040"}, {"relation": "hasParent", "type": "hasParent", "source": "614", "target": "613"}, {"relation": "hasChild", "type": "hasChild", "source": "614", "target": "916"}, {"relation": "hasParent", "type": "hasParent", "source": "916", "target": "614"}, {"relation": "hasChild", "type": "hasChild", "source": "916", "target": "-1000000041"}, {"relation": "hasParent", "type": "hasParent", "source": "617", "target": "616"}, {"relation": "hasChild", "type": "hasChild", "source": "617", "target": "917"}, {"relation": "hasParent", "type": "hasParent", "source": "917", "target": "617"}, {"relation": "hasChild", "type": "hasChild", "source": "917", "target": "-1000000042"}, {"relation": "hasParent", "type": "hasParent", "source": "620", "target": "619"}, {"relation": "hasChild", "type": "hasChild", "source": "620", "target": "918"}, {"relation": "hasParent", "type": "hasParent", "source": "918", "target": "620"}, {"relation": "hasChild", "type": "hasChild", "source": "918", "target": "-1000000043"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000020", "target": "896"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000021", "target": "897"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000022", "target": "898"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000023", "target": "899"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000024", "target": "900"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000025", "target": "901"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000026", "target": "902"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000027", "target": "903"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000028", "target": "904"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000029", "target": "905"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000030", "target": "906"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000031", "target": "907"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000032", "target": "907"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000033", "target": "908"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000034", "target": "909"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000035", "target": "910"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000036", "target": "911"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000037", "target": "912"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000038", "target": "913"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000039", "target": "914"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000040", "target": "915"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000041", "target": "916"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000042", "target": "917"}, {"relation": "hasParent", "type": "hasParent", "source": "-1000000043", "target": "918"}]} \ No newline at end of file diff --git a/scripts/sviluppo_wcag/target_size_extractor_script.py b/scripts/sviluppo_wcag/target_size_extractor_script.py index baded2a..d07cd32 100644 --- a/scripts/sviluppo_wcag/target_size_extractor_script.py +++ b/scripts/sviluppo_wcag/target_size_extractor_script.py @@ -854,15 +854,16 @@ class TargetSizeExtractor: #vp_all_rel = _to_viewport_coords(vp_all_rest, scroll_y) vp_all_rel = _to_viewport_coords(vp_all, scroll_y) - annotated_img = _draw_bounding_box_on_bytes(raw_png, vp_all_rel) + #annotated_img = _draw_bounding_box_on_bytes(raw_png, vp_all_rel) + annotated_img = _draw_bounding_box_on_bytes(raw_png, [])# to avoid all the bounding box drawing # Draw orange first (larger radius) → red on top - annotated_img = _draw_circles_on_bytes( + """annotated_img = _draw_circles_on_bytes( _pil_to_png_bytes(annotated_img), vp_44_only_rel, self.COLOR_44, radius=self.THRESHOLD_ENHANCED // 2, # 22 px - ) + )""" annotated_img = _draw_circles_on_bytes( _pil_to_png_bytes(annotated_img), vp_24_rel, diff --git a/scripts/test_utenti_03_2026/rebuttal.ipynb b/scripts/test_utenti_03_2026/rebuttal.ipynb new file mode 100644 index 0000000..6778ac9 --- /dev/null +++ b/scripts/test_utenti_03_2026/rebuttal.ipynb @@ -0,0 +1,1232 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 36, + "id": "4ab705a5", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import numpy as np\n", + "from scipy.stats import pearsonr\n", + "from itertools import combinations" + ] + }, + { + "cell_type": "markdown", + "id": "40990ff4", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "e7e990e9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
idinsertion_timeinsert_typepage_urluserimage_urloriginal_alt_texthtml_contextimmediate_contextnearby_context...llm_assessment_2llm_judgment_2llm_evaluation_result_2llm_alt_text_2llm_model_2user_assessmentuser_alt_textuser_llm_assessment_1user_llm_assessment_2digital_accessibility_experience
0325/03/2026 08:40wcag_user_llm_alttext_assessmentsCNN_Home_user_test.htmluser_1CNN_Home_user_test_files/117871-minelayersstri...117871_MinelayersStriaghOfHormuz_clean.00_00_0...No textual context foundNo immediate context found<span> [107px]: 0:34 <a> [125px]: Video\\n ......1failureThe original alt-text is a filename and does n...Unclassified thermal image of a boat on water,...gemma3:4b-q8_0-wcag1Ripresa aerea in bianco e nero, effettuata con...214
1325/03/2026 08:40wcag_user_llm_alttext_assessmentsCNN_Home_user_test.htmluser_1CNN_Home_user_test_files/sr2-courtesy-of-tom-w...Smiljan Radić.No textual context foundNo immediate context found<a> [131px]: Pritzker Prize 2026: The winner i......2failureThe alt-text 'Smiljan Radi఻' is insufficient a...Architect standing in a modern corridor with g...gemma3:4b-q8_0-wcag1Ritratto dell'architetto cileno Smiljan Radić:...114
2325/03/2026 08:40wcag_user_llm_alttext_assessmentsCNN_Home_user_test.htmluser_1CNN_Home_user_test_files/thumb-3-2026022520405...thumb 3.jpgNo textual context foundNo immediate context found<a> [98px]: Grace Cary/Moment RF/Getty Images ......1failureThe alt-text 'thumb 3.jpg' is inappropriate as...A person sitting at a desk with a computer and...gemma3:4b-q8_0-wcag1134
3325/03/2026 08:40wcag_user_llm_alttext_assessmentsCNN_Home_user_test.htmluser_1CNN_Home_user_test_files/screenshot-2026-03-11...Screenshot 2026-03-11 at 3.40.55 PM.pngNo textual context foundNo immediate context found<h2> [135px]: Weather <a> [141px]: Say goodbye......1failureThe alt-text 'Screenshot 2026-03-11 at 3.40.55...Map of U.S. states with color-coded regions re...gemma3:4b-q8_0-wcag1154
4325/03/2026 08:40wcag_user_llm_alttext_assessmentsCNN_Home_user_test.htmluser_1CNN_Home_user_test_files/thumbnail-kim-guns-nk...thumbnail kim guns nk 1 vrtc.jpgNo textual context foundNo immediate context found<span> [149px]: Kim Jong Un and daughter fire ......1failureThe original alt-text 'thumbnail kim guns nk 1...North Korean leader holding a handgun indoors ...gemma3:4b-q8_0-wcag1154
..................................................................
64031708/04/2026 19:38wcag_user_llm_alttext_assessmentsNike_men_user_test.htmluser_30Nike_men_user_test_files/M+ACG+SFADV+PHANTAZMA...Nike ACG \"Phantazma\" Men's Storm-FIT ADV Jacket<a>: Nike ACG \"Phantazma\"No immediate context found<a> [93px]: Nike ACG \"Phantazma\"...4successThe alt-text is appropriate as it accurately d...Nike ACG 'Phantazma' Men's Storm-FIT ADV Jacke...gemma3:4b-q8_0-wcag5Nike ACG \"Phantazma\" men's jacket543
64131708/04/2026 19:38wcag_user_llm_alttext_assessmentsNike_men_user_test.htmluser_30Nike_men_user_test_files/M+ACG+DFADV+SCNDSNRSE...Nike ACG \"Second Sunrise\" Men's Dri-FIT ADV 5\"...<a>: Nike ACG \"Second Sunrise\"No immediate context found<a> [97px]: Nike ACG \"Second Sunrise\"...3warningThe alt-text provides product details but does...Model wearing a green ACG jacket and shorts, s...gemma3:4b-q8_0-wcag5Nike ACG \"Second Sunrise\" men's shorts523
64231708/04/2026 19:38wcag_user_llm_alttext_assessmentsNike_men_user_test.htmluser_30Nike_men_user_test_files/DB+M+NK+DF+WVN+GAME+J...Book Men's Dri-FIT Woven Game Jacket<a>: BookNo immediate context found<a> [97px]: Book <p> [171px]: See Price in Bag...2failureThe original alt-text 'Book Men's Dri-FIT Wove...Grey Nike men's woven game jacket with zipper ...gemma3:4b-q8_0-wcag5Book men's Dri-FIT woven game jacket223
64331708/04/2026 19:38wcag_user_llm_alttext_assessmentsNike_men_user_test.htmluser_30Nike_men_user_test_files/DB+M+NK+DF+WVN+GAME+P...Book Men's Dri-FIT Woven Game Pants<a>: BookNo immediate context found<a> [97px]: Book...3warningThe alt-text 'Book Men's Dri-FIT Woven Game Pa...Gray Nike men's Dri-FIT woven game pants with ...gemma3:4b-q8_0-wcag5Book men's Dri-FIT woven game jacket213
64431708/04/2026 19:38wcag_user_llm_alttext_assessmentsNike_men_user_test.htmluser_30Nike_men_user_test_files/M+NK+DFADV+STRIDE+NVL...Nike Stride Plus Men's Dri-FIT ADV Short-Sleev...<a>: Nike Stride PlusNo immediate context found<a> [97px]: Nike Stride Plus...4successThe alt-text is appropriate as it accurately d...Nike Stride Plus Men's Dri-FIT ADV Short-Sleev...gemma3:4b-q8_0-wcag5Nike Stride Plus men's running top533
\n", + "

645 rows × 29 columns

\n", + "
" + ], + "text/plain": [ + " id insertion_time insert_type \\\n", + "0 3 25/03/2026 08:40 wcag_user_llm_alttext_assessments \n", + "1 3 25/03/2026 08:40 wcag_user_llm_alttext_assessments \n", + "2 3 25/03/2026 08:40 wcag_user_llm_alttext_assessments \n", + "3 3 25/03/2026 08:40 wcag_user_llm_alttext_assessments \n", + "4 3 25/03/2026 08:40 wcag_user_llm_alttext_assessments \n", + ".. ... ... ... \n", + "640 317 08/04/2026 19:38 wcag_user_llm_alttext_assessments \n", + "641 317 08/04/2026 19:38 wcag_user_llm_alttext_assessments \n", + "642 317 08/04/2026 19:38 wcag_user_llm_alttext_assessments \n", + "643 317 08/04/2026 19:38 wcag_user_llm_alttext_assessments \n", + "644 317 08/04/2026 19:38 wcag_user_llm_alttext_assessments \n", + "\n", + " page_url user \\\n", + "0 CNN_Home_user_test.html user_1 \n", + "1 CNN_Home_user_test.html user_1 \n", + "2 CNN_Home_user_test.html user_1 \n", + "3 CNN_Home_user_test.html user_1 \n", + "4 CNN_Home_user_test.html user_1 \n", + ".. ... ... \n", + "640 Nike_men_user_test.html user_30 \n", + "641 Nike_men_user_test.html user_30 \n", + "642 Nike_men_user_test.html user_30 \n", + "643 Nike_men_user_test.html user_30 \n", + "644 Nike_men_user_test.html user_30 \n", + "\n", + " image_url \\\n", + "0 CNN_Home_user_test_files/117871-minelayersstri... \n", + "1 CNN_Home_user_test_files/sr2-courtesy-of-tom-w... \n", + "2 CNN_Home_user_test_files/thumb-3-2026022520405... \n", + "3 CNN_Home_user_test_files/screenshot-2026-03-11... \n", + "4 CNN_Home_user_test_files/thumbnail-kim-guns-nk... \n", + ".. ... \n", + "640 Nike_men_user_test_files/M+ACG+SFADV+PHANTAZMA... \n", + "641 Nike_men_user_test_files/M+ACG+DFADV+SCNDSNRSE... \n", + "642 Nike_men_user_test_files/DB+M+NK+DF+WVN+GAME+J... \n", + "643 Nike_men_user_test_files/DB+M+NK+DF+WVN+GAME+P... \n", + "644 Nike_men_user_test_files/M+NK+DFADV+STRIDE+NVL... \n", + "\n", + " original_alt_text \\\n", + "0 117871_MinelayersStriaghOfHormuz_clean.00_00_0... \n", + "1 Smiljan Radić. \n", + "2 thumb 3.jpg \n", + "3 Screenshot 2026-03-11 at 3.40.55 PM.png \n", + "4 thumbnail kim guns nk 1 vrtc.jpg \n", + ".. ... \n", + "640 Nike ACG \"Phantazma\" Men's Storm-FIT ADV Jacket \n", + "641 Nike ACG \"Second Sunrise\" Men's Dri-FIT ADV 5\"... \n", + "642 Book Men's Dri-FIT Woven Game Jacket \n", + "643 Book Men's Dri-FIT Woven Game Pants \n", + "644 Nike Stride Plus Men's Dri-FIT ADV Short-Sleev... \n", + "\n", + " html_context immediate_context \\\n", + "0 No textual context found No immediate context found \n", + "1 No textual context found No immediate context found \n", + "2 No textual context found No immediate context found \n", + "3 No textual context found No immediate context found \n", + "4 No textual context found No immediate context found \n", + ".. ... ... \n", + "640 : Nike ACG \"Phantazma\" No immediate context found \n", + "641 : Nike ACG \"Second Sunrise\" No immediate context found \n", + "642 : Book No immediate context found \n", + "643 : Book No immediate context found \n", + "644 : Nike Stride Plus No immediate context found \n", + "\n", + " nearby_context ... llm_assessment_2 \\\n", + "0 [107px]: 0:34 [125px]: Video\\n ... ... 1 \n", + "1 [131px]: Pritzker Prize 2026: The winner i... ... 2 \n", + "2 [98px]: Grace Cary/Moment RF/Getty Images ... ... 1 \n", + "3

[135px]: Weather [141px]: Say goodbye... ... 1 \n", + "4 [149px]: Kim Jong Un and daughter fire ... ... 1 \n", + ".. ... ... ... \n", + "640 [93px]: Nike ACG \"Phantazma\" ... 4 \n", + "641 [97px]: Nike ACG \"Second Sunrise\" ... 3 \n", + "642 [97px]: Book

[171px]: See Price in Bag ... 2 \n", + "643 [97px]: Book ... 3 \n", + "644 [97px]: Nike Stride Plus ... 4 \n", + "\n", + " llm_judgment_2 llm_evaluation_result_2 \\\n", + "0 failure The original alt-text is a filename and does n... \n", + "1 failure The alt-text 'Smiljan Radi఻' is insufficient a... \n", + "2 failure The alt-text 'thumb 3.jpg' is inappropriate as... \n", + "3 failure The alt-text 'Screenshot 2026-03-11 at 3.40.55... \n", + "4 failure The original alt-text 'thumbnail kim guns nk 1... \n", + ".. ... ... \n", + "640 success The alt-text is appropriate as it accurately d... \n", + "641 warning The alt-text provides product details but does... \n", + "642 failure The original alt-text 'Book Men's Dri-FIT Wove... \n", + "643 warning The alt-text 'Book Men's Dri-FIT Woven Game Pa... \n", + "644 success The alt-text is appropriate as it accurately d... \n", + "\n", + " llm_alt_text_2 llm_model_2 \\\n", + "0 Unclassified thermal image of a boat on water,... gemma3:4b-q8_0-wcag \n", + "1 Architect standing in a modern corridor with g... gemma3:4b-q8_0-wcag \n", + "2 A person sitting at a desk with a computer and... gemma3:4b-q8_0-wcag \n", + "3 Map of U.S. states with color-coded regions re... gemma3:4b-q8_0-wcag \n", + "4 North Korean leader holding a handgun indoors ... gemma3:4b-q8_0-wcag \n", + ".. ... ... \n", + "640 Nike ACG 'Phantazma' Men's Storm-FIT ADV Jacke... gemma3:4b-q8_0-wcag \n", + "641 Model wearing a green ACG jacket and shorts, s... gemma3:4b-q8_0-wcag \n", + "642 Grey Nike men's woven game jacket with zipper ... gemma3:4b-q8_0-wcag \n", + "643 Gray Nike men's Dri-FIT woven game pants with ... gemma3:4b-q8_0-wcag \n", + "644 Nike Stride Plus Men's Dri-FIT ADV Short-Sleev... gemma3:4b-q8_0-wcag \n", + "\n", + " user_assessment user_alt_text \\\n", + "0 1 Ripresa aerea in bianco e nero, effettuata con... \n", + "1 1 Ritratto dell'architetto cileno Smiljan Radić:... \n", + "2 1 \n", + "3 1 \n", + "4 1 \n", + ".. ... ... \n", + "640 5 Nike ACG \"Phantazma\" men's jacket \n", + "641 5 Nike ACG \"Second Sunrise\" men's shorts \n", + "642 5 Book men's Dri-FIT woven game jacket \n", + "643 5 Book men's Dri-FIT woven game jacket \n", + "644 5 Nike Stride Plus men's running top \n", + "\n", + " user_llm_assessment_1 user_llm_assessment_2 \\\n", + "0 2 1 \n", + "1 1 1 \n", + "2 1 3 \n", + "3 1 5 \n", + "4 1 5 \n", + ".. ... ... \n", + "640 5 4 \n", + "641 5 2 \n", + "642 2 2 \n", + "643 2 1 \n", + "644 5 3 \n", + "\n", + " digital_accessibility_experience \n", + "0 4 \n", + "1 4 \n", + "2 4 \n", + "3 4 \n", + "4 4 \n", + ".. ... \n", + "640 3 \n", + "641 3 \n", + "642 3 \n", + "643 3 \n", + "644 3 \n", + "\n", + "[645 rows x 29 columns]" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.read_csv(\"DB_assets2026_submission.csv\",sep=\";\",keep_default_na=False)\n", + "df" + ] + }, + { + "cell_type": "markdown", + "id": "7e6bf010", + "metadata": {}, + "source": [ + "## stringhe vuote iniziali (possibili decorative)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "b73cc3db", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total rows: 645\n", + "Empty string '': 23 (3.57%)\n", + "Non-empty: 622 (96.43%)\n" + ] + } + ], + "source": [ + "total = len(df)\n", + "empty_str = (df['original_alt_text'] == '').sum()\n", + "pct_empty_str = empty_str / total * 100\n", + "\n", + "print(f\"Total rows: {total}\")\n", + "print(f\"Empty string '': {empty_str} ({pct_empty_str:.2f}%)\")\n", + "print(f\"Non-empty: {total - empty_str} ({(total - empty_str) / total * 100:.2f}%)\")" + ] + }, + { + "cell_type": "markdown", + "id": "666dcaec", + "metadata": {}, + "source": [ + "## stringhe vuote utente\n", + "il numero delle stringhe vuote dell'utente non è affidabile, semplicemnete magari non le hanno scritte per tempo" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "5471839f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total rows: 645\n", + "Empty string '': 161 (24.96%)\n", + "Non-empty: 484 (75.04%)\n" + ] + } + ], + "source": [ + "total = len(df)\n", + "empty_user_str = (df['user_alt_text'] == '').sum()\n", + "pct_empty_user_str = empty_user_str / total * 100\n", + "\n", + "print(f\"Total rows: {total}\")\n", + "print(f\"Empty string '': {empty_user_str} ({pct_empty_user_str:.2f}%)\")\n", + "print(f\"Non-empty: {total - empty_user_str} ({(total - empty_user_str) / total * 100:.2f}%)\")" + ] + }, + { + "cell_type": "markdown", + "id": "a1233e01", + "metadata": {}, + "source": [ + "## stringhe vuote LLM1" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "1a0bd3cb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total rows: 645\n", + "Empty string '': 0 (0.00%)\n", + "Non-empty: 645 (100.00%)\n" + ] + } + ], + "source": [ + "total = len(df)\n", + "empty_llm1_str = (df['llm_alt_text_1'] == '').sum()\n", + "pct_empty_llm1_str = empty_llm1_str / total * 100\n", + "\n", + "print(f\"Total rows: {total}\")\n", + "print(f\"Empty string '': {empty_llm1_str} ({pct_empty_llm1_str:.2f}%)\")\n", + "print(f\"Non-empty: {total - empty_llm1_str} ({(total - empty_llm1_str) / total * 100:.2f}%)\")" + ] + }, + { + "cell_type": "markdown", + "id": "b9e4fa34", + "metadata": {}, + "source": [ + "## stringhe vuote LLM2" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "691b95f0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total rows: 645\n", + "Empty string '': 0 (0.00%)\n", + "Non-empty: 645 (100.00%)\n" + ] + } + ], + "source": [ + "total = len(df)\n", + "empty_llm2_str = (df['llm_alt_text_2'] == '').sum()\n", + "pct_empty_llm2_str = empty_llm2_str / total * 100\n", + "\n", + "print(f\"Total rows: {total}\")\n", + "print(f\"Empty string '': {empty_llm2_str} ({pct_empty_llm2_str:.2f}%)\")\n", + "print(f\"Non-empty: {total - empty_llm2_str} ({(total - empty_llm2_str) / total * 100:.2f}%)\")" + ] + }, + { + "cell_type": "markdown", + "id": "0e550dae", + "metadata": {}, + "source": [ + "# stringhe vuote sia originali che utente" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "2f401476", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total rows: 645\n", + "Both original_alt_text and user_alt_text empty: 2 (0.31%)\n", + "\n", + "Rows where both are empty:\n", + " page_url original_alt_text user_alt_text llm_alt_text_1 llm_alt_text_2\n", + "314 LiveScience_user_test.html Close-up of a tick on a green leaf, relevant to tick-triggered meat allergy. Close-up of a red tick on a green leaf, illustrating a potential source of allergen exposure.\n", + "425 LiveScience_user_test.html Close-up of a tick on a leaf, related to a meat allergy article. Close-up of a red tick on a green leaf, representing a tick bite causing meat allergy.\n" + ] + } + ], + "source": [ + "total = len(df)\n", + "both_empty_mask = (df['original_alt_text'] == '') & (df['user_alt_text'] == '')\n", + "both_empty = both_empty_mask.sum()\n", + "pct_both_empty = both_empty / total * 100\n", + "\n", + "print(f\"Total rows: {total}\")\n", + "print(f\"Both original_alt_text and user_alt_text empty: {both_empty} ({pct_both_empty:.2f}%)\")\n", + "\n", + "cols = ['page_url', 'original_alt_text', 'user_alt_text', 'llm_alt_text_1', 'llm_alt_text_2']\n", + "print(\"\\nRows where both are empty:\")\n", + "print(df.loc[both_empty_mask, cols].to_string())" + ] + }, + { + "cell_type": "markdown", + "id": "d1f86a99", + "metadata": {}, + "source": [ + "## visione generale a partire stringhe vuote iniziali" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "c1803e1e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total rows: 645\n", + "Empty string '': 23 (3.57%)\n", + "Non-empty: 622 (96.43%)\n", + "\n", + "Rows with empty original_alt_text:\n", + " page_url image_url user_alt_text llm_alt_text_1 llm_alt_text_2\n", + "145 LiveScience_user_test.html LiveScience_user_test_files/u43eWTJn8DpGki9c8QSSrN-450-80.jpg Image of an orthopantomography Panoramic dental X-ray illustrating the anatomy and structure of teeth. X-ray image of the lower jaw with teeth and surrounding structures, illustrating dental anatomy.\n", + "147 LiveScience_user_test.html LiveScience_user_test_files/7MsncjgVUQpPKLgeG7xoa9-450-80.jpg A woman lifting weights in a gym with warm lighting Person lifting a heavy barbell in a gym, emphasizing strength. Person using a barbell in a gym setting, possibly illustrating strength training.\n", + "180 LiveScience_user_test.html LiveScience_user_test_files/u6iYoHMYax5KaGypJm5xVa-450-80.jpg bicchiere con liquido e fumo Liquid-nitrogen-infused cocktail emitting vapor, related to health risks discussed in the article. A liquid nitrogen infused cocktail with smoke releasing from a glass on a bar tray.\n", + "181 LiveScience_user_test.html LiveScience_user_test_files/3iLiUVFx8sncQEnzFPD8hE-450-80.jpg immagine con vari alimenti, tra cui pesce, carne bianca, uova, formaggio e legumi Assorted protein-rich foods including fish, meat, eggs, legumes, nuts, and cheese. A collection of protein-rich foods including fish, nuts, seeds, dairy products, and meat on a wooden table.\n", + "182 LiveScience_user_test.html LiveScience_user_test_files/5BdJ4FkXHuit3LMYwmiNxB-450-80.jpg esempio di piramide alimentare Illustration of the new US food pyramid emphasizing proteins, healthy fats, full-fat dairy, vegetables, fruits, and whole grains. Image illustrating healthy fats, protein sources, and whole grains as part of a balanced diet.\n", + "245 LiveScience_user_test.html LiveScience_user_test_files/u6iYoHMYax5KaGypJm5xVa-450-80.jpg A glass full of steaming liquid nitrogen on a tray used for theatrical effect. Liquid-nitrogen cocktail emitting vapor on a tray, related to health risks. Liquid nitrogen cocktail popping a man's stomach like a balloon in a bar setting.\n", + "246 LiveScience_user_test.html LiveScience_user_test_files/3iLiUVFx8sncQEnzFPD8hE-450-80.jpg Dishes with protein-rich foods: fish, legumes, eggs, meat, nuts Various protein-rich foods including fish, chicken, eggs, and legumes displayed on a table. Diverse protein foods: fish, chicken, nuts, seeds, eggs, and dairy products arranged on a table.\n", + "249 LiveScience_user_test.html LiveScience_user_test_files/u6iYoHMYax5KaGypJm5xVa-450-80.jpg A glass full of steaming liquid nitrogen on a tray used for theatrical effect. Liquid-nitrogen-infused cocktail emitting smoke on a tray, linked to article about its health impact. Liquid nitrogen-infused cocktail with swirling smoke and vapor atop a tray in a bar setting.\n", + "250 LiveScience_user_test.html LiveScience_user_test_files/3iLiUVFx8sncQEnzFPD8hE-450-80.jpg Dishes with protein-rich foods: fish, legumes, eggs, meat, nuts Assorted protein-rich foods including fish, chicken, eggs, cheese, nuts, lentils, and beans displayed on a table. Various foods representing protein sources: fish, nuts, seeds, dairy, eggs, meat arranged on a wooden table.\n", + "251 LiveScience_user_test.html LiveScience_user_test_files/5BdJ4FkXHuit3LMYwmiNxB-450-80.jpg Diagram of the new U.S. food pyramid, which emphasizes the consumption of meat and dairy products and the avoidance of highly processed foods. Illustration of the new US food pyramid highlighting high-protein foods, healthy fats, full-fat dairy, fruits, vegetables, and whole grains. Heart-shaped arrangement of healthy food options including protein sources, dairy, and vegetables.\n", + "307 LiveScience_user_test.html LiveScience_user_test_files/u6iYoHMYax5KaGypJm5xVa-450-80.jpg Hand pouring hot water from a glass pitcher into a small cup of dark tea on a metal drip tray. A smoking liquid-nitrogen cocktail served on a tray. A cocktail with liquid nitrogen creating smoke in a bar setting.\n", + "308 LiveScience_user_test.html LiveScience_user_test_files/3iLiUVFx8sncQEnzFPD8hE-450-80.jpg Assortment of high-protein foods on a wooden surface including fish, chicken, eggs, nuts, legumes, milk and cheese. Various protein-rich foods including fish, chicken, eggs, legumes, and cheese, illustrating protein sources. Various protein sources like fish, nuts, dairy, and meat arranged on a wooden board.\n", + "309 LiveScience_user_test.html LiveScience_user_test_files/5BdJ4FkXHuit3LMYwmiNxB-450-80.jpg Food pyramid infographic showing three categories: Protein, Dairy and Healthy Fats; Vegetables and Fruits; and Whole Grains, illustrated with photos of corresponding foods. Illustration of the new US food pyramid emphasizing high protein, beef tallow as healthy fat, and full-fat dairy. Heart-shaped graphic illustrating protein, dairy, healthy fats, whole grains, vegetables, and fruits for a balanced diet.\n", + "314 LiveScience_user_test.html LiveScience_user_test_files/xg9ByKvedo58ek7ACaewgW-450-80.jpg Close-up of a tick on a green leaf, relevant to tick-triggered meat allergy. Close-up of a red tick on a green leaf, illustrating a potential source of allergen exposure.\n", + "425 LiveScience_user_test.html LiveScience_user_test_files/xg9ByKvedo58ek7ACaewgW-450-80.jpg Close-up of a tick on a leaf, related to a meat allergy article. Close-up of a red tick on a green leaf, representing a tick bite causing meat allergy.\n", + "470 LiveScience_user_test.html LiveScience_user_test_files/u6iYoHMYax5KaGypJm5xVa-450-80.jpg sostanza liquida fumante in un contenitore di vetro posto su un vassoio circolare in metallo su un bancone Liquid-nitrogen cocktail emitting vapor on a bar tray, illustrating its hazardous nature. Liquid nitrogen-infused cocktail with billowing smoke on a metallic tray in a bar setting.\n", + "471 LiveScience_user_test.html LiveScience_user_test_files/3iLiUVFx8sncQEnzFPD8hE-450-80.jpg prodotti alimentari disposti ordinatamente su un tavolo di legno Various protein-rich foods including fish, chicken, eggs, and legumes. A variety of protein-rich foods including fish, nuts, seeds, dairy, and meat arranged on a table.\n", + "472 LiveScience_user_test.html LiveScience_user_test_files/5BdJ4FkXHuit3LMYwmiNxB-450-80.jpg piramide alimentare che esprime criteri di salubrità alimentare che non sono in linea con i dettami scientifici attuali New US food pyramid emphasizing high protein, healthy fats like beef tallow, and full-fat dairy options. Heart-shaped illustration showcasing protein, dairy, and healthy fats with various foods like meat, vegetables, fruits, and whole grains.\n", + "484 Nike_men_user_test.html Nike_men_user_test_files/image.png Yes/No button Check and close icon, possibly decorative. Blue checkmark and x icon on a green background.\n", + "485 Amazon_kitchen_user_test.html Amazon_kitchen_user_test_files/11++B3A2NEL._SS200_.png Green leaf icon, possibly decorative Icon representing safer chemicals, a green leaf symbol. Green leaf icon representing sustainability and eco-friendly practices.\n", + "502 LiveScience_user_test.html LiveScience_user_test_files/ue7MRnMbdy9Hoku8RZeahJ-450-80.jpg A doctor is talking to an elderly man sitting in front of him, in the background there is an examination table, some bright windows and an anatomical picture A doctor consulting with a patient in a clinical setting, relevant to healthcare discussions. A doctor and patient discussing medical examination in a healthcare setting.\n", + "579 LiveScience_user_test.html LiveScience_user_test_files/xg9ByKvedo58ek7ACaewgW-450-80.jpg Close-up of an insect moving on a green leaf. Close-up of a tick on a green leaf, related to tick-induced meat allergies. A red tick on a green leaf, symbolizing a potential link between insect bites and meat allergies.\n", + "606 LiveScience_user_test.html LiveScience_user_test_files/u43eWTJn8DpGki9c8QSSrN-450-80.jpg Panoramica di una bocca. A dental X-ray showing teeth and jaw structure, used to discuss why teeth are not considered bones. Black and white image of a jaw X-ray showing teeth and skeletal structures.\n" + ] + } + ], + "source": [ + "total = len(df)\n", + "empty_mask = df['original_alt_text'] == ''\n", + "empty_str = empty_mask.sum()\n", + "pct_empty_str = empty_str / total * 100\n", + "\n", + "print(f\"Total rows: {total}\")\n", + "print(f\"Empty string '': {empty_str} ({pct_empty_str:.2f}%)\")\n", + "print(f\"Non-empty: {total - empty_str} ({(total - empty_str) / total * 100:.2f}%)\")\n", + "\n", + "cols = ['page_url','image_url', 'user_alt_text', 'llm_alt_text_1', 'llm_alt_text_2']\n", + "empty_rows = df.loc[empty_mask, cols]\n", + "\n", + "print(\"\\nRows with empty original_alt_text:\")\n", + "print(empty_rows.to_string())" + ] + }, + { + "cell_type": "markdown", + "id": "d6fd42b5", + "metadata": {}, + "source": [ + "## ragionando a gruppi di image_url- quella usata per rebuttal\n", + "questo è corretto perchè una singola immagine valutata più volte, ma il fatto che sia o meno decorativa è una proprietà dell'immagine stessa, non delle valutazioni ripetute" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "9e82149b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total unique image_url: 205\n", + "Empty original_alt_text: 9 (4.39%)\n", + "Non-empty original_alt_text: 196 (95.61%)\n", + "\n", + "Grouped rows with empty original_alt_text:\n", + " image_url page_url occurrences mean_user_assessment mean_user_llm_assessment_1 mean_user_llm_assessment_2 user_alt_text_values llm_alt_text_1_values llm_alt_text_2_values\n", + "0 Amazon_kitchen_user_test_files/11++B3A2NEL._SS200_.png Amazon_kitchen_user_test.html 1 1.000000 5.0 5.0 [Green leaf icon, possibly decorative] [Icon representing safer chemicals, a green leaf symbol.] [Green leaf icon representing sustainability and eco-friendly practices.]\n", + "1 LiveScience_user_test_files/3iLiUVFx8sncQEnzFPD8hE-450-80.jpg LiveScience_user_test.html 5 1.000000 4.4 4.4 [immagine con vari alimenti, tra cui pesce, carne bianca, uova, formaggio e legumi, Dishes with protein-rich foods: fish, legumes, eggs, meat, nuts, Assortment of high-protein foods on a wooden surface including fish, chicken, eggs, nuts, legumes, milk and cheese., prodotti alimentari disposti ordinatamente su un tavolo di legno] [Assorted protein-rich foods including fish, meat, eggs, legumes, nuts, and cheese., Various protein-rich foods including fish, chicken, eggs, and legumes displayed on a table., Assorted protein-rich foods including fish, chicken, eggs, cheese, nuts, lentils, and beans displayed on a table., Various protein-rich foods including fish, chicken, eggs, legumes, and cheese, illustrating protein sources., Various protein-rich foods including fish, chicken, eggs, and legumes.] [A collection of protein-rich foods including fish, nuts, seeds, dairy products, and meat on a wooden table., Diverse protein foods: fish, chicken, nuts, seeds, eggs, and dairy products arranged on a table., Various foods representing protein sources: fish, nuts, seeds, dairy, eggs, meat arranged on a wooden table., Various protein sources like fish, nuts, dairy, and meat arranged on a wooden board., A variety of protein-rich foods including fish, nuts, seeds, dairy, and meat arranged on a table.]\n", + "2 LiveScience_user_test_files/5BdJ4FkXHuit3LMYwmiNxB-450-80.jpg LiveScience_user_test.html 4 1.000000 4.0 3.5 [esempio di piramide alimentare, Diagram of the new U.S. food pyramid, which emphasizes the consumption of meat and dairy products and the avoidance of highly processed foods., Food pyramid infographic showing three categories: Protein, Dairy and Healthy Fats; Vegetables and Fruits; and Whole Grains, illustrated with photos of corresponding foods., piramide alimentare che esprime criteri di salubrità alimentare che non sono in linea con i dettami scientifici attuali] [Illustration of the new US food pyramid emphasizing proteins, healthy fats, full-fat dairy, vegetables, fruits, and whole grains., Illustration of the new US food pyramid highlighting high-protein foods, healthy fats, full-fat dairy, fruits, vegetables, and whole grains., Illustration of the new US food pyramid emphasizing high protein, beef tallow as healthy fat, and full-fat dairy., New US food pyramid emphasizing high protein, healthy fats like beef tallow, and full-fat dairy options.] [Image illustrating healthy fats, protein sources, and whole grains as part of a balanced diet., Heart-shaped arrangement of healthy food options including protein sources, dairy, and vegetables., Heart-shaped graphic illustrating protein, dairy, healthy fats, whole grains, vegetables, and fruits for a balanced diet., Heart-shaped illustration showcasing protein, dairy, and healthy fats with various foods like meat, vegetables, fruits, and whole grains.]\n", + "3 LiveScience_user_test_files/7MsncjgVUQpPKLgeG7xoa9-450-80.jpg LiveScience_user_test.html 1 1.000000 4.0 4.0 [A woman lifting weights in a gym with warm lighting] [Person lifting a heavy barbell in a gym, emphasizing strength.] [Person using a barbell in a gym setting, possibly illustrating strength training.]\n", + "4 LiveScience_user_test_files/u43eWTJn8DpGki9c8QSSrN-450-80.jpg LiveScience_user_test.html 2 1.000000 3.0 4.0 [Image of an orthopantomography, Panoramica di una bocca.] [Panoramic dental X-ray illustrating the anatomy and structure of teeth., A dental X-ray showing teeth and jaw structure, used to discuss why teeth are not considered bones.] [X-ray image of the lower jaw with teeth and surrounding structures, illustrating dental anatomy., Black and white image of a jaw X-ray showing teeth and skeletal structures.]\n", + "5 LiveScience_user_test_files/u6iYoHMYax5KaGypJm5xVa-450-80.jpg LiveScience_user_test.html 5 2.600000 3.2 2.6 [bicchiere con liquido e fumo, A glass full of steaming liquid nitrogen on a tray used for theatrical effect., Hand pouring hot water from a glass pitcher into a small cup of dark tea on a metal drip tray., sostanza liquida fumante in un contenitore di vetro posto su un vassoio circolare in metallo su un bancone] [Liquid-nitrogen-infused cocktail emitting vapor, related to health risks discussed in the article., Liquid-nitrogen cocktail emitting vapor on a tray, related to health risks., Liquid-nitrogen-infused cocktail emitting smoke on a tray, linked to article about its health impact., A smoking liquid-nitrogen cocktail served on a tray., Liquid-nitrogen cocktail emitting vapor on a bar tray, illustrating its hazardous nature.] [A liquid nitrogen infused cocktail with smoke releasing from a glass on a bar tray., Liquid nitrogen cocktail popping a man's stomach like a balloon in a bar setting., Liquid nitrogen-infused cocktail with swirling smoke and vapor atop a tray in a bar setting., A cocktail with liquid nitrogen creating smoke in a bar setting., Liquid nitrogen-infused cocktail with billowing smoke on a metallic tray in a bar setting.]\n", + "6 LiveScience_user_test_files/ue7MRnMbdy9Hoku8RZeahJ-450-80.jpg LiveScience_user_test.html 1 1.000000 5.0 5.0 [A doctor is talking to an elderly man sitting in front of him, in the background there is an examination table, some bright windows and an anatomical picture] [A doctor consulting with a patient in a clinical setting, relevant to healthcare discussions.] [A doctor and patient discussing medical examination in a healthcare setting.]\n", + "7 LiveScience_user_test_files/xg9ByKvedo58ek7ACaewgW-450-80.jpg LiveScience_user_test.html 3 3.666667 1.0 1.0 [, Close-up of an insect moving on a green leaf.] [Close-up of a tick on a green leaf, relevant to tick-triggered meat allergy., Close-up of a tick on a leaf, related to a meat allergy article., Close-up of a tick on a green leaf, related to tick-induced meat allergies.] [Close-up of a red tick on a green leaf, illustrating a potential source of allergen exposure., Close-up of a red tick on a green leaf, representing a tick bite causing meat allergy., A red tick on a green leaf, symbolizing a potential link between insect bites and meat allergies.]\n", + "8 Nike_men_user_test_files/image.png Nike_men_user_test.html 1 1.000000 5.0 4.0 [Yes/No button] [Check and close icon, possibly decorative.] [Blue checkmark and x icon on a green background.]\n" + ] + } + ], + "source": [ + "\n", + "total_unique_images = df['image_url'].nunique() #len(df.groupby('image_url').size())\n", + "empty_mask = df['original_alt_text'] == ''\n", + "\n", + "# Unique images where original_alt_text is empty (at least once)\n", + "empty_images = df.loc[empty_mask, 'image_url'].nunique()\n", + "non_empty_images = total_unique_images - empty_images\n", + "pct_empty = empty_images / total_unique_images * 100\n", + "pct_non_empty = non_empty_images / total_unique_images * 100\n", + "\n", + "print(f\"Total unique image_url: {total_unique_images}\")\n", + "print(f\"Empty original_alt_text: {empty_images} ({pct_empty:.2f}%)\")\n", + "print(f\"Non-empty original_alt_text: {non_empty_images} ({pct_non_empty:.2f}%)\")\n", + "\n", + "# Convert assessment columns to numeric before grouping\n", + "assessment_cols = ['user_assessment', 'user_llm_assessment_1', 'user_llm_assessment_2']\n", + "df[assessment_cols] = df[assessment_cols].apply(pd.to_numeric, errors='coerce')\n", + "\n", + "# Group by image_url to collapse repeated entries\n", + "cols = ['image_url', 'page_url', 'user_alt_text', 'llm_alt_text_1', 'llm_alt_text_2'] + assessment_cols\n", + "empty_rows = df.loc[empty_mask, cols]\n", + "\n", + "grouped = empty_rows.groupby('image_url').agg(\n", + " page_url=('page_url', 'first'),\n", + " occurrences=('user_alt_text', 'count'),\n", + " mean_user_assessment=('user_assessment', 'mean'),\n", + " mean_user_llm_assessment_1=('user_llm_assessment_1', 'mean'),\n", + " mean_user_llm_assessment_2=('user_llm_assessment_2', 'mean'),\n", + " user_alt_text_values=('user_alt_text', lambda x: list(x.unique())),\n", + " llm_alt_text_1_values=('llm_alt_text_1', lambda x: list(x.unique())),\n", + " llm_alt_text_2_values=('llm_alt_text_2', lambda x: list(x.unique())),\n", + " \n", + ").reset_index()\n", + "\n", + "print(\"\\nGrouped rows with empty original_alt_text:\")\n", + "print(grouped.to_string())" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "c170e277", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(mean_user_assessment 1.474074\n", + " dtype: float64,\n", + " mean_user_llm_assessment_1 3.844444\n", + " dtype: float64,\n", + " mean_user_llm_assessment_2 3.722222\n", + " dtype: float64)" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "grouped[[\"mean_user_assessment\"]].mean(),grouped[[\"mean_user_llm_assessment_1\"]].mean(),grouped[[\"mean_user_llm_assessment_2\"]].mean()" + ] + }, + { + "cell_type": "markdown", + "id": "c9c563c3", + "metadata": {}, + "source": [ + "## la percentuale delle empty lato utente\n", + "il numero delle stringhe vuote dell'utente non è affidabile, semplicemnete magari non le hanno scritte per tempo" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "97348966", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total unique image_url: 205\n", + "Empty user_alt_text: 116 (56.59%)\n", + "Non-empty user_alt_text: 89 (43.41%)\n", + "\n", + "Grouped rows with empty user_alt_text:\n", + " image_url page_url occurrences user_alt_text_values llm_alt_text_1_values llm_alt_text_2_values\n", + "0 Amazon_kitchen_user_test_files/51mF3c-BLpL._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [Modern yellow arrowhead table runner, 13 x 72 inches, for 4th of July and Memorial Day home decor.] [Yellow and white chevron pattern table runner for indoor or outdoor use.]\n", + "1 Amazon_kitchen_user_test_files/51tjDtDQdWL._AC_UL320_.jpg Amazon_kitchen_user_test.html 2 [] [16-piece ceramic dinnerware set, microwave and dishwasher safe., 16-piece ceramic dinnerware set with plates and bowls, microwave and dishwasher safe, suitable for kitchen and dining.] [16-Piece Ceramic Dinnerware Sets with plates and bowls for kitchen and dining, microwave & dishwasher safe., 16-Piece Ceramic Dinnerware Set: Plates, Bowls, Microwave & Dishwasher Safe, Kitchen Dining, EUR 28.60]\n", + "2 Amazon_kitchen_user_test_files/61AwsD8HRNL._AC_UL320_.jpg Amazon_kitchen_user_test.html 2 [] [Kasepie PVC Plastic Placemats Set of 4, blue, heat-resistant and wipeable., Kasepie PVC Plastic Placemats Set of 4, Blue, Heat Resistant and Wipeable.] [Plastic bag with handwritten numbers 52-9-4703 visible in the image., Wrapped object with handwritten '52-9-4702' text inside plastic bag.]\n", + "3 Amazon_kitchen_user_test_files/61VjM8Sd6kL._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [Pink Bow placemats and coasters set arranged on a round dining table.] [Pink Bow Placemats Set of 4 with 3 Heat Resistant Coasters for wedding, party, or farmhouse kitchen decor.]\n", + "4 Amazon_kitchen_user_test_files/61W3TWy1saL._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [Handmade Marble Coasters Set of 4, 4” Travertine & White Matt Natural Stone, Elegant Table Protection for Kitchen & Home Décor.] [EarthenTones Handmade Marble Coasters Set of 4 with Travertine & White Stone, Elegant Table Protection for Kitchen, Dining, Home Decor.]\n", + "5 Amazon_kitchen_user_test_files/61ZdhggeA2L._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [Tall glass fruit tray with pedestal bowl for dining table, decorative and functional for fruits and snacks.] [Decorative glass fruit tray with pedestal bowl, suitable for household dining table decor.]\n", + "6 Amazon_kitchen_user_test_files/719IIjUk7OL._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [3 Pack Easter Bunny Serving Trays, 16x11 inches, blue, for food decoration and party supplies.] [Decorative Easter bunny tray with pastel cakes, ideal for party supplies or charcuterie boards.]\n", + "7 Amazon_kitchen_user_test_files/71B8kNOY6QL._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [Gold metal napkin holder stand for tabletop, modern design for kitchen or restaurant use.] [Gold metal napkin holder stand for tabletop, tissue dispenser for restaurant dining or kitchen countertop.]\n", + "8 Amazon_kitchen_user_test_files/71BOLmVEzVL._AC_SR322,134_CB1169409_QL70_.jpg Amazon_kitchen_user_test.html 1 [] [Quatish 32-piece black dinnerware set for 8, unbreakable plastic plates and bowls, microwave and dishwasher safe, ideal for camping and outdoor dining.] [Quatish 32 Piece Plates and Bowls Sets for 8, Unbreakable Dinnerware Sets, Plastic Dish Set for Camping, RV Essentials, Black.]\n", + "9 Amazon_kitchen_user_test_files/71uADhIeHQL._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [Hand towel featuring illustrated pasta shapes for Italian kitchen decor.] [Hand towel featuring pasta shapes for kitchen decor, gifts for pasta lovers.]\n", + "10 Amazon_kitchen_user_test_files/71uq-Tvf8tL._AC_UL320_.jpg Amazon_kitchen_user_test.html 2 [] [Set of 4 orange cat-themed placemats, washable, non-slip, heat-resistant, PVC, 12x18 inches, suitable for kitchen or dining decor., Set of 4 orange cat-themed washable placemats, 12x18 inches, non-slip, heat-resistant, PVC material, ideal for kitchen or dining table decor.] [Set of 4 orange cat table placemats for dining table, washable, 12x18 inches, kitchen decor., Colorful cat placemats with a fork and knife design, suitable for kitchen decor.]\n", + "11 Amazon_kitchen_user_test_files/71yRdxcWDrL._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [Black and white checkered tablecloth with tassels on a dining table, wrinkle-free and waterproof.] [Deep Dream Waterproof Checkered Tablecloth: Black & White Buffalo Plaid, Cotton Linen, Tassel Detail, 55 x 86 Inch.]\n", + "12 Amazon_kitchen_user_test_files/813ooP3m0cL._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [Checkered table runner with stars and stripes, ideal for Memorial Day and 4th of July decor, 13x72 inches.] [A checkered stars and stripes table runner with American flag patterns, suitable for patriotic decor.]\n", + "13 Amazon_kitchen_user_test_files/81FX07lfydL._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [Woven fruit basket, 35x25x5.5cm, hand-woven storage tray with handles, rattan-style serving basket for kitchen and dining table.] [Woven fruit basket with dual handles, 35x25x5.5cm, natural rattan style serving tray for kitchen and dining table.]\n", + "14 Amazon_kitchen_user_test_files/81ID1sfFZxL._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [Red poppy table runner with American flag design for Memorial Day or 4th of July decor.] [Artoid Mode Red Poppy American Flag Stars 210 GSM Table Runner for Home Party Decor.]\n", + "15 Amazon_kitchen_user_test_files/81W173Q69NL._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [Set of 4 red checkered scalloped placemats with ruffles, displayed for product listing.] [Red and white checkered placemats with ruffles displayed on a table setting.]\n", + "16 Amazon_kitchen_user_test_files/81eTAADrD4L._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [Artoid Mode God Bless America Patriotic Table Runner for Memorial Day or 4th of July, 13x72 Inch.] [Artoid Mode Wood God Bless America Stars Patriotic 210 GSM 4th of July Table Runner, Memorial Day Kitchen Dining Table Decoration for Home Party Decor 13x72 Inch]\n", + "17 Amazon_kitchen_user_test_files/81gjQpdliyL._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [Artoid Mode Burlap Brown Rustic Table Runner on a wooden table with candle and breadboard, ideal for kitchen and dining decor.] [Brown burlap braided table runner for farmhouse or kitchen decor, 12x48 inches.]\n", + "18 Amazon_kitchen_user_test_files/81lrEj+5CPL._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [Square patriotic tablecloth with red, white, and blue embroidery for 4th of July celebrations.] [SiliFine Patriotic Tablecloth 34 Inch 4th of July Square Embroidered Red White Blue Star Table Cover Independence Day Linens.]\n", + "19 Amazon_kitchen_user_test_files/91rjiaOyWML._AC_UL320_.jpg Amazon_kitchen_user_test.html 1 [] [AMARED Purple Lavender Floral Table Runner, Spring Decoration for Dining Table, 13x69 Inch.] [AMARED Mode Purple Lavender Floral Spring Table Runner, Summer Kitchen Dining Table Decoration 13x69 Inch.]\n", + "20 CNN_Home_user_test_files/008-008-ap26059717007628.jpg CNN_Home_user_test.html 1 [] [Missile launched from US Navy ship during Operation Epic Fury on February 28, 2026, as shown in a US Central Command video.] [A missile being launched from a US Navy ship during Operation Epic Fury on February 28, 2026.]\n", + "21 CNN_Home_user_test_files/117871-minelayersstriaghofhormuz-clean-00-00-00-00-still001.jpg CNN_Home_user_test.html 3 [] [Infrared image of a vessel marked 'UNCLASSIFIED' on open water, possibly related to surveillance., Infrared image of a vessel labeled 'UNCLASSIFIED' in the Strait of Hormuz., Infrared image of a naval vessel marked as 'UNCLASSIFIED'.] [Unclassified thermal imaging footage showing a boat on water, possibly related to military operations., Unclassified thermal image of a boat on water, possibly related to naval operations., Unclassified thermal imaging of a boat at sea in Hormuz Strait.]\n", + "22 CNN_Home_user_test_files/117887-joerogan-trump-iran-thumb-clean.jpg CNN_Home_user_test.html 1 [] [Image of a person holding a microphone at a UFC event.] [Man holding microphone at UFC press conference wearing academy apparel.]\n", + "23 CNN_Home_user_test_files/117894-dissentcrackdown-thumb.jpg CNN_Home_user_test.html 1 [] [Image related to dissent crackdown, possibly from a news broadcast.] [Image of a man with text in Urdu and Arabic, possibly related to news or commentary.]\n", + "24 CNN_Home_user_test_files/2026-03-10t150127z-1377402233-rc2s9o8ka4ft-rtrmadp-3-iran-crisis-leader.JPG CNN_Home_user_test.html 2 [] [Iran’s new supreme leader attends a meeting in Tehran, Iran, March 2, 2016., Iran’s Mojtaba Khamenei at a meeting in Tehran, March 2, 2016.] [Mojtaba Khamenei attends a meeting in Tehran, Iran, March 2, 2016., Iran's new supreme leader, Mojtaba Khamenei, attends a meeting in Tehran, Iran on March 2, 2016.]\n", + "25 CNN_Home_user_test_files/ap26067484115759-20260311143008704.jpg CNN_Home_user_test.html 1 [] [Residents observe flames and smoke rising from an oil facility in Tehran, Iran, after a strike on Saturday.] [Residents watch flames and smoke rise from an oil storage facility struck in Tehran, Iran.]\n", + "26 CNN_Home_user_test_files/ap26069507892459.jpg CNN_Home_user_test.html 1 [] [A stock trader at a desk amid reports of U.S. stock market declines.] [A person in a trading room with multiple screens, including one displaying an American flag and a mountain landscape.]\n", + "27 CNN_Home_user_test_files/atlantis-hires-024-flat-edit-v2-copy-1.jpg CNN_Home_user_test.html 2 [] [Two people in formal attire posing against a floral backdrop., Two individuals in formal attire with floral decor in the background.] [Two women wearing pink dresses and jewelry posing in front of a floral backdrop., Two individuals dressed in pink gowns posing in front of a floral background.]\n", + "28 CNN_Home_user_test_files/c-gettyimages-2265466601.jpg CNN_Home_user_test.html 1 [] [US President Donald Trump speaks at Verst Logistics in Hebron, Kentucky, March 11, 2026.] [Donald Trump speaking at Verst Logistics in Hebron, Kentucky on March 11, 2026.]\n", + "29 CNN_Home_user_test_files/c-gettyimages-2265924275.jpg CNN_Home_user_test.html 5 [] [A resident walks near the building damaged in an Israeli strike in central Beirut on March 11, 2026, injuring at least four people., A resident walks near a building damaged in an Israeli strike in the Aisha Bakkar area, Beirut, March 11, 2026., A resident in front of a building damaged by an Israeli strike in Beirut's Aisha Bakkar area on March 11, 2026., A resident in front of a damaged building in Beirut after an Israeli strike injured at least four people on March 11, 2026., A resident walks past a damaged building after an Israeli strike in Beirut's Aisha Bakkar area on March 11, 2026.] [A resident walks in front of a damaged building after an Israeli strike in Beirut, Lebanon on March 11, 2026., Resident walks in front of destroyed building after Israeli strike in Beirut on March 11, 2026., A woman walks in front of rubble and damaged vehicles after an Israeli strike on a residential building in Beirut, Lebanon., A resident walks amidst rubble after an explosion in Beirut, Lebanon., A resident walks amidst debris after an Israeli strike on a residential building in Beirut, Lebanon.]\n", + "30 CNN_Home_user_test_files/gettyimages-1434807928.jpg CNN_Home_user_test.html 1 [] [The Strategic Petroleum Reserve in Freeport, Texas, on October 19, 2022, amid a global release of 400 million barrels of oil.] [Aerial view of the Strategic Petroleum Reserve in Freeport, Texas, on October 19, 2022, with dozens of nations agreeing to release 400 million barrels of oil into the market.]\n", + "31 CNN_Home_user_test_files/gettyimages-2160812639.jpg CNN_Home_user_test.html 3 [] [File photo of Gulfstream G650ER from Qatar Executive landing in Barcelona, Spain, May 27, 2024., A Gulfstream G650ER from Qatar Executive landing at Barcelona airport, May 27, 2024., A Gulfstream G650ER from Qatar Executive landing at Barcelona airport.] [A Gulfstream G650ER from Qatar Executive aircraft landing at Barcelona airport on May 27, 2024., A Gulfstream G650ER aircraft landing at Barcelona airport in Spain., A Gulfstream G650ER aircraft landing at Barcelona airport in 2024.]\n", + "32 CNN_Home_user_test_files/gettyimages-2168856012.jpg CNN_Home_user_test.html 1 [] [A person walking in a park on a sunny morning.] [A black man exercising on a path in a park during morning hours.]\n", + "33 CNN_Home_user_test_files/gettyimages-2226239770-20260303221718957.jpg CNN_Home_user_test.html 2 [] [Satellite image of the Strait of Hormuz, a vital waterway for global energy transport on January 11, 2025., Satellite view of the Strait of Hormuz, linking the Persian Gulf to the Arabian Sea, a key chokepoint for global oil and gas exports as of January 11, 2025.] [Satellite view of the Strait of Hormuz, a strategic waterway between Iran and Oman linking Persian Gulf to Arabian Sea., Satellite view of the Strait of Hormuz in January 2025, highlighting its role as a vital waterway for global oil and LNG exports.]\n", + "34 CNN_Home_user_test_files/gettyimages-2234059973-20260311214538952.jpg CNN_Home_user_test.html 1 [] [Attendees at a rally outside the U.S. Capitol for the SAVE Act, advocating proof of citizenship for federal election registration.] [Attendees hold signs at a rally promoting \"Only Citizens Vote\" and opposing illegal voting for the Safeguard American Voter Eligibility Act.]\n", + "35 CNN_Home_user_test_files/gettyimages-2255435511.jpg CNN_Home_user_test.html 1 [] [A humanoid robot organizes shelves at a training ground in Qingdao, China, on January 12, 2026.] [A researcher operates a humanoid robot learning to organize shelves in Qingdao, China, January 12, 2026.]\n", + "36 CNN_Home_user_test_files/gettyimages-2259341238-20260311200559984.jpg CNN_Home_user_test.html 1 [] [Person viewing Moltbook homepage, a social network for AI agents, highlighting autonomous AI communication and global ethical debates.] [Illustration of Moltbook website homepage displaying AI agent social network concept, highlighting AI interaction without human participation.]\n", + "37 CNN_Home_user_test_files/gettyimages-2263930943.jpg CNN_Home_user_test.html 1 [] [Governor Gavin Newsom announces new funding for homelessness and mental health during a press conference at BACS REGIS Center, Hayward, CA, on March 2, 2026.] [Governor Newsom speaking at BACS REGIS Center in Hayward announcing new funding for homelessness and mental health initiatives during a press conference on March 2, 2026.]\n", + "38 CNN_Home_user_test_files/gettyimages-622913572.jpg CNN_Home_user_test.html 3 [] [Tatara Bridge spanning the Seto Inland Sea in Japan, Tatara Bridge in Seto Inland Sea, Japan] [A scenic shot of Tatara Bridge spanning the Seto Inland Sea in Japan with lush greenery on either side., Bridge spanning Seto Inland Sea with cyclist on road, Japan., A view of Tatara Bridge spanning the Seto Inland Sea under a blue sky.]\n", + "39 CNN_Home_user_test_files/screenshot-2026-03-11-at-3-40-55-pm.png CNN_Home_user_test.html 1 [] [Color-coded map of the U.S. showing gradient data distribution across states.] [Map of U.S. states with color-coded regions representing varying levels of heat, likely related to climate change patterns.]\n", + "40 CNN_Home_user_test_files/thumb-3-20260225204059793.jpg CNN_Home_user_test.html 1 [] [A person reading a document at a desk in a news office.] [A person sitting at a desk with a computer and paper, appearing thoughtful.]\n", + "41 CNN_Home_user_test_files/thumbnail-kim-guns-nk-1-vrtc.jpg CNN_Home_user_test.html 1 [] [Person firing a gun at a shooting range.] [North Korean leader holding a handgun indoors during training exercise.]\n", + "42 Fox_News_user_test_files/NEWSLETTER_LIFESTYLE_LOGO-532x120.png Fox_News_user_test.html 1 [] [Fox News Lifestyle logo] [Fox News Lifestyle logo with text 'Lifestyle' displayed against a black background.]\n", + "43 Fox_News_user_test_files/acq-2.jpg Fox_News_user_test.html 4 [] [American Culture Quiz: Test your knowledge of baseball and snacks in a fun weekly challenge., American Culture Quiz: Test your knowledge of baseball trivia and nutty snacks., American Culture Quiz: Test your knowledge of baseball and food trends., American Culture Quiz: Test yourself on baseball bests and nutty nibbles.] [American Culture Quiz: Test your knowledge on baseball, food trends, and American history., American Culture Quiz: Test your knowledge of baseball bests and nutty nibbles, featuring iconic American symbols., American Culture Quiz: Test yourself on baseball, food, history, and more with iconic American images., American Culture Quiz: Test your knowledge of baseball bests and nutty nibbles.]\n", + "44 Fox_News_user_test_files/airport-meal-voucher-drama-food-drink-1.jpg Fox_News_user_test.html 2 [] [Traveler in airport holding coffee, representing dissatisfaction with meal vouchers amid rising food prices., Airline meal vouchers 'almost insulting' as airport food prices soar, say passengers and experts.] [A woman with a coffee cup and luggage at an airport terminal, reflecting rising airport food costs., Person in an airport holding a cup of coffee and looking at their phone, reflecting rising food costs.]\n", + "45 Fox_News_user_test_files/americas-most-expensive-pizza-chains-2.jpg Fox_News_user_test.html 2 [] [America's most overpriced pizza chain revealed; study claims Round Table Pizza leads after analyzing 247,927 customer reviews., People sharing a pizza, related to the discussion of America's most overpriced pizza chain.] [Group of people enjoying a pizza slice together., Group of people sharing and enjoying a pizza slice at an outdoor table.]\n", + "46 Fox_News_user_test_files/bartender-wine-industry-downturn.jpg Fox_News_user_test.html 2 [] [A bartender pouring red wine into a glass in a wine bar., Bartender pouring wine in a glass at a wine bar, symbolizing wine industry challenges.] [A bartender pours red wine behind a bar stocked with bottles in a stylish setting., Bartender pours red wine into a glass at a bar with shelves of liquor bottles in the background.]\n", + "47 Fox_News_user_test_files/burger-king-patty-ai-1.jpg Fox_News_user_test.html 1 [] [Burger King worker hands food to drive-thru customer, linked to AI monitoring and coaching workers.] [Employee handing out a Burger King takeout bag in drive-thru window, highlighting AI monitoring of workers.]\n", + "48 Fox_News_user_test_files/chick-fil-a-sandwich-fries-chicken.jpg Fox_News_user_test.html 2 [] [Chick-fil-A reverts waffle fry recipe after customer backlash over taste and allergy concerns., Chick-fil-A waffle fries, chicken sandwich, and nuggets served on a wooden board.] [Chick-fil-A rolls back its waffle fry recipe after customer backlash, highlighting food trends and consumer preferences., Image of Chick-fil-A meal with chicken nuggets, fries, and a burger.]\n", + "49 Fox_News_user_test_files/coffee-shop-female-customer.gif Fox_News_user_test.html 1 [] [Etiquette expert reveals 5 coffee shop habits to avoid.] [Person using laptop and drinking coffee at a cafe, suggesting a shared public space habit.]\n", + "50 Fox_News_user_test_files/cruise-passenger-drinking.jpg Fox_News_user_test.html 2 [] [A woman on a cruise ship balcony holding a cocktail, overlooking the ocean., Person enjoying a cruise with a drink, overlooking the ocean.] [Person holding a cocktail on a cruise ship deck during sunset., Person holding a cocktail on a cruise ship balcony at sunset.]\n", + "51 Fox_News_user_test_files/food-drink-black-cherries-breast-cancer-study-mice-2.jpg Fox_News_user_test.html 2 [] [Dark sweet cherries may slow aggressive breast cancer growth, according to Texas A&M University research., Bowl of dark sweet cherries, linked to slowing aggressive breast cancer growth in study.] [A person holding a bowl of cherries surrounded by red fruit in an American kitchen., A person eating cherries from a bowl.]\n", + "52 Fox_News_user_test_files/food-drink-cancer-preventing-healthy-foods-what-to-know-2.jpg Fox_News_user_test.html 1 [] [A doctor advises eating more protective foods to lower cancer risk, emphasizing plant-forward and fiber-rich diets.] [A woman enjoys a colorful salad with tomatoes and greens, emphasizing healthy food choices.]\n", + "53 Fox_News_user_test_files/foodie.jpg Fox_News_user_test.html 2 [] [1 in 5 Americans admit sneaking sauces into restaurants as condiment flights trend goes viral., 1 in 5 Americans admit to sneaking their own sauces as a restaurant trend goes viral.] [Group of friends eating and socializing over food at an outdoor restaurant., Group enjoying food and beverages outdoors; reflects restaurant trends and social media appeal.]\n", + "54 Fox_News_user_test_files/garden-hoe.gif Fox_News_user_test.html 1 [] [VICTORY GARDEN: Cut grocery bills and healthcare costs with one simple backyard habit.] [A black spade partially buried in dark soil next to grass and plant life.]\n", + "55 Fox_News_user_test_files/image.jpg Fox_News_user_test.html 1 [] [Joey Jones explains why steak and lobster mean so much to deployed troops.] [Deployed soldiers eating steak in a military setting, reflecting Joey Jones's view on its importance.]\n", + "56 Fox_News_user_test_files/jfk-jr-carolyn-bessette-kennedy-marriage1.jpg Fox_News_user_test.html 1 [] [Two people in formal attire at an event, unrelated to JFK Jr. tourism frenzy.] [A black-suited couple photographed during the 1990s, related to JFK Jr.'s popularity and legacy.]\n", + "57 Fox_News_user_test_files/jj-watt-houston-texans-tipping-debate.jpg Fox_News_user_test.html 1 [] [Former NFL star speaking at an event, sparking a viral debate on tipping at self-service restaurants.] [A man in red attire speaks into a microphone during an NFL game.]\n", + "58 Fox_News_user_test_files/maine-avenue-fish-market-potomac-oysters.jpg Fox_News_user_test.html 1 [] [Impact of Potomac River sewage spill on oyster industry during seafood season: 'It's devastating us'] [Person handling oysters and dishes at an oyster market.]\n", + "59 Fox_News_user_test_files/suzy-karadsheh-olive-oil-split.jpg Fox_News_user_test.html 1 [] [Mediterranean chef promotes extra virgin olive oil for heart health and weight management benefits.] [Mediterranean chef showcasing olive oil as 'liquid gold' for heart health and weight loss in pantry setting.]\n", + "60 Fox_News_user_test_files/tipping-jar.gif Fox_News_user_test.html 1 [] [A tipping jar with coins and cash, symbolizing the tipping culture debate in America.] [A tipped glass on a table with cash, representing Americans' frustration with tipping culture.]\n", + "61 Fox_News_user_test_files/vaccine-marty-makary.jpg Fox_News_user_test.html 1 [] [FDA launches AI system to monitor drug and vaccine side effects nationwide.] [A person receiving a shot, alongside an FDA official in a lab setting, showcasing new AI-powered drug and vaccine side effect tracking.]\n", + "62 Fox_News_user_test_files/woman-holding-hot-mug-tea.png Fox_News_user_test.html 2 [] [An expert explains if cold or hot water is healthier to drink., Person holding a red mug with a lemon slice, related to health benefits of cold vs. hot water.] [A red mug filled with tea and lemon sits on a yellow sweater, illustrating healthy hydration options., A red mug filled with tea in someone's hands, representing warm hydration options.]\n", + "63 LiveScience_user_test_files/7kJDueUYJVYTkJH38UuHPo-450-80.jpg LiveScience_user_test.html 1 [] [A woman with allergies holding tissues, illustrating the article on whether air purifiers help with allergies.] [A woman holding tissues to her nose while sitting on a sofa, potentially related to allergy symptoms.]\n", + "64 LiveScience_user_test_files/Dvf2V5cUHtcV6sf7m38HSQ-450-80.jpg LiveScience_user_test.html 2 [] [A woman applies sunscreen to a child at the beach, illustrating mineral sunscreen use., Applying sunscreen to a child on the beach, illustrating proper skincare and sun protection.] [A tan woman applies sunscreen to a young boy on the beach; blurred toys visible in background., A tan woman applies sunscreen to a young boy on a blurred beach, highlighting mineral sunscreen's impact.]\n", + "65 LiveScience_user_test_files/NJ5Hd675vr5zvWxpuZ2rvJ-450-80.jpg LiveScience_user_test.html 2 [] [An illustration of bacteria in the gut., An illustration of gut bacteria, relevant to the study of aging and gut microbes.] [Illustration of bacteria in the gut microbiome, highlighting potential roles in health and aging., Illustration depicting bacteria in the gut, highlighting their potential role in understanding aging processes.]\n", + "66 LiveScience_user_test_files/RDEr3MZzWVDnXRKbFzLhPE-450-80.jpg LiveScience_user_test.html 2 [] [3D illustration of nerves in the head and neck, highlighting the vagus nerve and brain function., 3D illustration of a transparent human body showing nerves in the head and neck, relevant to vagus nerve study.] [3D illustration of a transparent blue human body with red lines depicting nerves in the head and neck., An illustration of a transparent blue human body displaying red nerve pathways in the head and neck.]\n", + "67 LiveScience_user_test_files/gKU9oNsfCUXydiKQFZn5yC-450-80.jpeg LiveScience_user_test.html 1 [] [The Saucony Ride 15 running shoes being tested during our full review.] [Saucony Ride 15 running shoes displayed during a full review, ideal for supination buyers.]\n", + "68 LiveScience_user_test_files/gwVZfGDoH4gbHJC74NxAka-450-80.jpg LiveScience_user_test.html 2 [] [Close-up of elderly hands crossed over a lap, symbolizing aging and longevity., Close-up of elderly hands crossed on a lap, symbolizing aging and longevity.] [Close-up of elderly person's crossed hands in striped shirt against black background., Close-up of elderly hands crossed over lap, wearing striped shirt, illustrating human longevity themes.]\n", + "69 LiveScience_user_test_files/o4HHzvcNZSRbjXpWMHzmJ6-415-80.jpg LiveScience_user_test.html 2 [] [Illustration of DNA strands, relevant to genetic testing and consumer health discussions., An illustration of DNA strands, relevant to genetic testing discussions.] [Illustration of DNA strands representing genetic concepts and tests discussed in the article., Abstract representation of DNA helix against dark background, symbolizing genetics and molecular biology.]\n", + "70 LiveScience_user_test_files/pxWUkgwqmnQhYiRZUQPai6-450-80.jpg LiveScience_user_test.html 2 [] [Air purifier on a table next to a sofa with an orange cat., Air purifier on a table near a sofa, featured in a buying guide for allergies.] [Orange cat relaxing near an air purifier on a sofa, related to allergy-focused health advice., Orange cat resting on sofa next to an air purifier in a living room setting.]\n", + "71 LiveScience_user_test_files/sTenoWjZtGXYvD6uVwDYEZ-450-80.jpg LiveScience_user_test.html 3 [] [Air purifier placed in a living room, featured in a buying guide for top air purifiers of 2026., An air purifier in a living room, featured in a buying guide for top models of 2026., An air purifier placed in a living room, highlighting its home usage.] [A minimalist air purifier in a modern living room, showcasing design and functionality., A white air purifier sits on a table in a furnished living room, part of a 'Best Air Purifiers 2026' guide., A white air purifier in a living room setting with blurred figures on a sofa.]\n", + "72 LiveScience_user_test_files/xNWjTGpcHmjuaY35taLAij-450-80.jpg LiveScience_user_test.html 2 [] [An orange cat on an air purifier, illustrating pet-related usage., An orange cat standing on an air purifier, illustrating air purifier use for pet owners.] [An orange cat standing on top of an air purifier, highlighting its usefulness for removing pet dander., Orange cat perched atop an air purifier in a sunlit room.]\n", + "73 LiveScience_user_test_files/xg9ByKvedo58ek7ACaewgW-450-80.jpg LiveScience_user_test.html 2 [] [Close-up of a tick on a green leaf, relevant to tick-triggered meat allergy., Close-up of a tick on a leaf, related to a meat allergy article.] [Close-up of a red tick on a green leaf, illustrating a potential source of allergen exposure., Close-up of a red tick on a green leaf, representing a tick bite causing meat allergy.]\n", + "74 Nike_men_user_test_files/13-nike-tennis-gifts-for-players-of-all-levels.jpg Nike_men_user_test.html 1 [] [Nike tennis gifts worn by pros, featuring a player showcasing Nike gear on the court.] [A tennis player in a blue outfit on a court, representing Nike's gift ideas for athletes.]\n", + "75 Nike_men_user_test_files/8-best-yoga-gifts-by-nike.jpg Nike_men_user_test.html 1 [] [8 Best Yoga Gifts by Nike featured in buying guide.] [Woman in black leggings and white sports bra posing gracefully with arms extended.]\n", + "76 Nike_men_user_test_files/DB+M+NK+TF+SI+BRSH+PO+HD.png Nike_men_user_test.html 1 [] [Book Standard Issue Men's Brushed Pullover Hoodie] [Dark gray Book Standard Issue men's brushed pullover hoodie with logo and pocket details.]\n", + "77 Nike_men_user_test_files/M+NK+CLUB+ALUMNI+FT+SHORT.png Nike_men_user_test.html 1 [] [Nike Club Men's French Terry Alumni Shorts] [A man wearing Nike Club Men's French Terry Alumni Shorts and a matching zip-up sweatshirt.]\n", + "78 Nike_men_user_test_files/M+NK+CLUB+WVN+CARGO+PANT+UF.png Nike_men_user_test.html 1 [] [Nike Club Men's Woven Cargo Pants in a black patterned design, part of men's clothing collection at Nike.com.] [Man wearing streetwear with woven cargo pants and layered tops, showcasing Nike Club style.]\n", + "79 Nike_men_user_test_files/M+NK+DF+COF+JSY+LS+FR+SP26.png Nike_men_user_test.html 1 [] [Nike Culture of Football Men's Dri-FIT Long-Sleeve Soccer Jersey in green and black with Air Max design.] [Nike Culture of Football Men's Dri-FIT Long-Sleeve Soccer Jersey featuring 'Air Max' branding and graphic design.]\n", + "80 Nike_men_user_test_files/M+NK+DF+PAR+SHRT+AT+KNEE.png Nike_men_user_test.html 2 [] [Nike Par Men's Dri-FIT Golf Shorts displayed in blue., Nike Par Men's Dri-FIT Golf Shorts modeled in blue.] [A man wearing Nike Par Dri-FIT golf shorts and polo shirt against a white background., Nike Par Men's Dri-FIT Golf Shorts outfit with blue polo shirt, shorts, socks, and shoes.]\n", + "81 Nike_men_user_test_files/M+NK+DF+STRDE+REALTREE+5BFSHRT.png Nike_men_user_test.html 2 [] [Nike Stride Men's Dri-FIT 5\" Realtree® Running Shorts with brief lining, featured on Nike.com., Nike Stride Men's Dri-FIT 5\" Brief-Lined Realtree® Running Shorts] [Nike Stride Men's Dri-FIT 5\" Brief-Lined Realtree≱ Running Shorts, Nike Stride Men's Dri-FIT 5\" Brief-Lined Realtree® Running Shorts.]\n", + "82 Nike_men_user_test_files/M+NK+DF+STRIDE+REALTREE+JKT.png Nike_men_user_test.html 2 [] [Nike Stride Men's Dri-FIT Realtree® Running Jacket] [Nike Stride Men's Dri-FIT Realtree³ Running Jacket in camouflage pattern., Nike Stride Men's Dri-FIT Realtree® Running Jacket displayed on a webpage.]\n", + "83 Nike_men_user_test_files/M+NK+DF+TCH+WVN+PANT.png Nike_men_user_test.html 1 [] [Nike Tech Men's Dri-FIT Woven Pants, black color, displayed on a model.] [A person wearing a Nike Tech Men's Dri-FIT Woven Pants and a black hooded jacket.]\n", + "84 Nike_men_user_test_files/M+NK+DF+VLCTY+POLO+LS+SOLID.png Nike_men_user_test.html 2 [] [Nike Velocity Men's Dri-FIT Long-Sleeve Golf Polo shirt in light blue., Nike Velocity Men's Dri-FIT Long-Sleeve Golf Polo] [Nike Velocity Men's Dri-FIT Long-Sleeve Golf Polo in light blue fabric., Nike Velocity Men's Dri-FIT Long-Sleeve Golf Polo in light blue.]\n", + "85 Nike_men_user_test_files/M+NK+TCH+FLC+JGGR+AMD+2K26.png Nike_men_user_test.html 1 [] [Nike Tech Men's Fleece Joggers displayed on a model.] [A man wearing black Nike Tech fleece joggers with yellow graphic details.]\n", + "86 Nike_men_user_test_files/M+NK+TCH+FLC+WR+FZ+JKT+AMD+26.png Nike_men_user_test.html 1 [] [Nike Tech Men's Fleece Full-Zip Windrunner Jacket] [Nike Tech Men's Fleece Full-Zip Windrunner Jacket with black and white design.]\n", + "87 Nike_men_user_test_files/M+NP+DFADV+NPT+6+IN+SHORT.png Nike_men_user_test.html 1 [] [Nike Pro Training Men's Dri-FIT ADV 6\" Shorts] [Man wearing blue Nike Dri-FIT ADV 6\" shorts and training gear, featuring logo on chest.]\n", + "88 Nike_men_user_test_files/M+NSW+AIR+MAX+95+WVN+JKT.png Nike_men_user_test.html 1 [] [Nike Sportswear Men's Woven Jacket in gray color.] [Nike Sportswear Men's Woven Jacket with a logo patch.]\n", + "89 Nike_men_user_test_files/M+NSW+AIR+MAX+95+WVN+PANT.png Nike_men_user_test.html 1 [] [Nike Sportswear Men's Woven Pants, black with logo detail.] [Model wearing Nike Sportswear woven tracksuit with logo details for men's clothing collection.]\n", + "90 Nike_men_user_test_files/M+NSW+SS+MAX+90+TEE+FR+SP26.png Nike_men_user_test.html 1 [] [Nike Sportswear Men's Max90 T-Shirt] [Black t-shirt with Nike Air Max design printed on it.]\n", + "91 Nike_men_user_test_files/M+NSW+SS+MAX90+TEE+KGJ2.png Nike_men_user_test.html 1 [] [Nike Sportswear 'Ken Griffey Jr.' Men's Max90 Short-Sleeve T-Shirt] [Nike Sportswear \"Ken Griffey Jr.\" Men's Max90 Short-Sleeve T-Shirt with graphic print.]\n", + "92 Nike_men_user_test_files/the-best-nike-beach-gifts.jpg Nike_men_user_test.html 1 [] [Two individuals sitting on a sandcastle wearing Nike clothing, related to Nike beach gift ideas.] [Two individuals relaxing in front of a sandcastle at the beach, representing a lifestyle aesthetic.]\n", + "93 https://media.wired.com/photos/68e030e70657e0c2fe68a56d/16:9/w_720%2Cc_limit/WIRED-AI-as_RELIGION_RED_ALT.jpg WIRED_science_user_test.html 3 [] [AI’s Next Frontier: Exploring an Algorithm for Consciousness, AI’s Next Frontier? Exploring an Algorithm for Consciousness., AI’s Next Frontier? An Algorithm for Consciousness] [Stylized portrait in red and black tones, possibly exploring themes of duality or reflection., Red and black silhouette of two faces in a room, possibly representing abstract concepts related to AI., Abstract black and red portrait with geometric shapes.]\n", + "94 https://media.wired.com/photos/6938a1462c86f578e7dfdbb7/16:9/w_720%2Cc_limit/WTE%2520brain%2520gear.jpg WIRED_science_user_test.html 2 [] [Illustration of a brain with circuits and wires, representing wearable technology., Brain Gear is the hot new wearable technology concept.] [Brain Gear: A wearable showcasing brain connections and technology in a stylized illustration., Stylized depiction of a pink brain connected to technology, possibly representing neural interfaces.]\n", + "95 https://media.wired.com/photos/696770c527e4d5dcaa4ce890/16:9/w_720%2Cc_limit/Pluribus_Photo_010804.jpg WIRED_science_user_test.html 1 [] [Two individuals outdoors under a clear blue sky.] [Two women standing outdoors with a water bottle against a blue sky and green landscape.]\n", + "96 https://media.wired.com/photos/69690ee78f59220ea2e720b9/16:9/w_720%2Cc_limit/sci-openai-2220468498.jpg WIRED_science_user_test.html 1 [] [OpenAI logo displayed on a futuristic screen, representing tech innovation.] [Blurred logo of OpenAl with text overlayed: OpenAI Invests in Sam Altman's New Brain-Tech Startup Merge Labs]\n", + "97 https://media.wired.com/photos/697cc8c5fec825eea30870e5/3:2/w_720%2Cc_limit/GettyImages-2257424044.jpg WIRED_science_user_test.html 1 [] [AI Digital Twins aiding diabetes and obesity management depicted with a human and digital hand connection.] [Abstract futuristic hand reaching towards a patterned light source, evoking themes of technology and interaction.]\n", + "98 https://media.wired.com/photos/6985ffc322e26927f08c23c1/16:9/w_720%2Cc_limit/sci-ny-datacenters-2163725750.jpg WIRED_science_user_test.html 1 [] [Aerial view of data centers, related to New York's pause consideration.] [Aerial view of industrial buildings and a lake near New York City.]\n", + "99 https://media.wired.com/photos/698b0ff7c15205b11b18c615/16:9/w_720%2Cc_limit/GettyImages-2260809279.jpg WIRED_science_user_test.html 1 [] [Record low snow in the West leads to water shortages, increased fire risk, and political challenges.] [Scenic view of ski slopes and town surrounded by snow-covered hills in winter.]\n", + "100 https://media.wired.com/photos/6994a673e3c49810b386ab2d/16:9/w_720%2Cc_limit/021726_Data-Emissions-False.jpg WIRED_science_user_test.html 1 [] [Big Tech claims generative AI will save the planet but provides little evidence.] [Black and white rendering of a large cylindrical tank with a green background and architectural elements.]\n", + "101 https://media.wired.com/photos/69961d8b368f665536b3bb24/16:9/w_720%2Cc_limit/homepage-space-station.gif WIRED_science_user_test.html 2 [] [An artistic representation of the International Space Station fragmented against Earth's backdrop., Visual depiction of potential risks to the International Space Station.] [Composite image of the International Space Station in orbit around Earth., Image of the International Space Station orbiting Earth with solar panels, modules, and scientific equipment.]\n", + "102 https://media.wired.com/photos/69977b3aacabb32f3cbd37c7/16:9/w_720%2Cc_limit/sci-space-data-1648725322.jpg WIRED_science_user_test.html 1 [] [Could AI data centers be relocated to space? Satellite in orbit above Earth.] [A space station orbiting Earth with solar panels, potentially representing AI data center technology.]\n", + "103 https://media.wired.com/photos/6998701dc31375ebca5a4cab/16:9/w_720%2Cc_limit/GettyImages-2191227367.jpg WIRED_science_user_test.html 1 [] [Solar panels symbolizing the US renewable energy boom in recent years.] [A sprawling solar farm against the backdrop of mountains and clouds in autumn.]\n", + "104 https://media.wired.com/photos/699872684fbc7cc192b292e0/3:2/w_720%2Cc_limit/GettyImages-1345490899.jpg WIRED_science_user_test.html 1 [] [Blood Moon during total lunar eclipse on March 3.] [A digitally rendered image of a blood-red moon in space, illustrating the 'blood moon' lunar eclipse.]\n", + "105 https://media.wired.com/photos/699c2f4a78972f77e910da08/3:2/w_720%2Cc_limit/GettyImages-2258921729.jpg WIRED_science_user_test.html 1 [] [NASA delays Artemis II lunar mission launch, showing the rocket at sunset.] [Space launchpad with towers and equipment at sunset in Florida.]\n", + "106 https://media.wired.com/photos/699c832687b4ddbea4d1c67a/16:9/w_720%2Cc_limit/022326_Science-UFO-Files-Dissapointment.jpg WIRED_science_user_test.html 1 [] [Government alien files imagery suggesting limited surprises in disclosures.] [Black and white document images of a plane, possibly linked to government investigations into UFOs.]\n", + "107 https://media.wired.com/photos/69a058f77da3e019b30e91a8/16:9/w_1600%2Cc_limit/ScienceSourceImages_1730789.jpg WIRED_science_user_test.html 1 [] [The Shingles Virus May Be Aging You More Quickly] [Abstract illustration of a pink and blue cell with intricate patterns, possibly representing biological processes.]\n", + "108 https://media.wired.com/photos/69a1fc5ccd255f245e966b8e/16:9/w_720%2Cc_limit/sci-artemis2-2256758081.jpg WIRED_science_user_test.html 1 [] [NASA's Artemis program advancements shown in rocket assembly image.] [A large orange rocket stands inside a hangar during preparation for launch.]\n", + "109 https://media.wired.com/photos/69a5818dfb8b2b3db6442eed/16:9/w_720%2Cc_limit/GettyImages-1250649650.jpg WIRED_science_user_test.html 1 [] [Oil tanker at sea with visible emissions, symbolizing global oil trade and environmental concerns.] [A large tanker sailing on the sea under clear blue skies.]\n", + "110 https://media.wired.com/photos/69a87016c7816c1e1584e8ee/3:2/w_720%2Cc_limit/Big-Tech-Signs-Nonbinding-White-House-Pledge-To-Protect-Consumers-From-Data-Centers-Science-2250991059.jpg WIRED_science_user_test.html 1 [] [Protest sign reading 'You Can't Drink Data' and 'Water is Life' with a heart and water drop illustration.] [Protestor holding sign reading 'YOU CAN'T DRINK DATA: WATER IS LIFE.']\n", + "111 https://media.wired.com/photos/69ab02c4ae15bcb547e25ca5/16:9/w_720%2Cc_limit/GettyImages-1253877737.jpg WIRED_science_user_test.html 1 [] [Close-up of a left-handed person writing in a notebook, illustrating research on left-handedness and competitiveness.] [Person writing in a notebook with pen, representing hands-on learning and activity.]\n", + "112 https://media.wired.com/photos/69ab5a2715dae1d56d0bffb8/16:9/w_720%2Cc_limit/Why-MAHA-Is-Obsessed-With-Shared-Decision-Making-Science-2210910497.jpg WIRED_science_user_test.html 1 [] [Two individuals in suits conversing at a public event.] [Two men in suits discussing in a conference hall during an event.]\n", + "113 https://media.wired.com/photos/69aebbb0ad83313d7f9d7cf9/16:9/w_640%2Ch_360%2Cc_limit/030926_Science-Sleep-Apnea-Tech.jpg WIRED_science_user_test.html 1 [] [Visual representation of advancements in sleep apnea treatment technology, showing medical tests and equipment.] [Abstract black and teal collage with medical elements.]\n", + "114 https://media.wired.com/photos/69b00c9e772e2c790732bbac/16:9/w_720%2Cc_limit/GettyImages-183097875.jpg WIRED_science_user_test.html 1 [] [Interstellar Comet 3I/Atlas, containing alcohol, depicted with colorful tail in space.] [Interstellar Comet 3I/Atlas reveals a surprising abundance of alcohol in its composition.]\n", + "115 https://media.wired.com/photos/69b06741afd392d14ab2c8ea/16:9/w_640%2Ch_360%2Cc_limit/science_measles_GettyImages-2259641016.jpg WIRED_science_user_test.html 1 [] [A yellow sign reads 'Measles Vaccines and Flu Vaccines - SC DPH'.] [A yellow sign reads 'Measles and Flu Vaccines' in a rural setting.]\n" + ] + } + ], + "source": [ + "total_unique_images = df['image_url'].nunique() #len(df.groupby('image_url').size())\n", + "\n", + "empty_mask = df['user_alt_text'] == ''\n", + "\n", + "# Unique images where original_alt_text is empty (at least once)\n", + "empty_images = df.loc[empty_mask, 'image_url'].nunique()\n", + "non_empty_images = total_unique_images - empty_images\n", + "pct_empty = empty_images / total_unique_images * 100\n", + "pct_non_empty = non_empty_images / total_unique_images * 100\n", + "\n", + "print(f\"Total unique image_url: {total_unique_images}\")\n", + "print(f\"Empty user_alt_text: {empty_images} ({pct_empty:.2f}%)\")\n", + "print(f\"Non-empty user_alt_text: {non_empty_images} ({pct_non_empty:.2f}%)\")\n", + "\n", + "# Group by image_url to collapse repeated entries\n", + "cols = ['image_url', 'page_url', 'user_alt_text', 'llm_alt_text_1', 'llm_alt_text_2']\n", + "empty_rows = df.loc[empty_mask, cols]\n", + "\n", + "grouped = empty_rows.groupby('image_url').agg(\n", + " page_url=('page_url', 'first'),\n", + " occurrences=('user_alt_text', 'count'),\n", + " user_alt_text_values=('user_alt_text', lambda x: list(x.unique())),\n", + " llm_alt_text_1_values=('llm_alt_text_1', lambda x: list(x.unique())),\n", + " llm_alt_text_2_values=('llm_alt_text_2', lambda x: list(x.unique())),\n", + ").reset_index()\n", + "\n", + "print(\"\\nGrouped rows with empty user_alt_text:\")\n", + "print(grouped.to_string())" + ] + }, + { + "cell_type": "markdown", + "id": "8a9effbb", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "id": "01a15685", + "metadata": {}, + "source": [ + "## now i want to check the agreement on 'user_alt_text' assegnmnet as empty string on the same image_url field\n", + "il numero delle stringhe vuote dell'utente non è affidabile, semplicemnete magari non le hanno scritte per tempo" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "c3481c95", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total unique image_url: 205\n", + "Full agreement → all empty: 23 (11.22%)\n", + "Full agreement → all non-empty: 89 (43.41%)\n", + "Disagreement: 93 (45.37%)\n", + "\n", + "Image URLs with disagreement:\n", + " image_url total_annotations empty_count non_empty_count\n", + "1 Amazon_kitchen_user_test_files/51mF3c-BLpL._AC_UL320_.jpg 2 1 1\n", + "2 Amazon_kitchen_user_test_files/51tjDtDQdWL._AC_UL320_.jpg 5 2 3\n", + "3 Amazon_kitchen_user_test_files/61AwsD8HRNL._AC_UL320_.jpg 4 2 2\n", + "4 Amazon_kitchen_user_test_files/61VjM8Sd6kL._AC_UL320_.jpg 2 1 1\n", + "5 Amazon_kitchen_user_test_files/61W3TWy1saL._AC_UL320_.jpg 3 1 2\n", + "6 Amazon_kitchen_user_test_files/61ZdhggeA2L._AC_UL320_.jpg 3 1 2\n", + "8 Amazon_kitchen_user_test_files/719IIjUk7OL._AC_UL320_.jpg 3 1 2\n", + "9 Amazon_kitchen_user_test_files/71B8kNOY6QL._AC_UL320_.jpg 3 1 2\n", + "10 Amazon_kitchen_user_test_files/71BOLmVEzVL._AC_SR322,134_CB1169409_QL70_.jpg 3 1 2\n", + "18 Amazon_kitchen_user_test_files/71uADhIeHQL._AC_UL320_.jpg 4 1 3\n", + "19 Amazon_kitchen_user_test_files/71uq-Tvf8tL._AC_UL320_.jpg 4 2 2\n", + "26 Amazon_kitchen_user_test_files/81FX07lfydL._AC_UL320_.jpg 5 1 4\n", + "30 Amazon_kitchen_user_test_files/81W173Q69NL._AC_UL320_.jpg 2 1 1\n", + "34 Amazon_kitchen_user_test_files/81gjQpdliyL._AC_UL320_.jpg 3 1 2\n", + "40 Amazon_kitchen_user_test_files/91rjiaOyWML._AC_UL320_.jpg 2 1 1\n", + "41 CNN_Home_user_test_files/008-008-ap26059717007628.jpg 2 1 1\n", + "43 CNN_Home_user_test_files/117871-minelayersstriaghofhormuz-clean-00-00-00-00-still001.jpg 16 3 13\n", + "44 CNN_Home_user_test_files/117887-joerogan-trump-iran-thumb-clean.jpg 3 1 2\n", + "47 CNN_Home_user_test_files/2026-03-10t150127z-1377402233-rc2s9o8ka4ft-rtrmadp-3-iran-crisis-leader.JPG 11 2 9\n", + "49 CNN_Home_user_test_files/ap26067484115759-20260311143008704.jpg 3 1 2\n", + "50 CNN_Home_user_test_files/ap26069507892459.jpg 2 1 1\n", + "53 CNN_Home_user_test_files/atlantis-hires-024-flat-edit-v2-copy-1.jpg 5 2 3\n", + "56 CNN_Home_user_test_files/c-gettyimages-2265924275.jpg 10 5 5\n", + "57 CNN_Home_user_test_files/gettyimages-1434807928.jpg 7 1 6\n", + "59 CNN_Home_user_test_files/gettyimages-2160812639.jpg 13 3 10\n", + "60 CNN_Home_user_test_files/gettyimages-2168856012.jpg 4 1 3\n", + "64 CNN_Home_user_test_files/gettyimages-2226239770-20260303221718957.jpg 17 2 15\n", + "67 CNN_Home_user_test_files/gettyimages-2255435511.jpg 2 1 1\n", + "68 CNN_Home_user_test_files/gettyimages-2259341238-20260311200559984.jpg 2 1 1\n", + "69 CNN_Home_user_test_files/gettyimages-2263930943.jpg 2 1 1\n", + "72 CNN_Home_user_test_files/gettyimages-622913572.jpg 10 3 7\n", + "76 CNN_Home_user_test_files/screenshot-2026-03-11-at-3-40-55-pm.png 4 1 3\n", + "78 CNN_Home_user_test_files/thumb-3-20260225204059793.jpg 6 1 5\n", + "79 CNN_Home_user_test_files/thumbnail-kim-guns-nk-1-vrtc.jpg 4 1 3\n", + "81 Fox_News_user_test_files/NEWSLETTER_LIFESTYLE_LOGO-532x120.png 4 1 3\n", + "82 Fox_News_user_test_files/acq-2.jpg 6 4 2\n", + "84 Fox_News_user_test_files/americas-most-expensive-pizza-chains-2.jpg 5 2 3\n", + "89 Fox_News_user_test_files/chick-fil-a-sandwich-fries-chicken.jpg 5 2 3\n", + "90 Fox_News_user_test_files/coffee-shop-female-customer.gif 3 1 2\n", + "93 Fox_News_user_test_files/food-drink-black-cherries-breast-cancer-study-mice-2.jpg 4 2 2\n", + "94 Fox_News_user_test_files/food-drink-cancer-preventing-healthy-foods-what-to-know-2.jpg 2 1 1\n", + "95 Fox_News_user_test_files/foodie.jpg 4 2 2\n", + "102 Fox_News_user_test_files/image.jpg 4 1 3\n", + "103 Fox_News_user_test_files/jfk-jr-carolyn-bessette-kennedy-marriage1.jpg 2 1 1\n", + "109 Fox_News_user_test_files/suzy-karadsheh-olive-oil-split.jpg 2 1 1\n", + "112 Fox_News_user_test_files/woman-holding-hot-mug-tea.png 4 2 2\n", + "118 LiveScience_user_test_files/7kJDueUYJVYTkJH38UuHPo-450-80.jpg 2 1 1\n", + "120 LiveScience_user_test_files/Dvf2V5cUHtcV6sf7m38HSQ-450-80.jpg 6 2 4\n", + "121 LiveScience_user_test_files/NJ5Hd675vr5zvWxpuZ2rvJ-450-80.jpg 3 2 1\n", + "122 LiveScience_user_test_files/RDEr3MZzWVDnXRKbFzLhPE-450-80.jpg 6 2 4\n", + "123 LiveScience_user_test_files/gKU9oNsfCUXydiKQFZn5yC-450-80.jpeg 6 1 5\n", + "124 LiveScience_user_test_files/gwVZfGDoH4gbHJC74NxAka-450-80.jpg 3 2 1\n", + "125 LiveScience_user_test_files/o4HHzvcNZSRbjXpWMHzmJ6-415-80.jpg 6 2 4\n", + "126 LiveScience_user_test_files/pxWUkgwqmnQhYiRZUQPai6-450-80.jpg 5 2 3\n", + "127 LiveScience_user_test_files/sTenoWjZtGXYvD6uVwDYEZ-450-80.jpg 7 3 4\n", + "131 LiveScience_user_test_files/xNWjTGpcHmjuaY35taLAij-450-80.jpg 6 2 4\n", + "132 LiveScience_user_test_files/xg9ByKvedo58ek7ACaewgW-450-80.jpg 3 2 1\n", + "133 Nike_men_user_test_files/13-nike-tennis-gifts-for-players-of-all-levels.jpg 4 1 3\n", + "134 Nike_men_user_test_files/8-best-yoga-gifts-by-nike.jpg 4 1 3\n", + "138 Nike_men_user_test_files/DB+M+NK+TF+SI+BRSH+PO+HD.png 4 1 3\n", + "141 Nike_men_user_test_files/M+NK+CLUB+ALUMNI+FT+SHORT.png 4 1 3\n", + "142 Nike_men_user_test_files/M+NK+CLUB+WVN+CARGO+PANT+UF.png 3 1 2\n", + "143 Nike_men_user_test_files/M+NK+DF+COF+JSY+LS+FR+SP26.png 2 1 1\n", + "144 Nike_men_user_test_files/M+NK+DF+PAR+SHRT+AT+KNEE.png 6 2 4\n", + "145 Nike_men_user_test_files/M+NK+DF+STRDE+REALTREE+5BFSHRT.png 5 2 3\n", + "146 Nike_men_user_test_files/M+NK+DF+STRIDE+REALTREE+JKT.png 6 2 4\n", + "147 Nike_men_user_test_files/M+NK+DF+TCH+WVN+PANT.png 3 1 2\n", + "148 Nike_men_user_test_files/M+NK+DF+VLCTY+POLO+LS+SOLID.png 6 2 4\n", + "150 Nike_men_user_test_files/M+NK+TCH+FLC+JGGR+AMD+2K26.png 4 1 3\n", + "151 Nike_men_user_test_files/M+NK+TCH+FLC+WR+FZ+JKT+AMD+26.png 4 1 3\n", + "152 Nike_men_user_test_files/M+NP+DFADV+NPT+6+IN+SHORT.png 5 1 4\n", + "154 Nike_men_user_test_files/M+NSW+AIR+MAX+95+WVN+JKT.png 4 1 3\n", + "155 Nike_men_user_test_files/M+NSW+AIR+MAX+95+WVN+PANT.png 2 1 1\n", + "156 Nike_men_user_test_files/M+NSW+SS+MAX+90+TEE+FR+SP26.png 3 1 2\n", + "157 Nike_men_user_test_files/M+NSW+SS+MAX90+TEE+KGJ2.png 4 1 3\n", + "161 Nike_men_user_test_files/the-best-nike-beach-gifts.jpg 2 1 1\n", + "170 https://media.wired.com/photos/69690ee78f59220ea2e720b9/16:9/w_720%2Cc_limit/sci-openai-2220468498.jpg 2 1 1\n", + "174 https://media.wired.com/photos/697cc8c5fec825eea30870e5/3:2/w_720%2Cc_limit/GettyImages-2257424044.jpg 2 1 1\n", + "178 https://media.wired.com/photos/698b0ff7c15205b11b18c615/16:9/w_720%2Cc_limit/GettyImages-2260809279.jpg 2 1 1\n", + "181 https://media.wired.com/photos/6994a673e3c49810b386ab2d/16:9/w_720%2Cc_limit/021726_Data-Emissions-False.jpg 2 1 1\n", + "182 https://media.wired.com/photos/69961d8b368f665536b3bb24/16:9/w_720%2Cc_limit/homepage-space-station.gif 3 2 1\n", + "183 https://media.wired.com/photos/69977b3aacabb32f3cbd37c7/16:9/w_720%2Cc_limit/sci-space-data-1648725322.jpg 2 1 1\n", + "185 https://media.wired.com/photos/6998701dc31375ebca5a4cab/16:9/w_720%2Cc_limit/GettyImages-2191227367.jpg 2 1 1\n", + "186 https://media.wired.com/photos/699872684fbc7cc192b292e0/3:2/w_720%2Cc_limit/GettyImages-1345490899.jpg 4 1 3\n", + "188 https://media.wired.com/photos/699c2f4a78972f77e910da08/3:2/w_720%2Cc_limit/GettyImages-2258921729.jpg 4 1 3\n", + "192 https://media.wired.com/photos/69a058f77da3e019b30e91a8/16:9/w_1600%2Cc_limit/ScienceSourceImages_1730789.jpg 2 1 1\n", + "194 https://media.wired.com/photos/69a1fc5ccd255f245e966b8e/16:9/w_720%2Cc_limit/sci-artemis2-2256758081.jpg 2 1 1\n", + "195 https://media.wired.com/photos/69a5818dfb8b2b3db6442eed/16:9/w_720%2Cc_limit/GettyImages-1250649650.jpg 2 1 1\n", + "198 https://media.wired.com/photos/69a87016c7816c1e1584e8ee/3:2/w_720%2Cc_limit/Big-Tech-Signs-Nonbinding-White-House-Pledge-To-Protect-Consumers-From-Data-Centers-Science-2250991059.jpg 5 1 4\n", + "200 https://media.wired.com/photos/69ab02c4ae15bcb547e25ca5/16:9/w_720%2Cc_limit/GettyImages-1253877737.jpg 5 1 4\n", + "201 https://media.wired.com/photos/69ab5a2715dae1d56d0bffb8/16:9/w_720%2Cc_limit/Why-MAHA-Is-Obsessed-With-Shared-Decision-Making-Science-2210910497.jpg 4 1 3\n", + "202 https://media.wired.com/photos/69aebbb0ad83313d7f9d7cf9/16:9/w_640%2Ch_360%2Cc_limit/030926_Science-Sleep-Apnea-Tech.jpg 4 1 3\n", + "204 https://media.wired.com/photos/69b06741afd392d14ab2c8ea/16:9/w_640%2Ch_360%2Cc_limit/science_measles_GettyImages-2259641016.jpg 4 1 3\n" + ] + } + ], + "source": [ + "# Flag rows where user_alt_text is empty\n", + "df['user_alt_empty'] = (df['user_alt_text'] == '').astype(int)\n", + "\n", + "# For each image_url, check if all annotators agree on empty user_alt_text\n", + "agreement = df.groupby('image_url').agg(\n", + " total_annotations=('user_alt_empty', 'count'),\n", + " empty_count=('user_alt_empty', 'sum'),\n", + ").reset_index()\n", + "\n", + "agreement['non_empty_count'] = agreement['total_annotations'] - agreement['empty_count']\n", + "agreement['full_agreement_empty'] = agreement['empty_count'] == agreement['total_annotations']\n", + "agreement['full_agreement_non_empty'] = agreement['non_empty_count'] == agreement['total_annotations']\n", + "agreement['disagreement'] = ~(agreement['full_agreement_empty'] | agreement['full_agreement_non_empty'])\n", + "\n", + "total_images = len(agreement)\n", + "agree_empty = agreement['full_agreement_empty'].sum()\n", + "agree_non_empty = agreement['full_agreement_non_empty'].sum()\n", + "disagree = agreement['disagreement'].sum()\n", + "\n", + "print(f\"Total unique image_url: {total_images}\")\n", + "print(f\"Full agreement → all empty: {agree_empty} ({agree_empty / total_images * 100:.2f}%)\")\n", + "print(f\"Full agreement → all non-empty: {agree_non_empty} ({agree_non_empty / total_images * 100:.2f}%)\")\n", + "print(f\"Disagreement: {disagree} ({disagree / total_images * 100:.2f}%)\")\n", + "\n", + "print(\"\\nImage URLs with disagreement:\")\n", + "print(agreement[agreement['disagreement']][['image_url', 'total_annotations', 'empty_count', 'non_empty_count']].to_string())" + ] + }, + { + "cell_type": "markdown", + "id": "967e2c13", + "metadata": {}, + "source": [ + "# conto caratteri per submission (gli spazi non contano)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "ecb23e75", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Non-whitespace characters: 8971\n" + ] + } + ], + "source": [ + "file=\"C:\\\\cartella_condivisa\\MachineLearning\\\\HIISlab\\\\accessibility\\\\Materiale_mio\\\\user_test_03_2026_ASSETS2026\\\\scrittura_articolo\\\\rebuttal\\official_rebuttal.txt\"\n", + "with open(file, \"r\",encoding=\"utf-8\") as f:\n", + " text = f.read()\n", + "\n", + "count = sum(1 for c in text if not c.isspace())\n", + "print(f\"Non-whitespace characters: {count}\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "accessibility", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.19" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}