{
  "@components": {
    "actions": {
      "@id": "https://www.arpa.veneto.it/api/dati-ambientali/dati-in-diretta/luminosita-del-cielo/old_brillanza/@actions"
    }, 
    "breadcrumbs": {
      "@id": "https://www.arpa.veneto.it/api/dati-ambientali/dati-in-diretta/luminosita-del-cielo/old_brillanza/@breadcrumbs"
    }, 
    "contextnavigation": {
      "@id": "https://www.arpa.veneto.it/api/dati-ambientali/dati-in-diretta/luminosita-del-cielo/old_brillanza/@contextnavigation"
    }, 
    "navigation": {
      "@id": "https://www.arpa.veneto.it/api/dati-ambientali/dati-in-diretta/luminosita-del-cielo/old_brillanza/@navigation"
    }, 
    "subsite": {
      "@id": "https://www.arpa.veneto.it/api/dati-ambientali/dati-in-diretta/luminosita-del-cielo/old_brillanza/@subsite"
    }, 
    "types": {
      "@id": "https://www.arpa.veneto.it/api/dati-ambientali/dati-in-diretta/luminosita-del-cielo/old_brillanza/@types"
    }, 
    "workflow": {
      "@id": "https://www.arpa.veneto.it/api/dati-ambientali/dati-in-diretta/luminosita-del-cielo/old_brillanza/@workflow"
    }
  }, 
  "@id": "https://www.arpa.veneto.it/api/dati-ambientali/dati-in-diretta/luminosita-del-cielo/old_brillanza", 
  "@type": "Document", 
  "UID": "a06bd929f53a4c7ebf5137814e2ade88", 
  "allow_discussion": false, 
  "blocks": {
    "0d5ab943-0516-41e3-8817-900c5e4ed1b6": {
      "@type": "slate", 
      "plaintext": "La rilevazione dei dati di brillanza avviene in automatico ogni cinque minuti durante tutta la notte,attraverso gli strumenti di Padova (tetto della sede ARPAV), Passo Valles (BL), Casera Razzo (BL), Sorg\u00e0 (VR) e Pradon (RO).", 
      "value": [
        {
          "children": [
            {
              "text": "La rilevazione dei dati di brillanza avviene in automatico ogni cinque minuti durante tutta la notte,attraverso gli strumenti di Padova (tetto della sede ARPAV), Passo Valles (BL), Casera Razzo (BL), Sorg\u00e0 (VR) e Pradon (RO). \r"
            }
          ], 
          "type": "p"
        }
      ]
    }, 
    "16632045-ba46-4075-871c-99f86a26112b": {
      "@type": "slate", 
      "plaintext": "Sul tetto della sede ARPAV \u00e8 presente anche un altro strumento di monitoraggio denominato TESS, fornito in uso gratuito dall'Universit\u00e0 di Madrid nell'ambito del progetto europeo STAR4ALL.", 
      "value": [
        {
          "children": [
            {
              "text": "Sul tetto della sede ARPAV \u00e8 presente anche un altro strumento di monitoraggio denominato TESS, fornito in uso gratuito dall'Universit\u00e0 di Madrid nell'ambito del progetto europeo STAR4ALL. "
            }
          ], 
          "type": "p"
        }
      ]
    }, 
    "427d5b6e-2215-4db9-b3fb-0cc3e5077943": {
      "@type": "dataMap", 
      "center_lat": "45.7", 
      "center_long": "11.8", 
      "map_height": "600", 
      "resources": [
        {
          "@id": "566c1fc5-55b2-42d2-8792-603abe462480", 
          "default_color": {
            "a": 1, 
            "b": 64, 
            "g": 180, 
            "r": 189
          }, 
          "default_icon": {
            "iconName": "circle", 
            "prefix": "fas"
          }, 
          "gis_field": "point", 
          "icon_size": "0.5", 
          "label": "${record.nome_stazione ? record.nome_stazione.replace(\"Brillanza\", \"\") : ' '}", 
          "marker_icon": "default", 
          "popup_text": "<div class=\"cms-ui\">\n    <div id=\"modal-loadmask\" class=\"ui dimmer active transition visible\" style=\"display: flex;\">\n        <div class=\"content\">\n            <div class=\"ui text loader\">Caricamento.</div>\n        </div>\n    </div>\n</div>\n\n<h3>${record.nome_stazione}</h3>\n\n<div class=\"row\">\n    <div class=\"col-3\">\n        <div class=\"nav flex-column nav-pills\" id=\"meteoTabPanel\" role=\"tablist\" aria-orientation=\"vertical\"></div>\n    </div>\n    <div class=\"col-9\">\n        <div class=\"tab-content\" id=\"meteoTabPanelContent\"></div>\n    </div>\n</div>\n\n<style>\n.nowrap {\n        white-space:nowrap;\n    }\n</style>\n\n<script>\n    const tabs = [\n        'TARIA2M',\n        'TARIA8M',\n        'PREC',\n        'UMID2M',\n        'UMID8M',\n        'VVENTO10M',\n        'VVENTO2M',\n        'VVENTO5M',        \n        'RADSOL',\n        'PRESS',\n        'LIDRO',\n        'PORT',\n        'NIVOM',\n        'VISIB',\n        'BRILLAIST'\n    ];\n    \n    const ordineSensoriTabellaDati = [\n        'TARIA2M',\n        'TARIA8M',\n        'PREC',\n        'PRECCUM',\n        'UMID2M',\n        'UMID8M',\n        'VVENTO10M',\n        'DVENTO10M',\n        'VVENTO2M',\n        'DVENTO2M',\n        'VVENTO5M',        \n        'DVENTO5M',        \n        'RADSOL',\n        'PRESS',\n        'LIDRO',\n        'PORT',\n        'NIVOM',\n        'VISIB',\n        'BRILLAIST'\n    ];\n    \n    const chartsColors = {\n        TARIA2M: 'rgb(208, 2, 27)',\n        TARIA8M: 'rgb(208, 2, 27)',\n        PREC: 'rgb(245, 166, 35)',\n        UMID2M: 'rgb(139, 87, 42)',\n        UMID8M: 'rgb(139, 87, 42)',\n        VVENTO10M: 'rgb(65, 117, 5)',\n        VVENTO2M: 'rgb(65, 117, 5)',\n        VVENTO5M: 'rgb(65, 117, 5)',\n        RADSOL: 'rgb(74, 144, 226)',\n        PRESS: 'rgb(144, 19, 254)',\n        LIDRO: 'rgb(0, 0, 254)',\n        PORT: 'rgb(0, 220, 0)',  \n        NIVOM: 'rgb(0, 0, 100)',\n        VISIB: 'rgb(0, 220, 0)',\n        BRILLAIST: 'rgb(208, 2, 27)' \n        \n    };\n    \n    \n    // flag per avere i console.log attivi oppure no\n    const DEBUG = false;\n    \n\n    /*------------------------------------------------------------------------------\n      ritorna la data con aggiunta di h ore\n    */\n    Date.prototype.addHours = function(h) {\n        this.setTime(this.getTime() + (h*60*60*1000));\n        return this;\n    }\n    /*------------------------------------------------------------------------------\n      ritorna la data con aggiunta di n minuti\n    */\n    Date.prototype.addMinutes = function(n) {\n        this.setTime(this.getTime() + (n*60*1000));\n        return this;\n    }\n        \n        \n    /**\n     * ritorna una data (2022-09-12T01:00:00) in UTC \n     * in realt\u00e0 , visto che tutte le date sono in solare, faccio finta che il solare\n     * corrisponda all'UTC in modo da non avere la conversione in locale del browser\n     */\n    Date.prototype.ConvIstante = function( ist, isUTC = false ) {\n        var nSolare = 0;\n        if (isUTC) {nSolare = 1;}\n        // 2022-09-12T01:00:00\n        // 0123456789012345678\n        var cosa = new Date(Date.UTC(ist.substring(0, 4), parseFloat(ist.substring(5, 7))-1, ist.substring(8, 10), parseFloat(ist.substring(11,13))+nSolare, ist.substring(14,16), 0, 0) );\n        this.setTime( cosa.getTime() );\n        return this;\n    }\n\n/*------------------------------------------------------------------------------\n  ritorna una stringa con la data nel formato indicato\n*/\nDate.prototype.Formato = function( formato ) {\n\n    var mm = ('0' + (this.getUTCMonth()+1) ) .slice(-2);\n    var dd = ('0' + this.getUTCDate()).slice(-2);\n    var yyyy = this.getUTCFullYear();\n    var hh = ('0' + (this.getUTCHours())).slice(-2);\n    var mi = ('0' + this.getUTCMinutes()).slice(-2);\n    var ss = ('0' + this.getUTCSeconds()).slice(-2);\n    var mesi = ['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno','Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre']; \n    var giorni = ['domenica', 'luned\u00ec', 'marted\u00ec', 'mercoled\u00ec', 'gioved\u00ec', 'venerd\u00ec', 'sabato']; \n    \n    var sRet = '';\n    switch (formato) {\n        case 'gg g mmm YYYY':\n            sRet =giorni[ this.getUTCDay() ] + ' ' +  this.getUTCDate() + ' ' + mesi[ this.getUTCMonth() ] + ' ' + yyyy;\n            break;\n        case 'DD/MM/YYYY':\n            sRet = dd + '/' + mm + '/' + yyyy;\n            break;\n        case 'DD/MM/YYYY HH':\n            sRet = dd + '/' + mm + '/' + yyyy + ' ' + hh;\n            break;\n        case 'DD/MM/YYYY HH:mm':\n            sRet = dd + '/' + mm + '/' + yyyy + ' ' + hh + ':' + mi;\n            break;\n        case 'DD HH'          :\n            sRet = dd + ' ' + hh;\n            break;\n        case 'DD'          :\n            sRet = dd;\n            break;\n        case 'HH:mm':\n            sRet = hh + ':' + mi;\n            break;\n        case 'HH':\n            sRet = hh;\n            break;\n        case 'mm':\n            sRet = mi;\n            break;\n        case 'YYYYMMDDHHmm':\n            sRet = yyyy + mm + dd + hh + mi;\n            break;\n        case 'YYYY-MM-DDTHH-mm':\n            sRet = yyyy + '-' + mm + '-' + dd + 'T' + hh + ':' + mi + ':00';\n            break;\n        default:\n            sRet = this.toString();\n            break;\n    }\n  \n    return sRet;\n}      \n\n\n\n    const tabnav = document.getElementById('meteoTabPanel');\n    const container = document.getElementById('meteoTabPanelContent');\n    const modalmask = document.getElementById('modal-loadmask');\n\n    const tooltiplableformat = {\n        year: 'numeric',\n        month: '2-digit',\n        day: '2-digit',\n        hour: '2-digit',\n        minute: '2-digit'\n    };\n    // modalmask.className = 'ui dimmer active transition visible';\n    modalmask.style.cssText = 'display:flex !important';\n    \n    //-------------------------------------------------------------------------\n    // funzione di log su console se DEBUG\n    function myConsoleLog(sFrase) {\n        if (DEBUG) { console.log(sFrase); }\n    }\n    \n    //-------------------------------------------------------------------------\n    // isNumeric pure java\n    function isNumeric(n) {\n      return !isNaN(parseFloat(n)) && isFinite(n);\n    }    \n    \n    // link per ottenere i dati visualizzati \n//    const linkJsonDati = 'https://api.arpa.veneto.it/REST/v1/meteo_meteogrammi_tabella?codseqst=${record.codseqst}'; \n    const linkJsonDati = 'https://api.arpa.veneto.it/REST/v1/meteo_brillanza_tabella?codseqst=${record.codseqst}'; \n\n    \n    // momento di aggiornamento dei dati visualizzati\n    var aggiornamento;\n    \n    //-------------------------------------------------------------------------\n    async function fetchStationData() {\n        const response = await fetch( linkJsonDati );\n        const stations = await response.json();\n\n        return stations;\n    }\n\n    //-------------------------------------------------------------------------\n    async function getData() {\n        const stationdata = await fetchStationData();\n        let sensors = {};\n\n        myConsoleLog('getData codseqst ' + ${record.codseqst});\n\n        stationdata.data.forEach((item) => {\n            if (!sensors[item.tipo]) {\n                sensors[item.tipo] = {\n                    data: [],\n                    label: item.nome_sensore,\n                    unitmeas: item.unitnm\n                }\n            }\n            \n            // momento di aggiornamento dei dati visualizzati\n            aggiornamento = item.aggiornamento;\n\n            // se il valore contiene una , (separatore delle migliaia) la tolgo\n            let valore = item.valore.replace(',','');\n            // se radiazione solare con unit\u00e0 di misura MJ/m2 la converto in W/m2\n            if (sensors[item.tipo].unitmeas == 'MJ/m2') {\n               valore = Math.round( valore * 277.7 );   // da MJ/m2 a W/m2 \n            }\n\n            // se visibilit\u00e0 allora metto in KM\n            if (item.tipo == 'VISIB') {\n                valore = valore / 1000;    // da metri a Km\n                \n                // arrotondamenti in base al numero\n                if (valore > 10) { \n                    valore = Math.round(valore); \n                } else {\n                    // 3 decimali\n                    valore = Math.round(valore*Math.pow(10,3))/Math.pow(10,3); \n                }\n                \n            }\n\n            sensors[item.tipo].data.push({\n                value: valore,\n                date: item.dataora\n            });\n        });\n        \n        // se unitmeas == \"MJ/m2\" correggo l'unit\u00e0 di misura in quanto ne ho appena modificato tutti i valori\n        // se unitmeas == \"magarcsec2\" la metto pi\u00f9 leggibile mag/arcsec2\n        Object.entries(sensors).forEach(entry => {\n          const [key, sensore] = entry;\n          if (sensore.unitmeas == \"MJ/m2\") {\n              sensors[key].unitmeas = \"W/m2\";\n          }\n          if (key == 'VISIB') {\n              sensors[key].unitmeas = \"Km\";   \n          }\n          \n        });\n        \n        // se ho la pioggia aggiungo il sensore PRECCUM con la cumulata giornaliera\n        Object.entries(sensors).forEach(entry => {\n            const [type, sensore] = entry;\n            if (type == 'PREC') {\n                // nuovo sensore della precipitazione cumulata giornaliera\n                const sPrecCum = 'PRECCUM'; \n                sensors[ sPrecCum ] = {\n                    data: [],\n                    label: 'Precipitazione cumulata',\n                    unitmeas: sensore.unitmeas\n                }\n                // per tutti i dati di pioggia ne calcolo la cumulata giornaliera nel sensore PRECCUM\n                let pCum = 0;\n                sensore.data.forEach((tuplaDatiSensore, index) => {\n                    var dataora = tuplaDatiSensore.date;      // var dataora = FormatTime('DD/MM/YYYY HH:mm', xvalori.value[0]);\n                    var valore = tuplaDatiSensore.value;\n\n                    myConsoleLog('PRECCUM dataora ' + dataora + ' valore ' + valore + ' cumulata prima ' + pCum + ' dopo ' + (pCum + Math.round( valore * 10) / 10) );\n\n                    if ( isNumeric( valore ) ) { \n                        pCum += Math.round( valore * 10) / 10;\n                    }  \n\n                    sensors[ sPrecCum ].data.push({\n                        value: parseFloat(pCum).toFixed(1),\n                        date: dataora\n                    });\n                    \n                    // alla mezzanotte la cumulata di pioggia si azzera\n                    // json \"dataora\":\"2022-09-06T02:00:00\"\n                    if ( dataora.substr(dataora.length - 8) == '00:00:00' ) {  \n                        pCum = 0;\n                    }   \n                });\n            }\n        });\n        \n        // se ho il sensore di BRILLANZA ci aggiungo le scansioni a 5 minuti mancanti\n        if (sensors['BRILLAIST']) {\n        \n            // scorro la brillanza e carico le scansioni orarie mancanti\n            // 2022-09-12T01:00:00\n            // 2022-09-12T00:00:00.000Z\n            var brill = sensors[ 'BRILLAIST' ];\n\n            myConsoleLog( 'BRILLAIST prima ' + JSON.stringify( sensors[ 'BRILLAIST' ] ) );        \n            \n            var valori = [];\n            var dAttesa = new Date().ConvIstante( brill.data[0].date )\n            brill.data.forEach((valore, index) => {\n                let datacorr = new Date().ConvIstante( brill.data[index].date );\n                myConsoleLog('dAttesa=' + dAttesa.Formato('YYYY-MM-DDTHH-mm') + ' datacorr=' + datacorr.Formato('YYYY-MM-DDTHH-mm') );                \n\n                // finch\u00e8 la dPrec \u00e8 inferiore alla data corrente aggiungo \"\" dato assente\n                while (dAttesa.getTime() < datacorr.getTime() ) {\n                    myConsoleLog('aggiunto 0 alla dAttesa=' + dAttesa.Formato('YYYY-MM-DDTHH-mm') );                \n\n                    valori.push( { date : dAttesa.Formato('YYYY-MM-DDTHH-mm'), value: null } );\n                    dAttesa.addMinutes(5);\n\n                }\n                valori.push( {date : brill.data[index].date, value: brill.data[index].value });\n                dAttesa.addMinutes(5);\n                \n            });\n            // cambio l'array dei valori\n            sensors[ 'BRILLAIST' ].data = valori;     \n            \n            myConsoleLog( 'BRILLAIST dopo ' + JSON.stringify( sensors[ 'BRILLAIST' ] ) );        \n        \n        }\n\n        return sensors;\n    }\n\n    //-------------------------------------------------------------------------\n    async function createHTML() {\n        const sensors = await getData();\n\n        let firstParameter = '';\n        \n        // aggiungo i tab dei sensori nel div del grafico\n        tabs.forEach(item => {\n            if (sensors[item]) {\n            \n                myConsoleLog('createHTML ' + item);\n            \n                if (firstParameter.length == 0) { firstParameter = item; }\n                createHTMLForTab(item, sensors[item].label, firstParameter);\n                initializeChart(item, sensors);\n                \n            }\n        });\n        \n        // tab della tabella dati\n        if (aggiornamento) {\n            myConsoleLog('createHTML Tabella');\n            createHTMLForTab('TABELLA', 'Tabella dati', firstParameter);\n            CreaTabella('TABELLA', sensors);\n        }    \n        \n        // aggiungo momento di aggiornamento dei dati presentati\n        var fraseAggiornam = 'Nessun valore negli ultimi giorni';\n        if (aggiornamento) {\n            var dAggior = new Date().ConvIstante( aggiornamento );\n            fraseAggiornam = 'Dati aggiornati il<br>' + dAggior.Formato('DD/MM/YYYY HH:mm') + ' (solare)'; \n        }    \n        const p = document.createElement('p');\n        p.setAttribute('class', 'text-center');\n        p.innerHTML = fraseAggiornam;\n        tabnav.append(p);\n\n        // modalmask.className = 'ui dimmer';\n        modalmask.style.cssText = 'display:none !important';\n    }\n\n    //-------------------------------------------------------------------------\n    // creazione della tabella dati\n    function createHTMLForTab(type, label, firstParameter) {\n        // create tab item\n        myConsoleLog('createHTMLForTab type ' + type + ' firstParameter ' + firstParameter);\n        \n        const a = document.createElement('a');\n        a.setAttribute('class', 'nav-link' + (type === firstParameter ? ' active' : ''));\n        a.setAttribute('id', 'tab-' + type);\n        a.setAttribute('data-toggle', 'tab');\n        a.setAttribute('href', '#tabcontent-' + type);\n        a.setAttribute('role', 'tab');\n        a.setAttribute('aria-controls', 'tabcontent-' + type);\n        a.setAttribute('aria-selected', (type === firstParameter ? 'true' : 'false'));\n        a.innerText = label;\n        tabnav.append(a);\n\n        // create tab content\n        const div = document.createElement('div');\n        div.setAttribute('id', 'tabcontent-' + type);\n        div.setAttribute('class', 'tab-pane fade' + (type === firstParameter ? ' show active' : ''));\n        div.setAttribute('role', 'tabpanel');\n        div.setAttribute('aria-labelledby', 'tab-' + type);\n\n        // il nome del sensore \u00e8 gi\u00e0 presente a sx div.innerHTML = '<h4>' + label + '</h4>' + '<canvas id=\"chart-' + type + '\"></canvas>';\n        div.innerHTML = '<canvas id=\"chart-' + type + '\"></canvas>';\n        container.append(div);\n\n        // init tab\n        const tabTrigger = new ARPAVAPI.bootstrap.Tab(a);\n        a.addEventListener('click', function (event) {\n            event.preventDefault()\n            tabTrigger.show()\n        });\n    }\n\n\n    //-------------------------------------------------------------------------\n    // oggetto freccia per il grafico della velocit\u00e0/direzione del vento\n    var xDirez;\n    var myCanvasDirez = document.createElement(\"canvas\");\n    myCanvasDirez.id = \"myfreccia\";\n    var ctxDirez = myCanvasDirez.getContext(\"2d\");\n    var imageDirez = new Image();\n    imageDirez.src = \"data:image/png;base64,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\";    \n    imageDirez.onload = function() {\n      ctxDirez.drawImage(imageDirez, 0, 0);\n    };\n    \n    \n    //-------------------------------------------------------------------------\n    // creo la tabella dei dati presenti nei grafici \n    function CreaTabella(type, sensors) {\n        myConsoleLog('CreaTabella');\n        \n        // TODO gestione della data di aggiornamento!!!!!\n        let testoRun;\n\n        // gestione della seconda riga se velocit\u00e0 vento con la direzione\n        let nSpan = 'style=\"text-align: center\"';\n\n        // se stazione con direzione del vento allora titolo su due righe\n        let bIsDVento = false;\n        let tupleDirez;\n        let nomeDirez;\n        Object.entries(sensors).forEach(entry => {\n            const [type, sensore] = entry;\n\n            // se type VVENTO allora anche la direzione su due colonne\n            if ( type.indexOf( 'VVENTO' ) >= 0 ) {\n                nomeDirez = type.replace('VVENTO', 'DVENTO');\n                if ( sensors[ nomeDirez ] ) {\n                    bIsDVento = true;\n                    tupleDirez = sensors[ nomeDirez ].data;\n                    nSpan = 'rowspan=\"2\" style=\"vertical-align: middle; text-align: center\"';\n                }\n            }\n            \n        });\n        \n        // gestione delle colonne nell'ordine corretto della tabella dei dati finale\n        let xNomiGiusti = [];\n        ordineSensoriTabellaDati.forEach((nomeColonna, index) => {\n            // cerco se ho il sensore nei sensori della stazione\n            Object.entries(sensors).forEach(entry => {\n                const [type, sensore] = entry;\n                // esiste il sensore da intabellare nei sesnori della stazione?\n                if ( nomeColonna == type ) {\n                    if ( ! xNomiGiusti[ type ] ) {\n                        xNomiGiusti.push( type );\n                    }\n                }\n            });\n        });\n        \n        myConsoleLog('xNomiGiusti' + JSON.stringify(xNomiGiusti) );\n            \n        // classi per centrare il contenuto\n        const sC = ' class=\"align-middle text-center nowrap\" ';\n            \n        // titoli delle colonne dei dati presenti\n        let titoloDati = '<tr>' + '<th' + sC + nSpan + '>Data<br>ora solare</th>';        \n      \n        // array delle righe nella tabella\n        let righe = [];\n        let nRiga = 0;\n        let iTab;       // variabile per ciclare sui dati dei sensori\n        let bAssente = false;       // flag per mettere >> solo se ci sono dati assenti in tabella\n        \n        // ciclo tutti i sensori presenti  nell'ordine delle colonne da scrivere\n        xNomiGiusti     \n        xNomiGiusti.forEach((nomeColonna, index) => {\n        \n        // Object.entries(sensors).forEach(entry => {\n            // const [type, sensore] = entry;\n        \n            const sensore = sensors[nomeColonna];\n            const type = nomeColonna; \n            \n            \n            // correggo i nomi del sensore per l'intestazione delle colonne\n            let nomeSensore = sensore.label.replace(' a ', '<br>a '); \n            nomeSensore = nomeSensore.replace('Precipitazione cumulata', 'Precipitazione<br>cumulata dalle<br>ore 24'); \n            nomeSensore = nomeSensore.replace('Radiazione ', 'Radiazione<br>');\n            nomeSensore = nomeSensore.replace('Pressione', 'Pressione atmosferica<br>ridotta a livello<br>del mare');          \n\n            // intestazioni delle colonne: nome del sensore e unit\u00e0  di misura\n            if ( (type.indexOf('VVENTO') >= 0 ) && (bIsDVento) ) { \n                titoloDati += '<th' + sC + ' colspan=\"2\" style=\"text-align: center\">' + nomeSensore + '</th>';\n            } else if (type.indexOf('DVENTO') >= 0 ) {\n                // non devo mettere la colonna della DVENTO in quanto viene messa se esiste\n            } else {\n                titoloDati += '<th' + sC + nSpan + '>' + nomeSensore + ' (' + sensore.unitmeas + ')</th>';\n            }  \n\n            // compongo le righe e colonne della tabella dei dati\n            sensore.data.forEach((tuplaDatiSensore, index) => {\n                var dataora = tuplaDatiSensore.date;     \n                // 2022-09-08T05:00:00\n                // 0123456789012345678 \n                dataora = dataora.substr(8, 2) + '/' + dataora.substr(5, 2) + '/' + dataora.substr(0, 4) + ' ' + \n                          dataora.substr(11, 2) + ':' + dataora.substr(14, 2);\n                // 08/09/2022 05:00              \n                \n                var valore = tuplaDatiSensore.value;\n\n                // cerco la riga nella righe \n                let bCarica = true;\n                for (iTab in righe) {       // uso il for per avere il break\n                    if ( righe[iTab].dataora == dataora ) {\n                        bCarica = false;\n                        nRiga = iTab;\n                        break;\n                    } \n                }                \n                if ( bCarica ) { \n                    \n                    // aggiungo la riga nella tabella da pubblicare\n                    nRiga = righe.push( { dataora: dataora } );\n                    nRiga -= 1;  // zero based\n                }                \n\n                // valore da intabellare \n                if ( ! isNumeric( valore ) ) {\n                    bAssente = true;\n                    valore = '>>';\n                }\n                righe[nRiga][type] = valore; \n            \n                // se sensore VVento ho anche la direzione da mettere prendendola dal sensore corretto\n                if (type.indexOf('VVENTO') >= 0 ) { \n                    righe[ nRiga ][ nomeDirez ] = tupleDirez[ index ].value;\n                }\n                \n            });     // sensore.data.forEach((valore, index) => { \n          \n        });        \n        \n        titoloDati += '</tr>';\n        // seconda riga se dvento\n        if ( bIsDVento ) {\n            titoloDati += \n                '<tr>' + \n                '<th' + sC + '>Velocit\u00e0 <br>(m/s)</th>' + \n                '<th' + sC + '>Provenienza<br>(gradi)</th>' + \n                '</tr>';\n        }         \n        \n        // tabella vera e propria in ordine decrescente\n        righe.reverse();\n        \n        myConsoleLog('righe' + JSON.stringify(righe) );\n        \n        let righeDati = '';\n        for (iTab in righe) {\n            let tupla = righe[iTab];\n            righeDati += '<tr>';\n            let i;\n            // per tutte le colonne della riga\n            for (i in tupla) {\n                righeDati += '<td class=\"text-right nowrap\">' + tupla[i] + '</td>';\n            }\n            righeDati += '</tr>';\n        }  \n        \n        \n        var tabDati = '';\n        tabDati +=   '<div class=\"modal-body\" style=\"height: 400px;overflow-y: scroll;\">';\n        tabDati +=     '<table class=\"table table-sm table-striped table-bordered table-hover\">';        \n        tabDati +=     '<thead>' + titoloDati + '</thead>';\n        tabDati +=     '<tbody>' + righeDati + '</tbody>';\n        tabDati +=     '</table><br>';\n        \n        // info varie e link al file xml dei dati utilizzati\n        // TODO gestione della data di aggiornamento!!!!!\n        // tabDati += testoRun + ' <br>';\n        if ( bAssente ) { tabDati += 'Con >> dato assente.<br>'; }  \n        if ( bIsDVento) { tabDati += 'La provenienza del vento indica con 0=Nord, 90=Est, 180=Sud, 270=Ovest.<br>'; }  \n        tabDati +=   '<a href=\"' + linkJsonDati + '\" target=\"_blank\" type=\"text/json\">Dati della stazione in formato JSON</a>';\n\n        tabDati +=   '</div>';\n        \n        // div dove mettere la tabella        \n        const divTabella = document.getElementById('tabcontent-' + type);\n        divTabella.innerHTML = tabDati;\n        \n        container.append(divTabella);\n        \n    }\n            \n                   \n\n    // costruzione del grafico dle sensore\n    //  sensors array di tutti i dati presenti nel json \n    function initializeChart(type, sensors) {\n\n        myConsoleLog('initializeChart type ' + type);\n\n        // se ho valori da graficare\n        if (! sensors[ type ].data ) { return;} \n\n        // in base al type realizzo il grafico opportuno\n        var objGraph = null;\n        if ( type.indexOf('TARIA') >= 0 ) { \n            objGraph = GraficoTARIA(type, sensors); \n        }\n        if ( type.indexOf('PREC') >= 0 ) { \n            objGraph = GraficoPREC(type, sensors); \n        }\n        if ( type.indexOf('VVENTO')  >= 0 ) { \n            objGraph = GraficoVVENTO(type, sensors);\n        }\n        if ( type.indexOf('BRILLAIST')  >= 0 ) { \n            objGraph = GraficoBRILLAIST(type, sensors);\n        }\n        if ( type.indexOf('NIVOM')  >= 0 ) { \n            objGraph = GraficoStandard(type, sensors, 'line');\n            // questo devo solo forzarlo che parta da y = 0\n            objGraph.options.scales.y.beginAtZero = true;\n        }\n        \n        // tutti gli altri sensori li faccio standard\n        if ( ! objGraph ) {\n            objGraph = GraficoStandard(type, sensors, 'line');\n        }\n        \n        // se pressione allora metto il titolo della legenda corretto\n        if (type == 'PRESS') {\n            objGraph.data.datasets[0].label += ' ridotta a livello del mare';\n            objGraph.update();\n        }\n        \n    }\n\n    function padTo2Digits(num) {\n        return num.toString().padStart(2, '0');\n    }\n\n    function formatDate(date) {\n        return padTo2Digits(date.getDate()) + '-' + padTo2Digits(date.getHours());\n    }\n    \n    \n    // ------------------------------------------------------------------------\n    // grafico normale\n    function GraficoStandard(type, sensors, tipoGrafico) {\n        myConsoleLog('GraficoStandard');\n    \n        var sensor = sensors[type];\n        const ctx = document.getElementById('chart-' + type);\n    \n        let xPointStyle = 'circle';\n        let xPointRotation = function(ctx) { return 0; };\n        let xPointColor = chartsColors[type];\n        let xRadius = 3;\n\n        /* https://www.chartjs.org/ */\n        const myChart = new ARPAVAPI.Chart(\n            ctx, {\n            type: tipoGrafico,\n            responsive: true,\n            data: {\n                datasets: [{\n                    label: sensor.label,\n                    data: sensor.data,\n                    fill: false,\n                    borderColor: chartsColors[type],\n                    backgroundColor: chartsColors[type],\n                    tension: 0,\n                    pointStyle: xPointStyle,\n                    rotation: xPointRotation,\n                    pointBackgroundColor: xPointColor,\n                    pointBorderColor: xPointColor,\n                    radius: xRadius,\n                    parsing: {\n                        xAxisKey: 'date',\n                        yAxisKey: 'value',\n                    },\n                }]\n            },\n            options: {\n                scales: {\n                    x: {\n                        title: {\n                            display: true,\n                            text: 'Giorno e ora'\n                        },\n                        ticks: {\n                            callback: function (value, index, ticks) {\n                                let date = new Date(this.getLabelForValue(value));\n                                return formatDate(date);\n                            }\n                        }\n                    },\n                    y: {\n                        title: {\n                            display: true,\n                            text:  sensor.label + (sensor.unitmeas ? ' (' + sensor.unitmeas + ')' : '')\n                        }\n                    }\n                },\n                plugins: {\n                    tooltip: {\n                        callbacks: {\n                            title: context_list => {\n                                return new Date(context_list[0].label).toLocaleDateString(\"it-IT\", tooltiplableformat);\n                            },\n                        }\n                    }\n                }\n            },\n        });   \n        \n        return myChart; \n    \n    }\n    \n    \n    // ------------------------------------------------------------------------\n    // grafico specifico per la velocit\u00e0 del vento ( oltre al grafico lineare ci metto la freccia della direzione )\n    function GraficoVVENTO(type, sensors) {\n        myConsoleLog('GraficoVVENTO');\n\n        // creo il grafico standard a cui aggiungo le freccie della direzione \n        var myChart = GraficoStandard(type, sensors, 'line');\n        \n        // filippo 06/10/2022 NON metto la direzione in quano i codice sotto non funziona!\n        return myChart;\n        \n\n        // valori della velocit\u00e0 e direzione\n        var nomeDirez = type.replace('VVENTO', 'DVENTO');\n        var xDirez = sensors[ nomeDirez ];\n        var xVento = sensors[ type ]; \n\n        var sType = 'line';\n        let xPointColor = 'rgb(0, 0, 255)';\n        let xRadius = 2;\n\n        if (DEBUG) {        \n            xVento.data.forEach((valore, index) => {\n                myConsoleLog('VVENTO ' + index + ' velocita ' + xVento.data[index].value + ' direzione ' + xDirez.data[index].value );\n            });\n        }                    \n        \n        let xPointRotation = function(ctx) {\n            myConsoleLog( 'xPointRotation ' + ctx.dataIndex + ' direz ' + xDirez.data[ctx.dataIndex].value );  \n            return xDirez.data[ctx.dataIndex].value;\n        } \n\n        // modifico i punti del grafico standard per mettere la freccia orientata\n        myChart.data.datasets['0'].pointStyle = myCanvasDirez;\n        myChart.data.datasets['0'].radius = xRadius;\n        myChart.data.datasets['0'].rotation = xPointRotation;\n        \n        myChart.update();\n\n        return myChart; \n        \n    }\n    \n    \n    /*------------------------------------------------------------------------------\n      Ritorna la temperatura di rugiada\n    */\n    function TRugiada(temp, umid) {\n        temp = 1 * temp;\n        umid = 1 * umid;\n        var enat = 2.71828182845905, atdew = 17.27, btdew = 237.7, alfa, ru;\n        alfa = atdew * temp / (btdew + temp) + Math.log(umid / 100) / Math.log(enat);\n        ru = btdew * alfa / (atdew - alfa);\n        ru = parseFloat(Math.round(ru * 10) / 10).toFixed(1);\n        return ru;\n    }    \n    \n    // ------------------------------------------------------------------------\n    // grafico specifico per la temperatura aria ( ci metto la temperatura di rugiada)\n    function GraficoTARIA(type, sensors) {\n        myConsoleLog('GraficoTARIA');\n\n        // creo il grafico standard a cui aggiungo la temperatura di rugiada\n        var myChart = GraficoStandard(type, sensors, 'line');\n\n        // valori della temperatura e di umidit\u00e0 per il calcolo della rugiada\n        var nomeUmid = type.replace('TARIA', 'UMID');\n        var temp = sensors[ type ];\n        var umid = sensors[ nomeUmid ];\n        \n        if (! umid) { return myChart; }\n        \n/*        \n        myConsoleLog( 'temp ' + JSON.stringify(temp) );        \n        myConsoleLog( 'umid ' + JSON.stringify(umid) );        \n*/\n        // per ogni valore di temperatura ne calcolo quello di rugiada\n        var valori = [];\n        umid.data.forEach((valore, index) => {\n            valori.push( {date : temp.data[index].date, value: TRugiada(temp.data[index].value, umid.data[index].value) });\n        });\n\n/*\n        myConsoleLog( 'valori ' + JSON.stringify(valori) );        \n        myConsoleLog( 'chartsColors ' + nomeUmid + ' ' + JSON.stringify(chartsColors) );        \n*/\n\n        var sType = 'line';\n        let xPointStyle = 'circle';\n        // il colore della linea rugiada metto quello dell'umidit\u00e0\n        let xRadius = 3;\n\n        var rugiada = {\n                    label: 'Temperatura di rugiada',\n                    data: valori,\n                    datalabels: {align: 'start', anchor: 'start'},\n                    fill: false,\n                    borderColor: chartsColors[nomeUmid],\n                    backgroundColor: chartsColors[nomeUmid],\n                    tension: 0,\n                    pointStyle: xPointStyle,\n                    rotation: 0,\n                    pointBackgroundColor: chartsColors[nomeUmid],\n                    pointBorderColor: chartsColors[nomeUmid],\n                    radius: xRadius,\n                    parsing: {\n                        xAxisKey: 'date',\n                        yAxisKey: 'value',\n                    },\n                };\n\n        myChart.data.datasets.push(rugiada)\n        myChart.update();\n\n        return myChart; \n        \n    \n    }\n\n\n    // ------------------------------------------------------------------------\n    // grafico specifico per la brillanza istantanea\n    function GraficoBRILLAIST(type, sensors) {\n        myConsoleLog('GraficoBRILLAIST');\n\n        // creo il grafico standard per poi personalizzarlo\n        var myChart = GraficoStandard(type, sensors, 'line');\n        // senza pallini\n        myChart.data.datasets[0].radius = 0;        \n\n        // la y parte da 13 sino a 23\n        myChart.options.scales.y.min = 13;\n        myChart.options.scales.y.max = 23;\n        \n        // aggiungo la fascia oltre  il 22\n        var bri = sensors[ type ];\n\n        // per ogni valore di brillanza ne metto uno a 22\n        var valori = [];\n        bri.data.forEach((valore, index) => {\n            valori.push( {date : bri.data[index].date, value: 22 });\n        });\n\n        var sType = 'line';\n        let xPointStyle = 'circle';\n        let xRadius = 0;\n\n        var banda = {\n                    label: 'limite',\n                    data: valori,\n                    datalabels: {align: 'start', anchor: 'start'},\n                    fill: false,\n                    borderColor: chartsColors['NIVOM'],\n                    backgroundColor: chartsColors['NIVOM'],\n                    tension: 0,\n                    pointStyle: xPointStyle,\n                    rotation: 0,\n                    pointBackgroundColor: chartsColors['NIVOM'],\n                    pointBorderColor: chartsColors['NIVOM'],\n                    radius: xRadius,\n                    parsing: {\n                        xAxisKey: 'date',\n                        yAxisKey: 'value',\n                    },\n                };\n\n        myChart.data.datasets.push(banda)\n        myChart.options.plugins.legend.display = false;        \n\n        myChart.update();\n\n        return myChart; \n        \n    \n    }\n    \n    // ------------------------------------------------------------------------\n    // grafico specifico per la precipitazione ( ci metto nel secondo asse la cumulata giornaliera )\n    function GraficoPREC(type, sensors) {\n        myConsoleLog('GraficoPREC');\n\n        // creo il grafico standard a barre a cui aggiungo la precipitazione cumulata nel secondo asse\n        var myChart = GraficoStandard(type, sensors, 'bar');\n\n        // per ogni valore di prec calcolo la cumulata azzerandola dopo mezzanotte\n        var prec = sensors[ type ];\n        \n        var valori = [];\n        var cumulata = 0;\n        prec.data.forEach((valore, index) => {\n\n            cumulata += ( 1 * prec.data[index].value );\n        \n            valori.push( {date : prec.data[index].date, value: cumulata });\n            myConsoleLog('prec ' + prec.data[index].date + ' mm ' + prec.data[index].value + ' cumulata ' +  cumulata);\n\n            // prossimo valore di cumulata\n            var d = new Date( prec.data[index].date );\n            if ( d.getHours() == 0 ) { \n                cumulata = 0;\n                // aggiungo un punto per spezzare la linea\n                valori.push( {date : prec.data[index].date, value: null });\n            }\n            \n        });\n\n        myConsoleLog( 'prec ' + JSON.stringify(prec) );        \n\n\n        let xPointStyle = 'circle';\n        let xRadius = 3;\n\n        var pioggiaCumul = {\n                    yAxisID: 'y1',\n                    type: 'line',\n                    order: 1,\n                    label: 'Precipitazione cumulata',\n                    data: valori,\n                    datalabels: {align: 'start', anchor: 'start'},\n                    fill: false,\n                    borderColor: chartsColors['RADSOL'],\n                    backgroundColor: chartsColors['RADSOL'],\n                    tension: 0,\n                    pointStyle: xPointStyle,\n                    rotation: 0,\n                    pointBackgroundColor: chartsColors['RADSOL'],\n                    pointBorderColor: chartsColors['RADSOL'],\n                    radius: xRadius,\n                    parsing: {\n                        xAxisKey: 'date',\n                        yAxisKey: 'value'\n                    }\n                };\n\n        // metto il primo grafico a barre\n        myChart.data.datasets[0].type = 'bar';\n        myChart.data.datasets[0].order = 2;\n        myChart.options.scales.y.beginAtZero = true;\n\n        // aggiungo la cumulata\n        myChart.data.datasets.push(pioggiaCumul);\n        myChart.options.scales.y1 = {\n                    type: 'linear',\n                    display: true,\n                    position: 'right',\n                    title: {\n                        display: true,\n                        text: 'Cumulata (mm)'\n                        }\n                    \n                    };           \n\n        // la legenda la metto in ordine inverso in modo da avere prima la pioggia e poi la cumulata\n        myChart.options.plugins.legend.reverse = true;\n        \n        myChart.update();\n\n        return myChart; \n        \n    \n    }\n\n    createHTML();\n\n</script>", 
          "title": "Brillanza", 
          "tooltip": "${record.nome_stazione ? record.nome_stazione.replace(\"Brillanza\", \"\") : ' '}", 
          "url": "https://api.arpa.veneto.it/REST/v1/meteo_meteogrammi?coordcd=20067&orario=0&rete=MGRAMMIBRI"
        }
      ], 
      "zoom": "8"
    }, 
    "74121547-253e-4863-af30-6c4dc9d617be": {
      "@type": "title"
    }, 
    "97bc1c77-65e4-4d69-a245-83b5d4a68bd8": {
      "@type": "slate", 
      "plaintext": "I dati vengono aggiornati ogni giorno alle 9:30 solari", 
      "value": [
        {
          "children": [
            {
              "text": "I dati vengono aggiornati ogni giorno alle 9:30 solari"
            }
          ], 
          "type": "p"
        }
      ]
    }, 
    "9c3d34cd-075a-4154-9c05-75786bcaee0a": {
      "@type": "customJavascript", 
      "jscode": "\n    // link per ottenere i dati visualizzati \n    const linkJsonDati = 'https://api.arpa.veneto.it/REST/v1/meteo_meteogrammi?coordcd=20067&orario=0&rete=MGRAMMIBRI';\n\n    // flag per avere i console.log attivi oppure no\n    const DEBUG = false;\n\n\n    //-------------------------------------------------------------------------\n    // funzione di log su console se DEBUG\n    function myConsoleLog(sFrase) {\n        if (DEBUG) { console.log(sFrase); }\n    }\n    \n    //-------------------------------------------------------------------------\n    // isNumeric pure java\n    function isNumeric(n) {\n      return !isNaN(parseFloat(n)) && isFinite(n);\n    }    \n    \n    \n    //-------------------------------------------------------------------------\n    // ritorna la coord (pasata in gradi decimali) in gradi, primi , secondi \n    function CoordGradi( coord ) {\n\n      const g = Math.floor(coord);\n      const p = Math.floor( (coord - g ) * 60);\n      const s = (coord - g - (p/60) ) * 60 * 60;\n      const s2 = Math.round(s*1000)/1000;        // tre decimali arrotondati\n      const ret = ' ' + g + '\u00b0 ' + p + \"' \" + s2 + \"'' \"    \n\n      myConsoleLog('CoordGradi ' + coord + ' ->' + ret );\n\n      return ret;      \n    \n    }\n    \n    //-------------------------------------------------------------------------\n    async function fetchStationData() {\n        const response = await fetch( linkJsonDati );\n        const stations = await response.json();\n\n        myConsoleLog('contenuto' + JSON.stringify(stations, null, '\\t') );\n\n        return stations.data;\n    }\n\n    //-------------------------------------------------------------------------\n    async function getData() {\n        const elenco = await fetchStationData();\n\n        return elenco;\n    }\n\n\n    //-------------------------------------------------------------------------\n    async function createHTML() {\n        const elenco = await getData();\n\n        myConsoleLog('createHTML');\n\n\n        const st = ' style=\"white-space:nowrap;\" ';\n    \n\n        var sTabella = '';\n        sTabella += '<th class=\"text-center\" ' + st + '>Nome</th>' + \n                    '<th class=\"text-center\">Gestore</th>' + \n                    '<th class=\"text-center\">Coordinate</th>' + \n                    '<th class=\"text-center\">Quota (m s.l.m)</th>';\n\n        Object.entries(elenco).forEach(entry => {\n            const [index, stazione] = entry;\n            \n            sTabella += '<tr>';\n            sTabella += '<td ' + st + '>' + stazione.nome_stazione + '</td>';\n            sTabella += '<td ' + st + ' class=\"text-center\">' + stazione.gestore + '</td>';\n            sTabella += '<td ' + st + ' class=\"text-right\">' + CoordGradi( stazione.latitudine ) + 'N - ' + CoordGradi( stazione.longitudine ) + 'E</td>';\n            sTabella += '<td ' + st + ' class=\"text-right\">' + stazione.quota + '</td>';\n            sTabella += '</tr>';\n            \n        });   \n        \n        \n        var tabDati = '';\n        tabDati += '<div class=\"modal-body\" style=\"height: 400px;overflow-y: scroll;\">';\n        tabDati += '<table id=\"eleStazioni\" class=\"table table-sm table-striped table-bordered table-hover\">';        \n        tabDati += '<tbody>' + sTabella + '</tbody>';\n        tabDati += '</table>';\n        tabDati += '</div><br><br>';\n        \n        \n        // metto la tabella nel suo posto        \n        const t = document.createElement('div');\n        t.innerHTML = tabDati;\n        block.append(t);\n        \n    }\n        \n    \n    createHTML();\n    "
    }, 
    "c4675578-6dd3-4ee9-9324-5e5380d31899": {
      "@type": "slate", 
      "plaintext": "", 
      "value": [
        {
          "children": [
            {
              "text": ""
            }
          ], 
          "type": "p"
        }
      ]
    }, 
    "e9aad047-148b-4a35-9b87-580e3bdc26fe": {
      "@type": "slate", 
      "plaintext": "Nell'ambito delle attivit\u00e0 dell'Osservatorio Regionale permanente sul fenomeno dell'Inquinamento luminoso, ai dati raccolti da ARPAV si affiancano quelli provenienti dalle centraline del Dipartimento di Fisica ed Astronomia dell'Universit\u00e0 di Padova, installate presso gli osservatori astronomici di Cima Ekar e del Pennar - Asiago - VI e di Veneto Stellato,osservatori amatoriali di Nove (VI), Cattignano (VR), Masi (PD), Monte Baldo (VR), Arson (BL), Galzignano (PD) e Piadera (TV).", 
      "value": [
        {
          "children": [
            {
              "text": "Nell'ambito delle attivit\u00e0 dell'Osservatorio Regionale permanente sul fenomeno dell'Inquinamento luminoso, ai dati raccolti da ARPAV si affiancano quelli provenienti dalle centraline del Dipartimento di Fisica ed Astronomia dell'Universit\u00e0 di Padova, installate presso gli osservatori astronomici di Cima Ekar e del Pennar - Asiago - VI e di Veneto Stellato,osservatori amatoriali di Nove (VI), Cattignano (VR), Masi (PD), Monte Baldo (VR), Arson (BL), Galzignano (PD) e Piadera (TV). \r"
            }
          ], 
          "type": "p"
        }
      ]
    }, 
    "eae4fd10-7cfa-4f77-b041-5e2efecefd3f": {
      "@type": "richtext", 
      "richtext": {
        "data": "<p>Per ogni stazione sono pubblicati i dati di brillanza non validati degli ultimi tre giorni, in formato grafico e tabellare,<br />raccolti da un rilevatore SQM (Sky Quality Meter), che registra la luce entro un determinato campo visuale.<br />In termini astronomici, il valore della luminosit&agrave; o brillanza del cielo &egrave; espresso in magnitudini per arcosecondo quadro (mag/arcsec<sup>2</sup>).<br />All'unit&agrave; di misura corrisponde una scala inversa, ovvero un cielo di 21,5 mag/arcsec<sup>2</sup>&nbsp;sar&agrave; pi&ugrave; buio, e quindi meno inquinato,<br />di un cielo con brillanza di 18 mag/arcsec<sup>2</sup>, dove con pi&ugrave; buio s'intende un cielo in cui il numero di stelle visibili sia maggiore a parit&agrave; di zona osservata.<br />Il valore massimo di brillanza del cielo non inquinato osservato da Terra &egrave; pari a 22 mag/arcsec<sup>2</sup>.<br /><br /><br />Questi dati sono esposti in modo automatico, senza validazione preventiva.<br />ARPAV non assume responsabilit&agrave; alcuna per usi diversi dalla pura informazione.<br />In seguito a validazione i dati possono subire modifiche anche notevoli, oppure possono essere invalidati e quindi non riportati negli archivi definitivi.</p>"
      }
    }
  }, 
  "blocks_layout": {
    "items": [
      "74121547-253e-4863-af30-6c4dc9d617be", 
      "0d5ab943-0516-41e3-8817-900c5e4ed1b6", 
      "e9aad047-148b-4a35-9b87-580e3bdc26fe", 
      "16632045-ba46-4075-871c-99f86a26112b", 
      "427d5b6e-2215-4db9-b3fb-0cc3e5077943", 
      "97bc1c77-65e4-4d69-a245-83b5d4a68bd8", 
      "9c3d34cd-075a-4154-9c05-75786bcaee0a", 
      "eae4fd10-7cfa-4f77-b041-5e2efecefd3f", 
      "c4675578-6dd3-4ee9-9324-5e5380d31899"
    ]
  }, 
  "contributors": [], 
  "created": "2022-09-29T10:13:09+00:00", 
  "creators": [
    "fturetta"
  ], 
  "description": "", 
  "effective": "2022-10-04T15:33:30", 
  "exclude_from_nav": false, 
  "expires": null, 
  "hide_modification_date": true, 
  "id": "old_brillanza", 
  "is_folderish": true, 
  "items": [], 
  "items_total": 0, 
  "language": {
    "title": "Italiano", 
    "token": "it"
  }, 
  "layout": "document_view", 
  "lock": {
    "locked": false, 
    "stealable": true
  }, 
  "modified": "2023-06-26T12:22:58+00:00", 
  "next_item": {
    "@id": "https://www.arpa.veneto.it/api/dati-ambientali/dati-in-diretta/luminosita-del-cielo/index_html", 
    "@type": "Document", 
    "description": "", 
    "title": "Luminosit\u00e0 del cielo"
  }, 
  "parent": {
    "@id": "https://www.arpa.veneto.it/api/dati-ambientali/dati-in-diretta/luminosita-del-cielo", 
    "@type": "Folder", 
    "CroppedDescription": null, 
    "announcement_completed": null, 
    "announcement_type": null, 
    "competition_end": null, 
    "description": "", 
    "effective": "2022-12-12T11:53:06+00:00", 
    "end": null, 
    "id": "luminosita-del-cielo", 
    "image_field": null, 
    "image_scales": null, 
    "organization_type": null, 
    "review_state": "published", 
    "start": null, 
    "title": "Luminosit\u00e0 del cielo"
  }, 
  "preview_caption": null, 
  "preview_image": null, 
  "previous_item": {}, 
  "relatedItems": [], 
  "related_environmental_themes": [], 
  "related_provinces": [], 
  "related_structures": [], 
  "related_type": null, 
  "related_year": [], 
  "review_state": "published", 
  "rights": "", 
  "subjects": [], 
  "table_of_contents": null, 
  "title": "Brillanza del cielo notturno", 
  "version": "current", 
  "working_copy": null, 
  "working_copy_of": null
}