PageSourceSearch

https://fploptimized.com/static/js/sampling_utils.js?ts=20260920183004

js fploptimized.com collected 2026-10-04 13:32:09 UTC 10,348 bytes, 285 lines download raw bytes

1let compactFormatter = Intl.NumberFormat('en', { notation: 'compact' });
2
3function sample_compact_number(value) {
4    switch (value) {
5        case "Overall":
6            return "Overall";
7        case "100":
8            return "Top 100";
9        case "1000":
10            return "Top 1K";
11        case "10000":
12            return "Top 10K";
13        case "100000":
14            return "Top 100K";
15        case "1000000":
16            return "Top 1M";
17        case "Prime":
18            return "Prime";
19        default:
20            return value;
21            // let new_value = compactFormatter.format(value);
22            // return new_value !== "NaN" ? ("Top " + new_value) : value;
23    }
24}
25
26function reverse_sample_name(value) {
27    switch (value) {
28        case "Sample - Overall":
29            return "Overall";
30        case "FPL Data":
31            return "Official FPL API"
32        case "Sample - Top 100":
33        case "Top 100":
34            return 100;
35        case "Sample - Top 1K":
36        case "Top 1K":
37            return 1000;
38        case "Sample - Top 10K":
39        case "Top 10K":
40            return 10000;
41        case "Sample - Top 100K":
42        case "Top 100K":
43            return 100000;
44        case "Sample - Top 1M":
45        case "Top 1M":
46            return 1000000;
47        case "Sample - Prime":
48        case "Prime":
49            return "Prime";
50        default:
51            return value.includes("Sample - ") ? value.replace("Sample - ", "") : value;
52    }
53}
54
55function autosubbed_team(team_picks, autosub_dict) {
56
57    let sub_replacements = []
58    let cap_replacements = []
59    let split_team = _.groupBy(team_picks, (i) => i.multiplier > 0)
60    let lineup = split_team[true]
61    let bench = split_team[false] || []
62    for (let i of lineup) {
63        let id = i.element;
64        let info = autosub_dict[id];
65        if (info === undefined) {
66            continue;
67        }
68        if (info.autosub) {
69            let original_mult = i.multiplier;
70            i.multiplier = 0;
71            if (i.is_captain) {
72                i.is_captain = false;
73                let vc = lineup.find(j => j.is_vice_captain && autosub_dict[j.element].autosub == false);
74                if (vc && vc.multiplier > 0) {
75                    vc.is_captain = true;
76                    vc.is_vice_captain = false;
77                    if (vc.multiplier <= 1) {
78                        vc.multiplier = original_mult;
79                    }
80                    cap_replacements.push([id, vc.element])
81                }
82            }
83            let target_pos = info.element_type;
84            let current_cnt = team_picks.filter(j => j.multiplier > 0 && (autosub_dict[j.element] && autosub_dict[j.element].element_type == target_pos)).length;
85            if (element_type[target_pos].min > current_cnt || target_pos == "1") {
86                // only this type
87                let player_to_enter = bench.find(j => autosub_dict[j.element] && autosub_dict[j.element].element_type == target_pos && autosub_dict[j.element].autosub == false)
88                if (player_to_enter) {
89                    player_to_enter.multiplier = 1;
90                    bench = bench.filter(i => i.element != player_to_enter.element)
91                    sub_replacements.push([id, player_to_enter.element])
92                }
93            } else {
94                // anyone on bench
95                let player_to_enter = bench.find(j => autosub_dict[j.element] && autosub_dict[j.element].element_type != "1" && autosub_dict[j.element].autosub == false)
96                if (player_to_enter) {
97                    player_to_enter.multiplier = 1;
98                    bench = bench.filter(i => i.element != player_to_enter.element)
99                    sub_replacements.push([id, player_to_enter.element])
100                }
101            }
102        }
103    }
104    return { 'team': team_picks, 'sub_replacement': sub_replacements, 'cap_replacement': cap_replacements };
105}
106
107function prepare_fixture_data(data) {
108
109    data.forEach((game, index) => {
110        game.start_dt = new Date(game.kickoff_time);
111        game.end_dt = new Date(game.start_dt.getTime() + (105 * 60 * 1000));
112        game.node_info = { start: (game.start_dt).getTime(), end: game.end_dt.getTime(), content: 'Game' }
113    })
114
115    data.sort((a, b) => { return a.node_info.start - b.node_info.start });
116
117    data.forEach((game, index) => {
118        game.duration = 105 * 60 * 1000;
119        game.team_h_name = teams_ordered[game.team_h - 1].name;
120        game.team_a_name = teams_ordered[game.team_a - 1].name;
121        game.label = teams_ordered[game.team_h - 1].name + " vs " + teams_ordered[game.team_a - 1].name;
122        let order = 0;
123        data.slice(0, index).forEach((game2) => {
124            if ((game.start_dt >= game2.start_dt && game.start_dt <= game2.end_dt) ||
125                (game.end_dt >= game2.start_dt && game.end_dt <= game2.end_dt)) {
126                if (game2.order == order) {
127                    order += 1;
128                }
129            }
130        })
131        game.order = order;
132    })
133
134    return data;
135}
136
137
138function get_provisional_bonus(gw_fixture) {
139    let bonus_players = {};
140
141    gw_fixture.forEach((game) => {
142        let bps_provisional = {};
143
144        if (needsProvisionalBonus(game)) {
145            try {
146                let bps_stats = game.stats.find(i => i.identifier == "bps")
147                let all_players = bps_stats.h.concat(bps_stats.a)
148                let sorted_groups = Object.entries(_.groupBy(all_players, i => i.value)).sort((a, b) => b[0] - a[0]).slice(0, 3)
149                sorted_groups.forEach((cat, i) => {
150                    let bonus = 3 - i;
151                    cat[1].forEach((p) => {
152                        bonus_players[p.element] = bonus;
153                    });
154                })
155            } catch (err) {}
156        }
157    })
158
159    return bonus_players;
160}
161
162function rp_by_id_dict(fixture, rp_data) {
163    rp_data.forEach((p) => {
164        try {
165            p.games_finished = p.explain.map(i => {
166                let f = fixture.find(j => j.id == i.fixture)
167                if (f == undefined) { return true }
168                return f.finished_provisional
169            }).every(i => i);
170            if (p.games_finished && p.stats.minutes == 0) {
171                p.autosub = true;
172            } else {
173                p.autosub = false;
174            }
175        } catch (e) {
176            console.log("Player game_finished error", e)
177        }
178    })
179    let rp_obj = Object.fromEntries(_.cloneDeep(rp_data.map(i => [i.id, i])));
180    if (!_.isEmpty(this.provisional_bonus) && !_.isEmpty(rp_obj)) {
181        Object.entries(this.provisional_bonus).forEach(entry => {
182            const [key, value] = entry;
183            rp_obj[key].stats.total_points += value;
184        })
185    }
186    return rp_obj;
187}
188
189function generate_autosub_dict(el_data, rp_by_id) {
190    let autosubs = [];
191    el_data.forEach((e) => {
192        autosubs.push([e.id, { element_type: e.element_type, autosub: rp_by_id[e.id] ? rp_by_id[e.id].autosub : false }]);
193    })
194    let autosub_dict = Object.fromEntries(autosubs);
195    return autosub_dict;
196}
197
198function get_ownership_by_type(ownership_source, fpl_data, sample_data, autosubs) {
199
200    let teams = [];
201    if (sample_data == undefined) {
202        ownership_source = "Official FPL API";
203    } else if (Object.keys(sample_data).length == 0) {
204        ownership_source = "Official FPL API";
205    }
206
207    let tag = reverse_sample_name(ownership_source)
208    if (tag == "Official FPL API") {
209        return {data: fpl_data}
210    }
211    
212    if (tag in sample_data) {
213        teams = sample_data[tag].filter(i => i.team != undefined)
214    }
215    else {
216        teams = sample_data['Overall'].filter(i => i.team != undefined)
217    }
218    
219
220    let el_copy = _.cloneDeep(fpl_data);
221    let sub_replacements = [];
222    let cap_replacements = [];
223
224    teams = teams.filter(i => i.data != null)
225
226    if (!_.isEmpty(autosubs)) {
227        teams = _.cloneDeep(teams);
228        teams.forEach((team) => {
229            let edits = autosubbed_team(team.data.picks, autosubs);
230            team.data.picks = edits.team;
231            sub_replacements = sub_replacements.concat(edits.sub_replacement)
232            cap_replacements = cap_replacements.concat(edits.cap_replacement)
233        })
234    }
235
236    let all_players = teams.map(i => i.data.picks).flat();
237    let grouped_players = _.groupBy(all_players, (i) => i.element);
238
239    el_copy.forEach((e) => {
240        // let this_player_picks = all_players.filter(i => i.element == e.id);
241        let this_player_picks = grouped_players[e.id];
242        if (this_player_picks !== undefined) {
243            let cnt = this_player_picks.length;
244            e.selected_by_percent = cnt / teams.length * 100;
245            let sum_of_multiplier = getSum(this_player_picks.map(i => i.multiplier));
246            e.effective_ownership = sum_of_multiplier / teams.length * 100;
247            let captain_count = this_player_picks.filter(i => i.multiplier > 1.5).length;
248            e.captain_percentage = captain_count / teams.length * 100;
249        } else {
250            e.selected_by_percent = 0;
251            e.effective_ownership = 0;
252            e.captain_percentage = 0;
253        }
254
255    });
256    return { data: el_copy, sub_replacement: sub_replacements, cap_replacement: cap_replacements };
257}
258
259async function get_latest_sample_data(season, gw) {
260    return new Promise((resolve, reject) => {
261        get_sample_data(season, gw.slice(2)).then(data => {
262            if (data[0].status == 'rejected') {
263                get_sample_data(season, parseInt(gw.slice(2))-1).then((data) => {
264                    if (data[0].status == 'rejected') {
265                        reject("no data")
266                    }
267                    else {
268                        let sample_data = data[0].value
269                        if (data[1].status != 'rejected') {
270                            sample_data['Prime'] = data[1].value
271                        }
272                        resolve({gw: parseInt(gw.slice(2))-1, data: sample_data})
273                    }
274                })
275            }
276            else {
277                let sample_data = data[0].value
278                if (data[1].status != 'rejected') {
279                    sample_data['Prime'] = data[1].value
280                }
281                resolve({gw: gw.slice(2), data: sample_data})
282            }
283        })
284    })
285}

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.