diff --git a/README.md b/README.md index ad57b4ba..d70896aa 100644 --- a/README.md +++ b/README.md @@ -226,6 +226,36 @@ Below is a listing of every possible machine-readable summary produced by Dark Sky. The listing is recursive so as to better describe how the various structural components interact. +### Status Information + +Instead of producing a summary of weather information, we may sometimes generate +a status message indicating an error of some sort. Such messages may take one of +the following forms: + +* `["sentence", [STATUS_MESSAGE, STATUS_TYPE, REASON]]` + +`STATUS_MESSAGE` may be one of the following: + +* `"next-hour-forecast-status"`: we have information to convey about our + hyperlocal next-hour forecasts + +`STATUS_TYPE` may be one of the following: + +* `"unavailable"`: no forecast is available for this request +* `"partially-unavailable"`: only a partial forecast is available for this request +* `"temporarily-unavailable"`: no forecast is available for this request, but we + expect it to be available again in the future + +`REASON` may be one of the following: + +* `"station-offline"`: we cannot generate a forecast because all nearby weather + stations are offline (e.g. for maintenance) +* `"station-incomplete"`: we cannot generate a forecast because of gaps in the + coverage of all nearby weather stations (e.g. radar beams are blocked by + local terrain) + +`"next-hour-forecast-status"`, `"unavailable"`, `"partially-unavailable"`, `"temporarily-unavailable"`, `"station-offline"`, and `"station-incomplete"` are not used in any other forms. + ### Moment Summaries When the API is producing a text summary for a single moment in time (that is, @@ -426,10 +456,15 @@ would be `["during", "rain", "next-wednesday"]`. * `RAIN_TYPE` * `SLEET_TYPE` * `SNOW_TYPE` -* `["parenthetical", SNOW_TYPE, SNOW_ACCUMULATION]`: For daily or weekly - summaries, if a significant amount of snow is expected, we will qualify it - with the amount of expected snow accumulation on the ground. (For example, - "snow (3-4 in.) throughout the day".) +* `["parenthetical", EXPECTED_PRECIP_TYPE, SNOW_ACCUMULATION]`: For daily or + weekly summaries, if a significant amount of snow is expected, we will + qualify it with the amount of expected snow accumulation. (For example, + "snow (3-4 in.) throughout the day".) PLEASE NOTE that it is possible for a + chance of snow accumulation to be forecasted even if the expected + precipitation type is rain or sleet: this may occur if the forecasted + temperature is right around the freezing point. Translations should clarify + that the parenthetical refers to a chance of snow in such circumstances. + (For example, "sleet (chance of 3-4 in. of snow) throughout the day".) In each of the below precipitation types, the intensity of precipitation is (very approximately) as follows: diff --git a/lib/lang/bg.js b/lib/lang/bg.js index 3a270ebe..4a09fe76 100644 --- a/lib/lang/bg.js +++ b/lib/lang/bg.js @@ -167,6 +167,10 @@ module.exports = { return str; }, - "unavailable-radar": "Прогнозата за идния час временно не е на разположение поради $1.", - "station-offline": "липса на информация от всички близки станции", + "next-hour-forecast-status": "Прогнозата за идния час $1 поради $2.", + "unavailable": "не е налична", + "temporarily-unavailable": "временно не е на разположение", + "partially-unavailable": "е частична", + "station-offline": "това че всички близки станции не са на линия", + "station-incomplete": "пропуски в покритието от близки станции", }; diff --git a/lib/lang/cy.js b/lib/lang/cy.js index fd467b8e..38fb42fb 100644 --- a/lib/lang/cy.js +++ b/lib/lang/cy.js @@ -48,7 +48,7 @@ module.exports = { "later-today-morning": "yn hwyrach bore yma", "today-afternoon": "y prynhawn yma", "later-today-afternoon": "yn hwyrach prynhawn yma", - "today-evening": "fin nos heno", + "today-evening": "gyda’r hwyr heno", "later-today-evening": "yn hwyrach fin nos heno", "today-night": "heno", "later-today-night": "yn hwyrach heno", @@ -58,7 +58,7 @@ module.exports = { "tomorrow-night": "nos yfory", "morning": "yn y bore", "afternoon": "yn y prynhawn", - "evening": "fin nos", + "evening": "gyda’r hwyr", "night": "dros nos", "today": "heddiw", "tomorrow": "yfory", @@ -89,8 +89,12 @@ module.exports = { return "llai na" + (/^(1|8|11|16)[\D\b]/.test(a) ? "g " : " ") + a; }, "and": function(a, b) { + // don't repeat 'yn y' + if (a.slice(0,5) === "yn y " && b.slice(0,5) === "yn y ") + return a + " a’r " + b.slice(5); // don't repeat 'ar' - if (a.slice(0,9) === "ar ddydd " && b.slice(0,9) === "ar ddydd ") b = b.slice(4); + if (a.slice(0,9) === "ar ddydd " && b.slice(0,9) === "ar ddydd ") + b = b.slice(4); return a // include comma if a list + (a.indexOf(",") !== -1 ? "," : "") @@ -141,4 +145,10 @@ module.exports = { str += "."; return str; }, + "next-hour-forecast-status": "Dydi rhagolygon yr awr nesa $1 oherwydd $2.", + "unavailable": "ddim ar gael", + "temporarily-unavailable": "ddim ar gael ar hyn o bryd", + "partially-unavailable": "ddim yn gyflawn", + "station-offline": "diffyg gwybodaeth o orsafoedd radar gerllaw", + "station-incomplete": "bylchau yn narpariaeth gorsafoedd radar gerllaw", }; diff --git a/lib/lang/en.js b/lib/lang/en.js index 58c5c770..9220f56a 100644 --- a/lib/lang/en.js +++ b/lib/lang/en.js @@ -6,26 +6,49 @@ function join_with_shared_prefix(a, b, joiner) { // HACK: This gets around "today through on Tuesday" or cases like it, which // are incorrect in English. - if(m === "today" || m === "tomorrow") + if(m === "today" || m === "tomorrow") { m = "on " + m; + } - while(i !== m.length && - i !== b.length && - m.charCodeAt(i) === b.charCodeAt(i)) + // Skip the prefix of b that is shared with a. + while( + i !== m.length && + i !== b.length && + m.charCodeAt(i) === b.charCodeAt(i) + ) { ++i; + } - while(i && m.charCodeAt(i - 1) !== 32) + // ...except whitespace! We need that whitespace! + while(i && b.charCodeAt(i - 1) !== 32) { --i; + } return a + joiner + b.slice(i); } function strip_prefix(period) { - return period.slice(0, 9) === "overnight" ? period.slice(4) : - period.slice(0, 7) === "in the " ? period.slice(7) : + return period.startsWith("overnight")? period.slice(4): + period.startsWith("in the ")? period.slice(7): period; } +function capitalize(str) { + // Do not capitalize articles, very short words, or units. + if( + str === "a" || + str === "and" || + str === "cm" || + str === "in" || + str === "of" || + str === "with" + ) { + return str; + } + + return str[0].toUpperCase() + str.slice(1); +} + module.exports = { "clear": "clear", "no-precipitation": "no precipitation", @@ -104,11 +127,7 @@ module.exports = { "centimeters": "$1 cm.", "less-than": "< $1", "and": function(a, b) { - return join_with_shared_prefix( - a, - b, - a.indexOf(",") !== -1 ? ", and " : " and " - ); + return join_with_shared_prefix(a, b, a.includes(",")? ", and ": " and "); }, "through": function(a, b) { return join_with_shared_prefix(a, b, " through "); @@ -116,7 +135,20 @@ module.exports = { "with": "$1, with $2", "range": "$1\u2013$2", "parenthetical": function(a, b) { - return a + " (" + b + (a === "mixed precipitation" ? " of snow)" : ")"); + // In the case of mixed precipitation, we want to clarify that the + // snow accumulation in the parenthetical is snow. In the case that it's + // of an unknown type or rain or sleet, we want to clarify that while snow + // isn't expected, it has a chance of occurring. The below checks do this. + + // HACK: These are not the best ways to determine the precipitation type... + if(!a.endsWith("flurries") && !a.endsWith("snow")) { + if(!a.startsWith("mixed")) { + b = "with a chance of " + b; + } + b += " of snow"; + } + + return a + " (" + b + ")"; }, "for-hour": "$1 for the hour", "starting-in": "$1 starting in $2", @@ -141,28 +173,28 @@ module.exports = { "temperatures-rising": "high temperatures rising to $1 $2", "temperatures-valleying": "high temperatures bottoming out at $1 $2", "temperatures-falling": "high temperatures falling to $1 $2", - // Capitalize the first letter of every word, except if that word is - // "and". (This is a very crude bastardization of proper English titling - // rules, but it is adequate for the purposes of this module.) + // Capitalize the first letter of every word except "and", "or", and units. + // (This is a very crude bastardization of proper English titling rules, but + // it is adequate for the purposes of this module.) "title": function(str) { - return str.replace( - /\b(?:a(?!nd\b)|c(?!m\.)|i(?!n\.)|[^\Waci])/g, - function(letter) { - return letter.toUpperCase(); - } - ); + return str.replace(/\w+/g, capitalize); }, - /* Capitalize the first word of the sentence and end with a period. */ + // Capitalize the first word of the sentence and end with a period. "sentence": function(str) { - /* Capitalize. */ - str = str.charAt(0).toUpperCase() + str.slice(1); + // Capitalize. + str = capitalize(str); - /* Add a period if there isn't already one. */ - if(str.charAt(str.length - 1) !== ".") + // Add a period if there isn't already one. + if(!str.endsWith(".")) { str += "."; + } return str; }, - "unavailable-radar": "Next hour forecasts are temporarily unavailable due to $1.", + "next-hour-forecast-status": "next hour forecasts are $1 due to $2", + "unavailable": "unavailable", + "temporarily-unavailable": "temporarily unavailable", + "partially-unavailable": "partially unavailable", "station-offline": "all nearby radar stations being offline", + "station-incomplete": "gaps in coverage from nearby radar stations", }; diff --git a/lib/lang/fr.js b/lib/lang/fr.js index de345d65..d67638f8 100644 --- a/lib/lang/fr.js +++ b/lib/lang/fr.js @@ -177,4 +177,10 @@ module.exports = { return str; }, + "next-hour-forecast-status": "Les prévisions pour la prochaine heure sont $1 car $2.", + "unavailable": "indisponibles", + "temporarily-unavailable": "temporairement indisponibles", + "partially-unavailable": "partiellement indisponibles", + "station-offline": "les stations radars voisines sont hors-ligne", + "station-incomplete": "il y a des lacunes dans la couverture des stations radars voisines", }; diff --git a/lib/lang/kw.js b/lib/lang/kw.js index 5122c311..cbf7e25c 100644 --- a/lib/lang/kw.js +++ b/lib/lang/kw.js @@ -1,23 +1,23 @@ "use strict"; function in_the(period) { - if(period === "myttin" || period === "dohajydh" || period === "gorthugher" || period === "nos") { + if (period === "myttin" || period === "dohajydh" || period === "gorthugher" || period === "nos") { return " y'n " + period; } - if(period === "an dohajydh ma" || period === "an nos ma") { + if (period === "an dohajydh ma" || period === "an nos ma") { return " y'n " + period.slice(3); } - if("123456789".indexOf(period.charAt(0)) !== -1) { + if ("123456789".indexOf(period.charAt(0)) !== -1) { return " yn " + period; } return " " + period; } function until_the(period) { - if(period === "myttin" || period === "dohajydh" || period === "gorthugher" || period === "nos") { + if (period === "myttin" || period === "dohajydh" || period === "gorthugher" || period === "nos") { return " bys y'n " + period; } - if(period === "an dohajydh ma" || period === "an nos ma") { + if (period === "an dohajydh ma" || period === "an nos ma") { return " bys y'n " + period.slice(3); } return " bys yn " + period; @@ -102,7 +102,7 @@ module.exports = { "less-than": "le ages $1", "and": function(a, b) { let andy = a.indexOf(",") !== -1 ? ", ha" : " ha"; - if(b.charAt(0) === "a" || b.charAt(0) === "e" || b.charAt(0) === "i" || b.charAt(0) === "o" || b.charAt(0) === "u") { + if (b.charAt(0) === "a" || b.charAt(0) === "e" || b.charAt(0) === "i" || b.charAt(0) === "o" || b.charAt(0) === "u") { andy = andy + "g"; } @@ -144,7 +144,6 @@ module.exports = { }, "during": function(condition, period) { return condition + in_the(period); - // "$1 y\'n $2" }, "for-week": "$1 dres oll an seythun", "over-weekend": "$1 dres an bennseythun", @@ -169,9 +168,15 @@ module.exports = { str = str.charAt(0).toUpperCase() + str.slice(1); /* Add a period if there isn't already one. */ - if(str.charAt(str.length - 1) !== ".") + if (str.charAt(str.length - 1) !== ".") str += "."; return str; }, + "next-hour-forecast-status": "Darganow herwydh an our yw $1 drefen bos $2.", + "unavailable": "ankavadow", + "temporarily-unavailable": "ankavadow dres pols", + "partially-unavailable": "ankavadow yn rann", + "station-offline": "pub gorsav radar y'n ranndir dhywarlinen", + "station-incomplete": "aswaow y'n gorherans dhyworth gorsavow radar y'n ranndir", }; diff --git a/lib/lang/no.js b/lib/lang/no.js index 2596fb5a..c8ebcc58 100644 --- a/lib/lang/no.js +++ b/lib/lang/no.js @@ -152,4 +152,10 @@ module.exports = { return str; }, + "next-hour-forecast-status": "Værvarsel for neste time er $1 på grunn av $2.", + "unavailable": "ikke tilgjengelig", + "temporarily-unavailable": "midertidlig ikke tilgjengelig", + "partially-unavailable": "delvis ikke tilgjengelig", + "station-offline": "ingen kontakt med radarstasjoner i nærheten", + "station-incomplete": "hull i dekningen fra radarstasjoner i nærheten", }; diff --git a/lib/lang/sk.js b/lib/lang/sk.js index c971eac1..f7e7ab73 100644 --- a/lib/lang/sk.js +++ b/lib/lang/sk.js @@ -236,4 +236,10 @@ module.exports = { return str; }, + "next-hour-forecast-status": "Predpoveď na ďalšiu hodinu je $1, pretože $2.", + "unavailable": "nedostupná", + "temporarily-unavailable": "dočasne nedostupná", + "partially-unavailable": "čiastočne nedostupná", + "station-offline": "všetky radarové stanice v okolí sú v režime offline", + "station-incomplete": "vznikli medzery v pokrytí radarovými stanicami v okolí", }; diff --git a/lib/lang/x-pig-latin.js b/lib/lang/x-pig-latin.js index 88e095a2..43cbb12b 100644 --- a/lib/lang/x-pig-latin.js +++ b/lib/lang/x-pig-latin.js @@ -168,4 +168,10 @@ module.exports = { return str; }, + "next-hour-forecast-status": "extnay hourway orecastsfay areway $1 ueday otay $2.", + "unavailable": "unavailableway", + "temporarily-unavailable": "emporarilytay unavailableway", + "partially-unavailable": "artiallypay unavailableway", + "station-offline": "allway earbynay adarray tationssay eingbay offlineway", + "station-incomplete": "apsgay inway overagecay romfay earbynay adarray ationsstay", }; diff --git a/package.json b/package.json index 0660f966..3e0c5640 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "translations", - "version": "2.15.1", + "version": "3.0.5", "description": "translate the Dark Sky API into any language", "author": { "name": "The Dark Sky Company", @@ -268,6 +268,10 @@ { "name": "Martin Macko", "web": "https://github.com/LinkedList" + }, + { + "name": "Chris Mitchell", + "web": "https://geidh.uk/" } ], "repository": { diff --git a/test_cases/bg.json b/test_cases/bg.json index 96a26f8d..ef66e31f 100644 --- a/test_cases/bg.json +++ b/test_cases/bg.json @@ -266,6 +266,8 @@ "Силен Дъжд и Гръмотевична Буря": ["title", ["and", "heavy-rain", "thunderstorm"]], - "Прогнозата за идния час временно не е на разположение поради липса на информация от всички близки станции.": - ["sentence",["unavailable-radar", "station-offline"]] + "Прогнозата за идния час временно не е на разположение поради това че всички близки станции не са на линия.": + ["sentence",["next-hour-forecast-status", "temporarily-unavailable", "station-offline"]], + "Прогнозата за идния час е частична поради пропуски в покритието от близки станции.": + ["sentence",["next-hour-forecast-status", "partially-unavailable", "station-incomplete"]] } diff --git a/test_cases/cy.json b/test_cases/cy.json index b14dcc84..f7bcff46 100644 --- a/test_cases/cy.json +++ b/test_cases/cy.json @@ -57,13 +57,13 @@ "medium-snow", ["and", "later-today-evening", "tomorrow-morning"]]], - "Glaw trwm hyd at hwyrach bore yma, gan gychwyn eto fin nos heno.": + "Glaw trwm hyd at hwyrach bore yma, gan gychwyn eto gyda’r hwyr heno.": ["sentence", ["until-starting-again", "heavy-rain", "later-today-morning", "today-evening"]], - "Cymylau trwchus yn cychwyn fin nos, gan barhau hyd at y nos.": + "Cymylau trwchus yn cychwyn gyda’r hwyr, gan barhau hyd at y nos.": ["sentence", ["starting-continuing-until", "heavy-clouds", "evening", @@ -158,5 +158,18 @@ ["through", "friday", "saturday"]], ["temperatures-peaking", ["fahrenheit", 100], - "monday"]]] + "monday"]]], + + "Glaw ysgafn yn bosib yn y bore a’r prynhawn.": + ["sentence", ["during", + "possible-light-rain", ["and", + "morning", "afternoon"]]], + + "Dydi rhagolygon yr awr nesa ddim ar gael ar hyn o bryd oherwydd diffyg gwybodaeth o orsafoedd radar gerllaw.": + ["sentence",["next-hour-forecast-status", "temporarily-unavailable", "station-offline"]], + "Dydi rhagolygon yr awr nesa ddim yn gyflawn oherwydd bylchau yn narpariaeth gorsafoedd radar gerllaw.": + ["sentence",["next-hour-forecast-status", "partially-unavailable", "station-incomplete"]], + "Dydi rhagolygon yr awr nesa ddim ar gael oherwydd diffyg gwybodaeth o orsafoedd radar gerllaw.": + ["sentence",["next-hour-forecast-status", "unavailable", "station-offline"]] + } diff --git a/test_cases/en.json b/test_cases/en.json index 7dfa2d94..88474a0e 100644 --- a/test_cases/en.json +++ b/test_cases/en.json @@ -249,6 +249,9 @@ "Heavy Snow (3\u20135 cm.)": ["title", ["parenthetical", "heavy-snow", ["centimeters", ["range", 3, 5]]]], + "Rain (with a Chance of 2\u20134 in. of Snow)": + ["title", ["parenthetical", "medium-rain", ["inches", ["range", 2, 4]]]], + "Possible Thunderstorms": ["title", "possible-thunderstorm"], @@ -260,5 +263,11 @@ ["starting-in", "very-light-rain", ["less-than", ["minutes", 1]]]], "Next hour forecasts are temporarily unavailable due to all nearby radar stations being offline.": - ["sentence",["unavailable-radar", "station-offline"]] + ["sentence", ["next-hour-forecast-status", "temporarily-unavailable", "station-offline"]], + + "Next hour forecasts are partially unavailable due to gaps in coverage from nearby radar stations.": + ["sentence", ["next-hour-forecast-status", "partially-unavailable", "station-incomplete"]], + + "Next hour forecasts are unavailable due to all nearby radar stations being offline.": + ["sentence", ["next-hour-forecast-status", "unavailable", "station-offline"]] } diff --git a/test_cases/fr.json b/test_cases/fr.json index 2e3a32a7..7a862103 100644 --- a/test_cases/fr.json +++ b/test_cases/fr.json @@ -242,5 +242,15 @@ ["sentence", ["during", "possible-thunderstorm", ["and", "next-wednesday", "next-thursday"] - ]] + ]], + + "Les prévisions pour la prochaine heure sont temporairement indisponibles car les stations radars voisines sont hors-ligne.": + ["sentence",["next-hour-forecast-status", "temporarily-unavailable", "station-offline"]], + + "Les prévisions pour la prochaine heure sont partiellement indisponibles car il y a des lacunes dans la couverture des stations radars voisines.": + ["sentence",["next-hour-forecast-status", "partially-unavailable", "station-incomplete"]], + + "Les prévisions pour la prochaine heure sont indisponibles car les stations radars voisines sont hors-ligne.": + ["sentence",["next-hour-forecast-status", "unavailable", "station-offline"]] + } diff --git a/test_cases/kw.json b/test_cases/kw.json index ef4b8fc6..49682e1f 100644 --- a/test_cases/kw.json +++ b/test_cases/kw.json @@ -257,5 +257,12 @@ "Glaw pur skav ow talleth le ages 1 myn.": ["sentence", - ["starting-in", "very-light-rain", ["less-than", ["minutes", 1]]]] + ["starting-in", "very-light-rain", ["less-than", ["minutes", 1]]]], + + "Darganow herwydh an our yw ankavadow dres pols drefen bos pub gorsav radar y'n ranndir dhywarlinen.": + ["sentence",["next-hour-forecast-status", "temporarily-unavailable", "station-offline"]], + "Darganow herwydh an our yw ankavadow yn rann drefen bos aswaow y'n gorherans dhyworth gorsavow radar y'n ranndir.": + ["sentence",["next-hour-forecast-status", "partially-unavailable", "station-incomplete"]], + "Darganow herwydh an our yw ankavadow drefen bos pub gorsav radar y'n ranndir dhywarlinen.": + ["sentence",["next-hour-forecast-status", "unavailable", "station-offline"]] } diff --git a/test_cases/no.json b/test_cases/no.json index a1bd6088..00eff195 100644 --- a/test_cases/no.json +++ b/test_cases/no.json @@ -246,5 +246,12 @@ ["title", "possible-thunderstorm"], "Kraftige regnbyger og tordenvær": - ["title", ["and", "heavy-rain", "thunderstorm"]] + ["title", ["and", "heavy-rain", "thunderstorm"]], + + "Værvarsel for neste time er midertidlig ikke tilgjengelig på grunn av ingen kontakt med radarstasjoner i nærheten.": + ["sentence",["next-hour-forecast-status", "temporarily-unavailable", "station-offline"]], + "Værvarsel for neste time er delvis ikke tilgjengelig på grunn av hull i dekningen fra radarstasjoner i nærheten.": + ["sentence",["next-hour-forecast-status", "partially-unavailable", "station-incomplete"]], + "Værvarsel for neste time er ikke tilgjengelig på grunn av ingen kontakt med radarstasjoner i nærheten.": + ["sentence",["next-hour-forecast-status", "unavailable", "station-offline"]] } diff --git a/test_cases/sk.json b/test_cases/sk.json index b20c45b1..8a2d3be2 100644 --- a/test_cases/sk.json +++ b/test_cases/sk.json @@ -263,5 +263,12 @@ ["title", ["and", "heavy-rain", "thunderstorm"]], "Búrky až do budúceho pondelka.": - ["sentence", ["until", "thunderstorm", "next-monday"]] + ["sentence", ["until", "thunderstorm", "next-monday"]], + + "Predpoveď na ďalšiu hodinu je dočasne nedostupná, pretože všetky radarové stanice v okolí sú v režime offline.": + ["sentence",["next-hour-forecast-status", "temporarily-unavailable", "station-offline"]], + "Predpoveď na ďalšiu hodinu je čiastočne nedostupná, pretože vznikli medzery v pokrytí radarovými stanicami v okolí.": + ["sentence",["next-hour-forecast-status", "partially-unavailable", "station-incomplete"]], + "Predpoveď na ďalšiu hodinu je nedostupná, pretože všetky radarové stanice v okolí sú v režime offline.": + ["sentence",["next-hour-forecast-status", "unavailable", "station-offline"]] } diff --git a/test_cases/x-pig-latin.json b/test_cases/x-pig-latin.json index 45d03402..9558b330 100644 --- a/test_cases/x-pig-latin.json +++ b/test_cases/x-pig-latin.json @@ -242,5 +242,12 @@ ["title", "possible-thunderstorm"], "Eavyhay Ainray andway Understormsthay": - ["title", ["and", "heavy-rain", "thunderstorm"]] + ["title", ["and", "heavy-rain", "thunderstorm"]], + + "Extnay hourway orecastsfay areway emporarilytay unavailableway ueday otay allway earbynay adarray tationssay eingbay offlineway.": + ["sentence",["next-hour-forecast-status", "temporarily-unavailable", "station-offline"]], + "Extnay hourway orecastsfay areway artiallypay unavailableway ueday otay apsgay inway overagecay romfay earbynay adarray ationsstay.": + ["sentence",["next-hour-forecast-status", "partially-unavailable", "station-incomplete"]], + "Extnay hourway orecastsfay areway unavailableway ueday otay allway earbynay adarray tationssay eingbay offlineway.": + ["sentence",["next-hour-forecast-status", "unavailable", "station-offline"]] }