PageSourceSearch

https://weather.metoffice.gov.uk/public/adhoc/mo-adhoc-gsc.js

js metoffice.gov.uk collected 2026-09-24 07:14:15 UTC 6,424 bytes, 152 lines download raw bytes

1"use strict";
2
3window.metoffice.getSiteControl_widgetSelect = function(config) {
4    const ONE_YEAR_MILLIS = 3.154e+10;
5    const getCookie = function(name) {
6        const value = `; ${document.cookie}`;
7        const parts = value.split(`; ${name}=`);
8        return (parts.length === 2) ? parts.pop().split(';').shift() : null;
9    };
10    let gscStateJson = getCookie("mo-gsc-state");
11    let gscState = {};
12    if (gscStateJson != null) {
13        gscState = JSON.parse(decodeURIComponent(gscStateJson));
14    }
15
16    // Populate state with new items that may not yet exist...
17    let configItemIDs = new Set();
18    let newConfigItemIDs = new Set();
19    config.forEach((itm) => {
20        if (gscState[itm.id] == undefined) {
21            gscState[itm.id] = {
22                rnd: Math.floor(Math.random() * 10000) / 100
23            }
24            newConfigItemIDs.add(itm.id);
25        }
26        configItemIDs.add(itm.id);
27    });
28
29    // For new items, If previous cookies exist, include them
30    newConfigItemIDs.forEach(function(key) {
31        if (document.cookie.includes(`mo-getsitecontrol-${key}=true;`)) {
32            gscState[key].rnd = 0;
33            gscState[key].migrated=true;
34
35        } else if (document.cookie.includes(`mo-getsitecontrol-${key}=false;`)) {
36            gscState[key].rnd = 100;
37            gscState[key].migrated=true;
38        }
39    });
40
41    // Remove those that no longer exist.
42    Object.keys(gscState).forEach(function(key) {
43        if (!configItemIDs.has(key)) {
44            delete gscState[key];
45        }
46    });
47
48    document.cookie = 'mo-gsc-widget=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
49
50    // Build list of get site control widgets that are applicable to be shown on this page..
51    let percentageOfUsersCheck = (itm) => itm.percentageOfUsers > gscState[itm.id].rnd;
52
53    let pathIncludesCheck = (itm) => itm.pathIncludes == null ? false :
54        Array.isArray(itm.pathIncludes) ?
55            itm.pathIncludes.find((pathIncludes) => window.location.pathname.match('^' + pathIncludes.replace('*', '.*') + '$')) != undefined :
56            window.location.pathname.match('^' + itm.pathIncludes.replace('*', '.*') + '$');
57
58    let pathExcludesCheck = (itm) => itm.pathExcludes == null ? true :
59        Array.isArray(itm.pathExcludes) ?
60            itm.pathExcludes.find((pathExcludes) => window.location.pathname.match('^' + pathExcludes.replace('*', '.*') + '$')) == undefined :
61            !window.location.pathname.match('^' + itm.pathExcludes.replace('*', '.*') + '$');
62
63    let hostCheck = (itm) => itm.host == null ? true :
64        Array.isArray(itm.host) ?
65            itm.host.find((host) => window.location.hostname.match('^' + host.replace('*', '.*') + '$')) != undefined :
66            window.location.hostname.match('^' + itm.host.replace('*', '.*') + '$');
67
68    let conditionCheck = (itm) =>
69        !((typeof itm.condition == 'boolean' && itm.condition === false) ||
70            (typeof itm.condition == 'function' && itm.condition() === false));
71
72    let getSiteControlItems = [];
73    config.forEach((itm) => {
74        let applicable =
75            pathIncludesCheck(itm) &&
76            pathExcludesCheck(itm) &&
77            hostCheck(itm) &&
78            conditionCheck(itm);
79
80        if (!applicable) {
81            return;
82        }
83
84        // if NOT included in the percentage of users, return
85        // but remove firstShown incase percentages were lowered temporarily,
86        // and when raised again in future, want to re-show the popup, without it have becomming timed out.
87        if (!percentageOfUsersCheck(itm)) {
88            delete gscState[itm.id].firstShown;
89            return;
90        };
91
92
93        // If widget has already been showing for more than 2 weeks (or item.timeOut), dont add.
94        if (gscState[itm.id].firstShown != undefined) {
95            let firstShownTime = new Date(gscState[itm.id].firstShown);
96            let diffDays = Math.floor((new Date() - firstShownTime) / (1000 * 60 * 60 * 24));
97            let timeOutDays = (itm.timeOut == null) ? 14 : itm.timeOut;
98            let redisplayAfterDays = (itm.redisplayAfter == null) ? 28 : itm.redisplayAfter;
99
100            if (diffDays >= timeOutDays && diffDays < redisplayAfterDays) {
101                return;
102            } else {
103                itm.firstShown = gscState[itm.id].firstShown;
104            }
105        }
106
107        if (itm.priority == null) itm.priority = 3; // default priority of 3
108        if (gscState[itm.id].migrated) itm.migrated = true;
109        getSiteControlItems.push(itm);
110    });
111
112    // Sort by priority. Items which have a firstShownTime will be higher priority.
113    getSiteControlItems.sort((a, b) => {
114            if (a.firstShown != null && b.firstShown != null) return new Date(a.firstShown) - new Date(b.firstShown);
115            else if (a.firstShown != null) return -1;
116            else if (b.firstShown != null) return 1;
117            else if (a.migrated && b.migrated) return 0;
118            else if (a.migrated) return -1;
119            else if (b.migrated) return 1;
120
121
122            else return a.priority - b.priority;
123        }
124    );
125
126    // Set cookie mo-gsc-widget to indicate what widget to show.
127    // getSiteControl should use this to condition showing a survey.
128    if (getSiteControlItems.length > 0) {
129        const widget = getSiteControlItems[0];
130        document.cookie = `mo-gsc-widget=${widget.id}; path=/;`;
131        const now = new Date().toISOString();
132        if (typeof gscState[widget.id].firstShown == 'undefined') {
133            // First time showing the widget
134            gscState[widget.id].firstShown = now;
135        } else {
136            // Widget was shown before
137            const redisplayAfterDays = (widget.redisplayAfter == null) ? 28 : widget.redisplayAfter;
138            const lastShownTime = new Date(gscState[widget.id].firstShown);
139            const diffDays = Math.floor((new Date() - lastShownTime) / (1000 * 60 * 60 * 24));
140            if (diffDays >= redisplayAfterDays) {
141                // Enough time has passed since the last show
142                gscState[widget.id].firstShown = now;
143            }
144        }
145    }
146
147    // set the cookie.
148    let expiresDate = new Date();
149    expiresDate.setTime(expiresDate.getTime() + ONE_YEAR_MILLIS);
150    gscStateJson = encodeURIComponent(JSON.stringify(gscState));
151    document.cookie = `mo-gsc-state=${gscStateJson}; expires=${expiresDate.toUTCString()}; path=/;`
152}

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