{"version":3,"file":"js/scripts_react_shared_api_fetching_js-scripts_react_shared_utils_js.js?_t=c704921be72f935db5b3","mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAGA;AAGA;AAKA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AAGA;AAAA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AAKA;AAIA;AACA;AAEA;AACA;AACA;AAyBA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AAIA;AAEA;AACA;AACA;AAAA;AAEA;AAAA;AAGA;AACA;AAYA;AACA;AACA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AAkBA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAWA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChQA;AAEA;AAOA;AAEA;AACA;AAIA;AAGA;AACA;AAEA;AACA;AAEA;AACA;AAAA;AAGA;AACA;AACA;AACA;AAAA;AACA;AAGA;AAAA;AAEA;AAAA;AAAA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAAA;AAGA;AACA;AAEA;AAIA;AACA;AAEA;AACA;AAEA;AACA;AAAA;AAGA;AACA;AAEA;AAAA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AAEA;AAKA;AACA;AACA;AACA;AAAA;AACA;AACA;AAGA;AAAA;AAEA;AACA;AAAA;AAEA;AAAA;AACA;AACA;AACA;AAGA;AAAA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AAKA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAEA;AAIA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AAKA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AAEA;AACA;AAEA;AAEA;AACA;AAAA;AAGA;AACA;AAAA;AAGA;AACA;AAEA;AAEA;AAIA;AAAA;AACA;AACA;AAGA;AAAA;AAEA;AAAA;AACA;AAGA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AAEA;AAGA;AACA;AAAA;AAEA;AACA;AAIA;AAEA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AAEA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAAA;AAGA;AAKA;AAAA;AAGA;AAIA;AAAA;AAGA;AACA;AACA;AACA;AACA;AAIA;AAAA;AACA;AACA;AACA;AAGA;AAAA;AAEA;AAAA;AACA;AAEA;AAIA;AAAA;AACA;AACA;AAGA;AAAA;AAEA;AAAA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAGA;AACA;AAEA;AAKA;AACA;AAEA;AAAA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AAEA;AAAA;AACA;AAGA;AAKA;AAKA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAKA;AACA;AAEA;AAAA;AACA;AAEA;AAAA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AAEA;AAAA;AACA;AAGA;AAKA;AAKA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAAA;AAGA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AAAA;AAEA;AAAA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AAMA;AAAA;AAGA;AAGA;AACA;AAAA;AAEA;AACA;AAGA;AAAA;AAIA;AAGA;AAEA;AAUA;AAAA;AACA;AACA;AAEA;AACA;AAIA;AAGA;AAEA;AAKA;AAAA;AACA;AACA;AAEA;AACA;AAIA;AAGA;AAEA;AAKA;AAAA;AACA;AACA;AAEA;AACA;AAIA;AAAA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAAA;AAEA;AAAA;AACA;AAGA;AACA;AACA;AAAA;AAEA;AAAA;AACA;AAGA;AACA;AACA;AAAA;AAEA;AAAA;AACA;AAGA;AACA;AACA;AAAA;AAEA;AAAA;AACA;AAGA;AACA;AACA;AAAA;AAEA;AAAA;AACA;AAGA;AAIA;AACA;AAAA;AAEA;AAAA;AACA;AAGA;AACA;AACA;AAAA;AACA;AAEA;AACA;AAAA;AACA;AAEA;AAAA;AAGA;AACA;AACA;AACA;AAAA;AAEA;AAAA;AACA;AAGA;AAAA;AAGA;AACA;AACA;AACA;AAAA;AAEA;AAAA;AACA;AAGA;AAAA;AAGA;AACA;AACA;AACA;AAAA;AAEA;AAAA;AACA;AAGA;AACA;AACA;AAAA;AAEA;AAAA;AACA;AAGA;AACA;AACA;AAAA;AAEA;AAAA;AACA;AAGA;AAAA;AAGA;AAAA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AACA;AAAA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AAEA;AAAA;AACA;AACA;AAEA;AAAA;AAEA;AAAA;AACA;AACA;AAEA;AAAA;AAEA;AAAA;AACA;AACA;AAEA;AAAA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AAEA;AAGA;AACA;AAEA;AAGA;AACA;AAEA;AAGA;AACA;AAAA;AAGA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAKA;AACA;AAAA;AAGA;AACA;AAEA;AAIA;AAGA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAGA;AACA;AAAA;AAGA;AACA;AAAA;AAGA;AACA;AAAA;AAGA;AACA;AAAA;AAGA;AACA;AAAA;AAGA;AACA;AAEA;AAAA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AAAA;AAEA;AAAA;AAEA;AACA;AAAA;AAEA;AAAA;AAEA;AACA;AAAA;AAEA;AAAA;AAEA;AACA;AAAA;AAEA;AAAA;AAEA;AACA;AAAA;AAEA;AAAA;AAEA;AACA;AAAA;AAEA;AAAA;AAEA;AACA;AAAA;AAEA;AAAA;AAEA;AACA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAEA;AACA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AAGA;AACA;AAGA;AAIA;AAEA;AAGA;AAGA;AAEA;AACA;AAAA;AAGA;AAEA;AAAA;AAGA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AAAA;AACA;AAEA;AAAA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAIA;AAOA;AACA;AACA;AACA;AAEA;AAAA;AAKA;AAKA;AAKA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AAAA;AAEA;AAEA;AAAA;AAEA;AAEA;AAAA;AAGA;AAGA;AACA;AACA;AAEA;AAKA;AAKA;AAAA;AACA;AAGA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AAMA;AAEA;AACA;AACA;AAAA;AAGA;AAEA;AACA;AAGA;AACA;AAIA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AAAA;AAEA;AAGA;AACA;AAEA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAGA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AAEA;AACA;AACA;AAGA;AACA;AAAA;AAGA;AACA;;;;;;;;;;;;;;;;;;AChjDA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AAAA;AACA;AAEA;AAAA;AAEA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AAAA;AACA;AAEA;AAAA;AAEA;AAEA;AAAA;AACA;AACA;AAEA;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5DA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AACA;AACA;AAGA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AAAA;AAGA;AAGA;AAGA;AAGA;AAIA;AAEA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AAQA;AAEA;AAEA;AACA;AAEA;AAYA;AAEA;AACA;AACA;AAAA;AAGA;AAGA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AAEA;AACA;AAAA;AAGA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AAMA;AAEA;AACA;AAKA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAIA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AAAA;AACA;AACA;AACA;AAGA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AAAA;AAGA;AACA;AAAA;AAGA;AACA;AAAA;AAGA;AAAA;AACA;AAGA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAAA;AAEA;AACA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AAAA;AACA;AACA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AAIA;AAEA;AACA;AACA;AAAA;AAGA;AAMA;AAEA;AACA;AACA;AAAA;AAGA;AAGA;AAEA;AACA;AACA;AAAA;AAGA;AAGA;AAEA;AACA;AACA;AAAA;AAGA;AAMA;AAEA;AACA;AACA;AAAA;AAGA;AAIA;AAEA;AACA;AACA;AAAA;AAGA;AAIA;AAEA;AACA;AACA;AAAA;AAGA;AAIA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AASA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AAIA;AAEA;AACA;AACA;AAAA;AAGA;AAIA;AAEA;AACA;AACA;AAAA;AAGA;AAIA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AAIA;AAEA;AACA;AACA;AAAA;AAGA;AAIA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AAIA;AAGA;AACA;AACA;AAAA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AAMA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AAEA;AACA;AAAA;AAEA;AAAA;AAGA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAGA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AACA;AAGA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAMA;AAGA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAGA;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;ACt4BA;AAEA;AACA;AAEA;AACA;AACA;AACA;AAAA;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACXA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAEA;AAAA;AACA;AAEA;AAEA;AAAA;AAEA;AAEA;AAAA;AACA;AACA;AAEA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AAEA;AAEA;AAAA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AAAA;AAEA;AACA;AAEA;AAAA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AAEA;AACA;AACA;AAAA;AACA;AAEA;AAEA;AAKA;AACA;AAAA;AAGA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AAEA;AAEA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AAGA;AAEA;AACA;AACA;AAAA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AAGA;AAEA;AACA;AACA;AAAA;AAGA;AAEA;AAAA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAAA;AAGA;AACA;AAEA;AACA;AAIA;AAEA;AAAA;AAEA;AAAA;AAEA;AAEA;AACA;AACA;AAAA;AACA;AACA;AACA;AAGA;AAEA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AAEA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AAEA;AAAA;AACA;AAEA;AAEA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AAAA;AAIA;AACA;AAEA;AAAA;AAGA;AAEA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AAEA;AACA;AACA;AAAA;AACA;AAGA;AACA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AACA;AACA;AAAA;AAEA;AAEA;AACA;AACA;AAAA;AAGA;AAIA;AACA;AAAA;AAGA;AAAA;AAGA;AACA;AAAA;AAGA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AAEA;AAEA;AAAA;AACA;AACA;AAEA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAEA;AACA;AACA","sources":["webpack://@mlssoccer/netcore/./scripts/libraries/_helpers/index.js","webpack://@mlssoccer/netcore/./scripts/react/mls-match-list/utils.js","webpack://@mlssoccer/netcore/./scripts/react/shared/api/fetching.js","webpack://@mlssoccer/netcore/./scripts/react/shared/api/variables.js","webpack://@mlssoccer/netcore/./scripts/react/shared/containers/utils.js","webpack://@mlssoccer/netcore/./scripts/react/shared/utils.js"],"sourcesContent":["export const x = (selector, context = document) =>\n context.querySelectorAll(selector);\n\nexport const x0 = (selector, context = document) =>\n context.querySelector(selector);\n\nexport const isTouch = (() =>\n \"ontouchstart\" in window ||\n navigator.MaxTouchPoints > 0 ||\n navigator.msMaxTouchPoints > 0)();\n\nexport const doubleDigitIntDisplay = (count) => {\n return count < 10 ? \"0\" + count : count;\n};\n\nexport function parseCSSText(cssText) {\n const cssTxt = cssText.replace(/\\/\\*(.|\\s)*?\\*\\//g, \" \").replace(/\\s+/g, \" \");\n const style = {};\n const rule = (cssTxt.match(/ ?(.*?) ?{([^}]*)}/) || [])[2] || cssTxt;\n const cssToJs = (s) =>\n s.replace(/\\W+\\w/g, (match) => match.slice(-1).toUpperCase());\n const properties = rule\n .split(\";\")\n .map((o) => o.split(\":\").map((x) => x && x.trim()));\n for (const [property, value] of properties) style[cssToJs(property)] = value;\n return style;\n}\n\nexport function truncateString(str, length = 7) {\n if (!str) {\n return null;\n }\n\n return str.length > length ? `${str.slice(0, length)}...` : str;\n}\n\nexport const callAll = (...fns) => (...args) =>\n fns.forEach((fn) => fn?.(...args));\n\nexport const mediaQueries = {\n screenSmallMin: \"(min-width: 375px)\",\n screenSmall: \"(min-width: 375px) and (max-width: 767px)\",\n screenSmallMax: \"(max-width: 767px)\",\n screenMediumMin: \"(min-width: 768px)\",\n screenMedium: \"(min-width: 768px) and (max-width: 1079px)\",\n screenMediumMax: \"(max-width: 1079px)\",\n screenMediumLargeMin: \"(min-width: 1080px)\",\n screenMediumLarge: \"(min-width: 1080px) and (max-width: 1439px)\",\n screenMediumLargeMax: \"(min-width: 1439px)\",\n screenLargeMin: \"(min-width: 1440px)\",\n screenLarge: \"(min-width: 1440px) and (max-width: 1647px)\",\n screenLargeMax: \"(max-width: 1647px)\",\n screenXLargeMin: \"(min-width: 1648px)\",\n screenXLarge: \"(min-width: 1648px) and (max-width: 1919px)\",\n screenXLargeMax: \"(max-width: 1919px)\",\n screenXXLargeMin: \"(min-width: 1920px)\",\n};\n\nexport function formatMillisecondToHumanMinute(ms) {\n if (!ms || ms < 1000) {\n return null;\n }\n const date = new Date(1000 * Math.round(ms / 1000)); // round to nearest second\n\n if (date.getUTCHours() !== 0) {\n return (\n date.getUTCHours() +\n \":\" +\n pad(date.getUTCMinutes()) +\n \":\" +\n pad(date.getUTCSeconds(), true)\n );\n }\n\n return pad(date.getUTCMinutes()) + \":\" + pad(date.getUTCSeconds(), true);\n}\n\nfunction pad(i, includeZeroPrefix = false) {\n return (`${includeZeroPrefix ? \"0\" : \"\"}` + i).slice(-2);\n}\n\n// export const getOffsetTop = (elem) => {\n// let offsetTop = 0;\n// do {\n// if (!isNaN(elem.offsetTop)) {\n// offsetTop += elem.offsetTop;\n// }\n// } while ((elem = elem.offsetParent));\n// return offsetTop;\n// };\n//\n// export const getScrollTop = () => {\n// if (typeof pageYOffset != 'undefined') {\n// return pageYOffset;\n// } else {\n// let doc = document,\n// B = doc.body,\n// D = doc.documentElement;\n//\n// D = D.clientHeight ? D : B;\n// return D.scrollTop;\n// }\n// };\n\nexport const encodeURLComponent = (str) => {\n return encodeURIComponent(str).replace(/[!'()*]/g, escape);\n};\n\nexport const getFirstCharacter = (str) => {\n if (!str) {\n return \"\";\n }\n\n return str.charAt(0);\n};\n\nexport const getParametersFromURL = () => {\n const re = /(?:\\?|&(?:amp;)?)([^=&#]+)(?:=?([^&#]*))/g,\n params = {},\n url = document.location.href,\n decode = (s) => decodeURIComponent(s.replace(/\\+/g, \" \"));\n let match;\n\n while ((match = re.exec(url))) {\n if (!params[decode(match[1])]) {\n params[decode(match[1])] = [];\n }\n params[decode(match[1])].push(decode(match[2]));\n }\n\n return params;\n};\n\n// export const closest = (el, parentClass) => {\n// do {\n// if (el.classList && el.classList.contains(parentClass)) {\n// return el;\n// }\n// } while ((el = el.parentNode));\n//\n// return null;\n// };\n\nexport const minmax = (value, min, max) => {\n const valueInt = parseInt(value, 10);\n if (isNaN(valueInt) || valueInt < min) return min;\n else if (valueInt > max) return max;\n else return value;\n};\n\n// export const setScrollTop = (offset = 0) => {\n// document.documentElement.scrollTop = document.body.scrollTop = offset;\n// };\n//\n// export const getSiblings = (elem) => {\n// const siblings = [];\n// let sibling = elem.parentNode.firstChild;\n// while (sibling) {\n// if (sibling.nodeType === 1) {\n// siblings.push(sibling);\n// }\n// sibling = sibling.nextSibling;\n// }\n// return siblings;\n// };\n\nexport function checkIfObject(obj) {\n return obj != null && obj.constructor.name === \"Object\";\n}\n\nexport function calculateDistanceBetweenTwoNumbers(firstValue, secondValue) {\n if (firstValue === secondValue) {\n return 50;\n }\n const sum = firstValue + secondValue;\n const percentageDifference = (firstValue * 100) / sum;\n\n return !percentageDifference ? 1 : percentageDifference;\n}\n\nexport function calculateDistanceBetweenTwoDecimals(firstValue, secondValue) {\n if (firstValue === secondValue) {\n return 50;\n }\n\n const sum = Number(firstValue) + Number(secondValue);\n const percentageDifference = (Number(firstValue) * 100) / sum;\n\n return !percentageDifference ? 1 : percentageDifference;\n}\n\nexport function percentDiff(first, second, isRounded = false) {\n if (first == null || isNaN(first) || second == null || isNaN(second)) {\n return 0;\n }\n\n const sum = first + second;\n const percentageDifference = (first * 100) / sum;\n\n let value;\n value = percentageDifference;\n\n return isRounded ? round(value, 1) : value;\n}\n\nexport function round(number, decimalSpot = 2) {\n if (typeof number !== \"number\") {\n return number;\n }\n\n return Number(number.toFixed(decimalSpot));\n}\n\nexport function decimalRound(number, decimalSpot = 2) {\n if (typeof number !== \"number\") {\n return number;\n }\n\n return eval((Math.round(number * 100) / 100).toFixed(decimalSpot));\n}\n\nexport function calculatePercentage(partialValue, totalValue) {\n if (!partialValue || !totalValue) {\n return decimalRound(0, 1);\n }\n\n return decimalRound((100 * partialValue) / totalValue, 1);\n}\n\nexport function calculateSubtractedValues(firstValue = 0, secondValue = 0) {\n if ((firstValue || firstValue === 0) && (secondValue || secondValue === 0)) {\n return firstValue - secondValue;\n }\n\n return 0;\n}\n\nexport function calculateSum(firstValue = 0, secondValue = 0) {\n if ((firstValue || firstValue === 0) && (secondValue || secondValue === 0)) {\n return firstValue + secondValue;\n }\n\n return 0;\n}\n\nexport function titleCase(str) {\n const splitStr = str.toLowerCase().split(\" \");\n for (let i = 0; i < splitStr.length; i++) {\n splitStr[i] =\n splitStr[i].charAt(0).toUpperCase() + splitStr[i].substring(1);\n }\n return splitStr.join(\" \");\n}\n\nexport function getPercentageFromDecimal(decimal) {\n return decimal * 100;\n}\n\n//\n// export const isDesktop = () => window.outerWidth >= 1440;\n// export const isTablet = () => window.outerWidth >= 768 && window.outerWidth < 1440;\n// export const isMobile = () => window.outerWidth < 768;\n// export const isIOS = (() => /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream)();\n// export const isIE11 = !!(\n// navigator.userAgent.match(/Trident/) && navigator.userAgent.match(/rv[ :]11/)\n// );\n\nexport function replaceAmpersand(str) {\n return String(str).replace(/&/g, \"&\");\n}\n\nexport function splitAndTrimStr(str) {\n if (str == null) {\n return [];\n }\n\n return str.split(\",\").map((word) => word.trim());\n}\n\nexport function IsMlsCompetition(compettionId) {\n const mlsIds =\n window.forgeVariables?.match?.competitionsWithFirstSecondAssists ?? \"\";\n return mlsIds.includes(compettionId);\n}\n","import {\n addYears,\n addMonths,\n addWeeks,\n endOfYear,\n endOfMonth,\n endOfWeek,\n format,\n formatISO,\n getMonth,\n isToday,\n isTomorrow,\n isWithinInterval,\n parseISO,\n startOfYear,\n startOfMonth,\n startOfWeek,\n subYears,\n subMonths,\n subWeeks,\n subDays,\n endOfDay,\n isDate,\n isBefore,\n isAfter,\n isSameDay,\n differenceInMinutes,\n isThisYear,\n} from \"date-fns\";\nimport { utcToZonedTime, zonedTimeToUtc } from \"date-fns-tz\";\nimport {\n createContext,\n useContext,\n useMemo,\n useEffect,\n useState,\n useCallback,\n} from \"react\";\nimport { useReactAppState } from \"../shared/containers/utils\";\nimport dayjs from \"dayjs\";\nimport {\n broadcasterTypes,\n filterTypes,\n getCultureLocalizer,\n} from \"../shared/utils\";\n\nexport const MatchContext = createContext();\nMatchContext.displayName = \"Match\";\n\nexport function useHash() {\n const [hash, setHash] = useState(() => window.location.hash);\n\n const hashChangeHandler = useCallback(() => {\n setHash(window.location.hash);\n }, []);\n\n useEffect(() => {\n window.addEventListener(\"hashchange\", hashChangeHandler);\n return () => {\n window.removeEventListener(\"hashchange\", hashChangeHandler);\n };\n }, []);\n\n const updateHash = useCallback(\n (newHash) => {\n if (newHash !== hash) window.location.hash = newHash;\n },\n [hash],\n );\n\n return [hash, updateHash];\n}\n\nexport const getHashQueryObject = (query) => {\n const pairs = query.slice(1).split(\"&\");\n const filters = {};\n pairs.forEach(function (pair) {\n pair = pair.split(\"=\");\n filters[pair[0]] = decodeURIComponent(pair[1] || \"\");\n });\n\n return filters;\n};\n\nexport function useMatchData() {\n const context = useContext(MatchContext);\n if (context === undefined) {\n throw new Error(\"useMatchData must be used within a \");\n }\n return context;\n}\n\nexport const composeAggregate = (aggregate, date) => {\n if (!aggregate) {\n return null;\n }\n\n if (!date || !aggregate.includes(\"##date##\")) {\n return aggregate;\n }\n\n return aggregate.replace(/##date##/g, dayjs(date).format(\"MM/DD/YYYY\"));\n};\n\nexport function getTimeAdjustedByTimeZone(\n dateString,\n timeZoneString = \"America/New_York\",\n) {\n return utcToZonedTime(`${dateString}`, timeZoneString);\n}\n\nfunction takeCrossSectionOfMonthMatchList({ matchList, weekRange }) {\n const { dateRangeStart, dateRangeEnd } = weekRange || {};\n\n if (!matchList) {\n return null;\n }\n\n return matchList.filter((match) => {\n const date = parseISO(match.date);\n\n return isWithinInterval(date, { start: dateRangeStart, end: dateRangeEnd });\n });\n}\n\nexport const useMatchList = ({ matchList, dateRangeType, weekRange }) => {\n if (!matchList) {\n return null;\n }\n\n let month;\n\n return dateRangeType === dateRangeTypes.week\n ? takeCrossSectionOfMonthMatchList({ matchList, weekRange })\n : dateRangeType === dateRangeTypes.year\n ? matchList\n : matchList.reduce((accum, current) => {\n const parsedDate = parseISO(current.date);\n if (month == null) {\n month = getMonth(parsedDate);\n accum.push({\n date: current.date,\n matches: [...current.matches],\n });\n\n return accum;\n } else {\n if (month === getMonth(parsedDate)) {\n accum[accum.length - 1].matches.push(...current.matches);\n } else {\n accum.push({\n date: current.date,\n matches: [current.matches],\n });\n }\n\n return accum;\n }\n }, []);\n};\n\nexport const useDateDisplay = (date, dateRangeType = dateRangeTypes.week) => {\n const { t } = useReactAppState();\n const parsedDate = parseISO(date);\n return useMemo(() => {\n return dateRangeType === dateRangeTypes.week\n ? isToday(parsedDate)\n ? `${t(\"today\")}, ${format(parsedDate, isThisYear(parsedDate) ? \"MMM d\" : \"MMM d, yyy\", { locale: getCultureLocalizer() })}`\n : isTomorrow(parsedDate)\n ? `${t(\"tomorrow\")}, ${format(parsedDate, isThisYear(parsedDate) ? \"MMM d\" : \"MMM d, yyy\", { locale: getCultureLocalizer() })}`\n : format(\n parsedDate,\n isThisYear(parsedDate) ? \"EEEE MMM d\" : \"EEEE MMM d, yyy\",\n { locale: getCultureLocalizer() },\n )\n : format(parsedDate, \"MMMM yyy\", { locale: getCultureLocalizer() });\n }, [date, dateRangeType]);\n};\n\nfunction getTimezone() {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n}\n\nexport const composeDateRangeStartAndEnd = (\n now,\n dateRangeType = dateRangeTypes.week,\n) => {\n if (!now) {\n return {\n currentRangeYear: null,\n currentRangeMonth: null,\n currentRangeWeek: null,\n nextRangeYear: null,\n nextRangeMonth: null,\n nextRangeWeek: null,\n prevRangeYear: null,\n prevRangeMonth: null,\n prevRangeWeek: null,\n isoStringRS: null,\n isoStringRE: null,\n };\n }\n\n const timezone = getTimezone();\n const composedNow = utcToZonedTime(now, timezone);\n\n const { yearRange, monthRange, weekRange } = getDateRange(composedNow);\n\n const {\n currentRange: currentRangeYear,\n nextRange: nextRangeYear,\n prevRange: prevRangeYear,\n } = yearRange || {};\n const {\n currentRange: currentRangeWeek,\n nextRange: nextRangeWeek,\n prevRange: prevRangeWeek,\n } = weekRange || {};\n const {\n currentRange: currentRangeMonth,\n nextRange: nextRangeMonth,\n prevRange: prevRangeMonth,\n } = monthRange || {};\n const { isoStringRS, isoStringRE } = convertToIsoString(\n dateRangeType === dateRangeTypes.week\n ? currentRangeWeek\n : dateRangeType === dateRangeTypes.year\n ? currentRangeYear\n : currentRangeMonth,\n );\n\n return {\n currentRangeYear,\n currentRangeMonth,\n currentRangeWeek,\n nextRangeYear,\n nextRangeMonth,\n nextRangeWeek,\n prevRangeYear,\n prevRangeMonth,\n prevRangeWeek,\n isoStringRS,\n isoStringRE,\n };\n};\n\nexport function orderStatsApiMatchesByDate(matchesData) {\n if (!matchesData) {\n return null;\n }\n\n return matchesData.map((match) => {\n const { date } = match;\n return parseISO(date);\n });\n}\n\nexport function orderMatchesLiteByDate({ matchesData }) {\n if (!matchesData) {\n return null;\n }\n\n const orderedMatches = [];\n\n for (let i = 0; i < matchesData.length; i++) {\n const currentMatch = matchesData[i];\n\n const { optaId: matchOptaId, matchDate } = currentMatch || {};\n\n if (!matchOptaId) {\n continue;\n }\n\n if (!matchDate) {\n continue;\n }\n\n const toTimeZone = getTimeAdjustedByTimeZone(matchDate);\n const currentDate = format(toTimeZone, \"yyyy-LL-dd\");\n\n const latestOrderedMatchDate = orderedMatches[orderedMatches.length - 1];\n\n if (\n orderedMatches.length === 0 ||\n latestOrderedMatchDate.date !== currentDate\n ) {\n const matchDay = {\n date: currentDate,\n matches: [currentMatch],\n };\n\n orderedMatches.push(matchDay);\n } else {\n latestOrderedMatchDate.matches.push(currentMatch);\n }\n }\n\n return orderedMatches;\n}\n\nexport function orderEnrichedMatchesByDate({\n dateRangeType = dateRangeTypes.week,\n mlsMatches,\n competitionSportecId,\n clubSportecId,\n isoStringRS,\n isoStringRE,\n}) {\n const enrichedMatches = matchesDataLocalTimes(\n mlsMatches,\n isoStringRS,\n isoStringRE,\n );\n return orderMatchesByDate({\n dateRangeType,\n mlsMatches: enrichedMatches,\n clubSportecId,\n competitionSportecId,\n });\n}\n\nexport function matchesDataLocalTimes(mlsMatches, isoStringRS, isoStringRE) {\n if (!mlsMatches) {\n return;\n }\n\n return mlsMatches\n .map((mlsMatch) => ({\n ...mlsMatch,\n localMatchDate: mlsMatch.planned_kickoff_time && parseISO(mlsMatch.planned_kickoff_time),\n localMatchKickOffTime:\n mlsMatch.planned_kickoff_time && parseISO(mlsMatch.planned_kickoff_time),\n }))\n .filter((mlsMatch) => {\n if (!isoStringRS || !isoStringRE) {\n return true;\n } else {\n const day = parseISO(mlsMatch?.planned_kickoff_time);\n return (\n isSameDay(day, parseISO(isoStringRS)) ||\n isSameDay(day, parseISO(isoStringRE)) ||\n (!isBefore(day, parseISO(isoStringRS)) &&\n !isAfter(day, parseISO(isoStringRE)))\n );\n }\n });\n}\n\nexport function orderMatchesByDate({\n dateRangeType = dateRangeTypes.week,\n mlsMatches,\n competitionSportecId,\n clubSportecId,\n isAllMatches = false,\n}) {\n if (!mlsMatches) {\n return null;\n }\n\n const orderedMatches = [];\n\n for (let i = 0; i < mlsMatches.length; i++) {\n const currentMatch = mlsMatches[i];\n\n const {\n localMatchDate,\n match_id,\n competition_id,\n away_team_id,\n home_team_id,\n } = currentMatch || {};\n\n if (!localMatchDate || !match_id) {\n continue;\n }\n\n if (\n clubSportecId !== filterTypes.all.toLowerCase() &&\n away_team_id !== clubSportecId &&\n home_team_id !== clubSportecId\n ) {\n continue;\n }\n\n if (\n competitionSportecId !== filterTypes.all.toLowerCase() &&\n competition_id !== competitionSportecId\n ) {\n continue;\n }\n\n const currentDate = format(currentMatch.localMatchDate, \"yyyy-LL-dd\");\n const latestOrderedMatchDate = orderedMatches[orderedMatches.length - 1];\n const currentMonth = format(currentMatch.localMatchDate, \"LL\");\n if (dateRangeType === dateRangeTypes.year) {\n if (\n orderedMatches.length === 0 ||\n latestOrderedMatchDate.month !== currentMonth\n ) {\n const matchDay = {\n date: currentDate,\n month: currentMonth,\n matches: [currentMatch],\n };\n\n orderedMatches.push(matchDay);\n } else {\n latestOrderedMatchDate.matches.push(currentMatch);\n }\n } else {\n if (\n orderedMatches.length === 0 ||\n latestOrderedMatchDate.date !== currentDate\n ) {\n const matchDay = {\n date: currentDate,\n matches: [currentMatch],\n };\n\n orderedMatches.push(matchDay);\n } else {\n latestOrderedMatchDate.matches.push(currentMatch);\n }\n }\n }\n\n return orderedMatches;\n}\n\nfunction getDateRange(now) {\n const yearRange = getYearRange(now);\n const weekRange = getWeekRange(now);\n const monthRange = getMonthRange(now);\n\n return { weekRange, monthRange, yearRange };\n}\n\nexport function getYear(date) {\n return format(date, \"y\");\n}\n\nfunction getWeekRange(now) {\n const weekStart = startOfWeek(now, { weekStartsOn: 1 });\n const weekEnd = endOfWeek(weekStart, { weekStartsOn: 1 });\n\n const prevWeekStart = subWeeks(weekStart, 1);\n const prevWeekEnd = endOfWeek(prevWeekStart, { weekStartsOn: 1 });\n\n const nextWeekEnd = addWeeks(weekEnd, 1);\n const nextWeekStart = startOfWeek(nextWeekEnd, { weekStartsOn: 1 });\n\n const prevRange = getIsoStringWeekEndWeekStart(prevWeekStart, prevWeekEnd);\n const currentRange = getIsoStringWeekEndWeekStart(weekStart, weekEnd);\n const nextRange = getIsoStringWeekEndWeekStart(nextWeekStart, nextWeekEnd);\n\n return { prevRange, currentRange, nextRange };\n}\n\nfunction getMonthRange(now) {\n const monthStart = startOfMonth(now);\n const monthEnd = endOfMonth(now);\n\n const prevMonthStart = subMonths(monthStart, 1);\n const prevMonthEnd = endOfMonth(prevMonthStart);\n\n const nextMonthEnd = endOfMonth(addMonths(monthEnd, 1));\n const nextMonthStart = startOfMonth(nextMonthEnd);\n\n const prevRange = getIsoStringMonthEndMonthStart(\n prevMonthStart,\n prevMonthEnd,\n );\n const currentRange = getIsoStringMonthEndMonthStart(monthStart, monthEnd);\n const nextRange = getIsoStringMonthEndMonthStart(\n nextMonthStart,\n nextMonthEnd,\n );\n\n return { prevRange, currentRange, nextRange };\n}\n\nfunction getYearRange(now) {\n const yearStart = startOfYear(now);\n const yearEnd = endOfYear(now);\n\n const prevYearStart = subYears(yearStart, 1);\n const prevYearEnd = endOfYear(prevYearStart);\n\n const nextYearEnd = addYears(yearEnd, 1);\n const nextYearStart = startOfYear(nextYearEnd);\n\n const prevRange = getIsoStringWeekEndWeekStart(\n prevYearStart,\n endOfDay(subDays(prevYearEnd, 1)),\n );\n const currentRange = getIsoStringWeekEndWeekStart(\n yearStart,\n endOfDay(subDays(yearEnd, 1)),\n );\n const nextRange = getIsoStringWeekEndWeekStart(\n nextYearStart,\n endOfDay(subDays(nextYearEnd, 1)),\n );\n\n return { prevRange, currentRange, nextRange };\n}\n\nfunction getIsoStringWeekEndWeekStart(\n weekStart,\n weekEnd,\n timeZone = \"America/Los_Angeles\",\n) {\n const dateRangeStart = dayjs(weekStart).toDate();\n const dateRangeEnd = dayjs(weekEnd).toDate();\n\n const monthWeekStart = format(dateRangeStart, \"MMM\", {\n locale: getCultureLocalizer(),\n });\n const monthWeekEnd = format(dateRangeEnd, \"MMM\", {\n locale: getCultureLocalizer(),\n });\n const dayWeekStart = format(dateRangeStart, \"d\");\n const dayWeekEnd = format(dateRangeEnd, \"d\");\n\n const monthWeekStartIntl = format(dateRangeStart, \"MMM\", {\n locale: getCultureLocalizer(),\n });\n const monthWeekEndIntl = format(dateRangeEnd, \"MMM\", {\n locale: getCultureLocalizer(),\n });\n\n const formattedDateRangeString =\n monthWeekStart === monthWeekEnd\n ? `${monthWeekStart} ${dayWeekStart} - ${dayWeekEnd}`\n : `${monthWeekStart} ${dayWeekStart} - ${monthWeekEnd} ${dayWeekEnd}`;\n\n const formattedDateRangeStringIntl =\n monthWeekStartIntl === monthWeekEndIntl\n ? `${monthWeekStartIntl} ${dayWeekStart} - ${dayWeekEnd}`\n : `${monthWeekStartIntl} ${dayWeekStart} - ${monthWeekEndIntl} ${dayWeekEnd}`;\n\n return {\n dateRangeStart,\n dateRangeEnd,\n formattedDateRangeString,\n formattedDateRangeStringIntl,\n };\n}\n\nfunction getIsoStringMonthEndMonthStart(\n monthStart,\n monthEnd,\n timeZone = \"America/Los_Angeles\",\n) {\n const dateRangeStart = monthStart;\n const dateRangeEnd = monthEnd;\n\n const monthWeekStart = format(dateRangeStart, \"MMM\", {\n locale: getCultureLocalizer(),\n });\n const monthWeekEnd = format(dateRangeEnd, \"MMM\", {\n locale: getCultureLocalizer(),\n });\n const dayWeekStart = format(dateRangeStart, \"d\");\n const dayWeekEnd = format(dateRangeEnd, \"d\");\n\n const monthWeekStartIntl = format(dateRangeStart, \"MMM\", {\n locale: getCultureLocalizer(),\n });\n const monthWeekEndIntl = format(dateRangeEnd, \"MMM\", {\n locale: getCultureLocalizer(),\n });\n\n const formattedDateRangeString =\n monthWeekStart === monthWeekEnd\n ? `${monthWeekStart} ${dayWeekStart} - ${dayWeekEnd}`\n : `${monthWeekStart} ${dayWeekStart} - ${monthWeekEnd} ${dayWeekEnd}`;\n\n const formattedDateRangeStringIntl =\n monthWeekStartIntl === monthWeekEndIntl\n ? `${monthWeekStartIntl} ${dayWeekStart} - ${dayWeekEnd}`\n : `${monthWeekStartIntl} ${dayWeekStart} - ${monthWeekEndIntl} ${dayWeekEnd}`;\n\n return {\n dateRangeStart,\n dateRangeEnd,\n formattedDateRangeString,\n formattedDateRangeStringIntl,\n };\n}\n\nexport function convertToIsoString({ dateRangeStart, dateRangeEnd }) {\n const isoStringRS = formatISO(dateRangeStart, { representation: \"date\" });\n const isoStringRE = formatISO(dateRangeEnd, { representation: \"date\" });\n\n return {\n isoStringRS,\n isoStringRE,\n };\n}\n\nexport const getNearestDate = ({ date, previousDate, nextDate }) => {\n if (!date || (!previousDate && !nextDate)) {\n return null;\n }\n\n if (!previousDate) {\n return nextDate;\n }\n\n if (!nextDate) {\n return previousDate;\n }\n\n const previousDiff = Math.abs(date - previousDate);\n const nextDiff = Math.abs(date - nextDate);\n\n if (previousDiff < nextDiff) {\n return previousDate;\n } else {\n return nextDate;\n }\n};\n\nexport const useMediaProviders = ({\n broadcasters,\n homeClubBroadcasters,\n awayClubBroadcasters,\n clubBroadcasters,\n}) => {\n const { t } = useReactAppState();\n if (\n broadcasters == null &&\n homeClubBroadcasters == null &&\n awayClubBroadcasters == null &&\n clubBroadcasters == null\n ) {\n return null;\n }\n\n const broadcastersArray =\n broadcasters && broadcasters.length > 0\n ? broadcasters.map((broadcaster) => {\n if (broadcaster?.broadcasterType) {\n broadcaster.broadcasterTypeLabel = t(\n \"brd_type_\" +\n broadcaster?.broadcasterType.toLowerCase().replace(/ /g, \"_\"),\n );\n }\n\n return broadcaster;\n })\n : [];\n\n const clubBroadcastersArray =\n clubBroadcasters && clubBroadcasters.length > 0\n ? clubBroadcasters.map((broadcaster) => {\n const { broadcasterName, broadcasterType } = broadcaster || {};\n\n const broadcasterTypeLabel = broadcaster?.broadcasterTypeLabel\n ? broadcaster?.broadcasterTypeLabel\n : broadcasterType === broadcasterTypes.linearTv\n ? t(\"brd_type_linear_tv\")\n : broadcasterType === broadcasterTypes.streaming\n ? t(\"brd_type_streaming\")\n : broadcasterType === broadcasterTypes.radio\n ? t(\"brd_type_radio\")\n : null;\n\n return {\n ...broadcaster,\n broadcasterTypeLabel,\n broadcasterName:\n broadcasterName != null ? `${broadcasterName}` : null,\n };\n })\n : [];\n\n const homeClubBroadcastersArray =\n homeClubBroadcasters && homeClubBroadcasters.length > 0\n ? homeClubBroadcasters.map((broadcaster) => {\n const { broadcasterName, broadcasterType } = broadcaster || {};\n\n const broadcasterTypeLabel =\n broadcasterType === broadcasterTypes.linearTv\n ? t(\"brd_type_home_linear_tv\")\n : null;\n\n return {\n ...broadcaster,\n broadcasterTypeLabel,\n broadcasterName:\n broadcasterName != null ? `${broadcasterName}` : null,\n };\n })\n : [];\n\n const awayClubBroadcastersArray =\n awayClubBroadcasters && awayClubBroadcasters.length > 0\n ? awayClubBroadcasters.map((broadcaster) => {\n const { broadcasterName, broadcasterType } = broadcaster || {};\n\n const broadcasterTypeLabel =\n broadcasterType === broadcasterTypes.linearTv\n ? t(\"brd_type_away_linear_tv\")\n : null;\n\n return {\n ...broadcaster,\n broadcasterTypeLabel,\n broadcasterName:\n broadcasterName != null ? `${broadcasterName}` : null,\n };\n })\n : [];\n\n const mergedProviders = [\n ...broadcastersArray,\n ...homeClubBroadcastersArray,\n ...awayClubBroadcastersArray,\n ...clubBroadcastersArray,\n ];\n\n const providerObj = mergedProviders.reduce((accum, current) => {\n if (current?.broadcasterStreamingURL) {\n if (accum.streamingList && accum.streamingList.length > 0) {\n accum.streamingList.push(current);\n } else {\n accum.streamingList = [current];\n }\n }\n\n if (current?.broadcasterType === broadcasterTypes.usStreaming) {\n if (accum.usStreaming && accum.usStreaming.length > 0) {\n accum.usStreaming.push(current);\n } else {\n accum.usStreaming = [current];\n }\n }\n\n if (current?.broadcasterType === broadcasterTypes.canadianStreaming) {\n if (accum.canadianStreaming && accum.canadianStreaming.length > 0) {\n accum.canadianStreaming.push(current);\n } else {\n accum.canadianStreaming = [current];\n }\n }\n\n if (current?.broadcasterType === broadcasterTypes.usNational) {\n if (accum.usNational && accum.usNational.length > 0) {\n accum.usNational.push(current);\n } else {\n accum.usNational = [current];\n }\n }\n\n if (current?.broadcasterType === broadcasterTypes.canadianNational) {\n if (accum.canadianNational && accum.canadianNational.length > 0) {\n accum.canadianNational.push(current);\n } else {\n accum.canadianNational = [current];\n }\n }\n\n if (\n current?.broadcasterType === broadcasterTypes.canadaRadio ||\n current?.broadcasterType === broadcasterTypes.usRadio\n ) {\n if (accum.radio && accum.radio.length > 0) {\n accum.radio.push(current);\n } else {\n accum.radio = [current];\n }\n }\n\n if (accum.allProvidersList) {\n if (current?.broadcasterTypeLabel) {\n accum.allProvidersList.push(current);\n }\n } else {\n if (current?.broadcasterTypeLabel) {\n accum.allProvidersList = [current];\n }\n }\n return accum;\n }, {});\n\n const homeProviderObj = homeClubBroadcastersArray.reduce((accum, current) => {\n if (current?.broadcasterType === broadcasterTypes.linearTv) {\n if (accum.homeLinear && accum.homeLinear.length > 0) {\n accum.homeLinear.push(current);\n } else {\n accum.homeLinear = [current];\n }\n }\n\n return accum;\n }, {});\n\n const awayProviderObj = awayClubBroadcastersArray.reduce((accum, current) => {\n if (current?.broadcasterType === broadcasterTypes.linearTv) {\n if (accum.awayLinear && accum.awayLinear.length > 0) {\n accum.awayLinear.push(current);\n } else {\n accum.awayLinear = [current];\n }\n }\n\n return accum;\n }, {});\n\n const clubProviderObj = clubBroadcastersArray.reduce((accum, current) => {\n if (current?.broadcasterType === broadcasterTypes.linearTv) {\n if (accum.clubLinear && accum.clubLinear.length > 0) {\n accum.clubLinear.push(current);\n } else {\n accum.clubLinear = [current];\n }\n }\n\n if (current?.broadcasterType === broadcasterTypes.streaming) {\n if (accum.clubStreaming && accum.clubStreaming.length > 0) {\n accum.clubStreaming.push(current);\n } else {\n accum.clubStreaming = [current];\n }\n }\n\n if (current?.broadcasterType === broadcasterTypes.radio) {\n if (accum.clubRadio && accum.clubRadio.length > 0) {\n accum.clubRadio.push(current);\n } else {\n accum.clubRadio = [current];\n }\n }\n\n return accum;\n }, {});\n\n const mergedObj = {\n ...providerObj,\n ...homeProviderObj,\n ...awayProviderObj,\n ...clubProviderObj,\n };\n\n return isEmpty(mergedObj) ? null : mergedObj;\n};\n\nfunction isEmpty(obj) {\n return Object.keys(obj).length === 0;\n}\n\nexport function composeMatchStatus({\n period,\n isFinal = false,\n delayedMatch = false,\n}) {\n let status = {\n value: period,\n };\n\n if (delayedMatch) {\n return {\n value: periodTypes.Delayed,\n abbreviation: statusTypes.delayed,\n };\n }\n\n if (isFinal && period !== periodTypes.Abandoned) {\n return {\n value: \"FullTime\",\n abbreviation: statusTypes.post,\n };\n }\n\n switch (period) {\n case periodTypes.firstHalf:\n case periodTypes.half:\n case periodTypes.secondHalf:\n case periodTypes.preExtra:\n case periodTypes.firstHalfExtra:\n case periodTypes.halfExtra:\n case periodTypes.secondHalfExtra:\n case periodTypes.prePenalty:\n case periodTypes.penalty:\n status = {\n ...status,\n period,\n abbreviation: statusTypes.live,\n };\n break;\n case periodTypes.finalWhistle:\n status = {\n ...status,\n period,\n abbreviation: statusTypes.post,\n };\n break;\n case periodTypes.Abandoned:\n status = {\n ...status,\n abbreviation: statusTypes.abandoned,\n };\n break;\n case periodTypes.Postponed:\n status = {\n ...status,\n abbreviation: statusTypes.postponed,\n };\n break;\n case periodTypes.Cancelled:\n status = {\n ...status,\n abbreviation: statusTypes.cancelled,\n };\n break;\n case periodTypes.preMatch:\n default:\n status = {\n ...status,\n abbreviation: statusTypes.pre,\n };\n }\n\n return status;\n}\n\nexport function minutesBeforeMatchStart(date) {\n if (!date || !isDate(date) || date?.toString() === \"Invalid Date\") {\n return 0;\n }\n\n return differenceInMinutes(date, Date.now());\n}\n\nexport function useMatchDateTime(utcString) {\n if (utcString == null) {\n return null;\n }\n const easternStandardTime = getTimeAdjustedByTimeZone(utcString);\n const time = format(easternStandardTime, \"p\");\n const date = format(easternStandardTime, \"M/d\");\n const fullDate = format(easternStandardTime, \"M/d/y\");\n const matchFullDateTime = format(easternStandardTime, \"PP, p\");\n\n return { time, date, matchFullDateTime, easternStandardTime, fullDate };\n}\n\nexport function useLocalMatchHour(matchDate) {\n if (matchDate == null) {\n return null;\n }\n\n const localTime = dayjs(matchDate).toDate();\n const hours = format(localTime, \"h:mm aaa\")?.toLowerCase();\n\n return { hours };\n}\n\nexport function useLocalMatchDateTime(matchDate) {\n if (matchDate == null) {\n return null;\n }\n const localTime = dayjs(matchDate).toDate();\n const time = format(localTime, \"p\");\n const date = format(localTime, \"M/d\");\n const fullDate = format(localTime, \"M/d/y\");\n const matchFullDateTime = format(localTime, \"PP, p\");\n\n return { time, date, matchFullDateTime, localTime, fullDate };\n}\n\nexport function useVenueData(venueEntity) {\n if (!venueEntity?.[0]?.fields) {\n return null;\n }\n\n return useMemo(() => {\n const { fields } = venueEntity[0];\n const { name, stateOrProvince, country, city } = fields || {};\n const fullVenueInfo = formatVenue({ name, stateOrProvince, city, country });\n\n return {\n name,\n stateOrProvince,\n country,\n city,\n fullVenueInfo,\n };\n }, [venueEntity]);\n}\n\nexport function formatVenue({ name, stateOrProvince, city, country }) {\n const venueArr = [];\n\n if (name) {\n stateOrProvince || city || country\n ? venueArr.push(`${name},`)\n : venueArr.push(name);\n }\n\n if (city) {\n stateOrProvince || country\n ? venueArr.push(`${city},`)\n : venueArr.push(city);\n }\n\n if (stateOrProvince) {\n country\n ? venueArr.push(`${stateOrProvince},`)\n : venueArr.push(stateOrProvince);\n }\n\n if (country) {\n venueArr.push(country);\n }\n\n return venueArr ? venueArr.join(\"\") : null;\n}\n\nfunction composeShootout({\n period,\n resultType,\n homeShootoutScore,\n awayShootoutScore,\n homeAbbrev,\n awayAbbrev,\n}) {\n if (\n period === periodTypes.ShootOut ||\n period === periodTypes.FullTimePens ||\n resultType === resultTypes.Shootout\n ) {\n if (homeShootoutScore === null && awayShootoutScore === null) {\n return \"Going to PKs\";\n }\n\n const homeFormattedShootoutScore = homeShootoutScore || 0;\n const awayFormattedShootoutScore = awayShootoutScore || 0;\n\n return homeFormattedShootoutScore === awayFormattedShootoutScore\n ? `${homeAbbrev} ties ${awayAbbrev} ${homeFormattedShootoutScore}:${awayFormattedShootoutScore} on PKs`\n : awayFormattedShootoutScore > homeFormattedShootoutScore\n ? `${awayAbbrev} ${period === periodTypes.ShootOut ? \"leads\" : \"wins\"} ${awayFormattedShootoutScore}:${homeFormattedShootoutScore} on PKs`\n : `${homeAbbrev} ${period === periodTypes.ShootOut ? \"leads\" : \"wins\"} ${homeFormattedShootoutScore}:${awayFormattedShootoutScore} on PKs`;\n }\n\n return null;\n}\n\nexport function formatScores({\n homeClubData,\n awayClubData,\n period,\n resultType,\n}) {\n const {\n homeScore,\n homeShootoutScore,\n abbreviation: homeAbbrev,\n } = homeClubData || {};\n const {\n awayScore,\n awayShootoutScore,\n abbreviation: awayAbbrev,\n } = awayClubData || {};\n\n const formattedHomeScore = homeScore === 0 || !homeScore ? 0 : homeScore;\n const formattedAwayScore = awayScore === 0 || !awayScore ? 0 : awayScore;\n const formattedHomeShootoutScore =\n homeShootoutScore === 0 || !homeShootoutScore ? 0 : homeShootoutScore;\n const formattedAwayShootoutScore =\n awayShootoutScore === 0 || !awayShootoutScore ? 0 : awayShootoutScore;\n\n const shootoutResult = composeShootout({\n period,\n resultType,\n homeShootoutScore,\n awayShootoutScore,\n homeAbbrev,\n awayAbbrev,\n });\n\n return {\n homeScore: formattedHomeScore,\n awayScore: formattedAwayScore,\n homeShootoutScore: formattedHomeShootoutScore,\n awayShootoutScore: formattedAwayShootoutScore,\n shootoutResult,\n };\n}\n\nexport function formatMlsMatchScores({ match }) {\n const { match_information } = match || {};\n const { home_team_goals = 0, away_team_goals = 0 } = match_information || {};\n\n const shootout_result = composeMlsMatchShootout({ match });\n\n return {\n shootout_result,\n home_score: home_team_goals,\n away_score: away_team_goals,\n };\n}\n\nexport function composeMlsMatchShootout({ match }) {\n const { match_information, home, away } = match || {};\n const { match_status, home_team_penalty_goals, away_team_penalty_goals } = match_information || {};\n\n const homeAbbrev = home?.team_three_letter_code || home?.team_short_name;\n const awayAbbrev = away?.team_three_letter_code || away?.team_short_name;\n\n\n if (match_status === periodTypes.prePenalty) {\n return \"Going to PKs\";\n }\n\n if (isNaN(home_team_penalty_goals) || isNaN(away_team_penalty_goals)) {\n return null;\n }\n\n if (home_team_penalty_goals === away_team_penalty_goals) {\n return `${homeAbbrev} ties ${awayAbbrev} ${home_team_penalty_goals}:${away_team_penalty_goals} on PKs`\n }\n\n if (home_team_penalty_goals > away_team_penalty_goals) {\n return `${homeAbbrev} wins ${home_team_penalty_goals}:${away_team_penalty_goals} on PKs`\n }\n\n if (away_team_penalty_goals > home_team_penalty_goals) {\n return `${awayAbbrev} wins ${away_team_penalty_goals}:${home_team_penalty_goals} on PKs`\n }\n\n return null;\n}\n\nexport const listTypes = {\n tv: \"tv\",\n matches: \"matches\",\n odds: \"odds\",\n};\n\nexport const statusTypes = {\n live: \"live\",\n post: \"post\",\n pre: \"pre\",\n abandoned: \"aban\",\n postponed: \"ppd\",\n cancelled: \"canc\",\n delayed: \"dly\",\n scheduled: \"scheduled\",\n preMatch: \"preMatch\",\n firstHalf: \"firstHalf\",\n half: \"half\",\n secondHalf: \"secondHalf\",\n preExtra: \"preExtra\",\n firstHalfExtra: \"firstHalfExtra\",\n halfExtra: \"halfExtra\",\n secondHalfExtra: \"secondHalfExtra\",\n prePenalty: \"prePenalty\",\n penalty: \"penalty\",\n finalWhistle: \"finalWhistle\"\n};\n\nexport const dateRangeTypes = {\n year: \"year\",\n month: \"month\",\n week: \"week\",\n};\n\nexport const periodTypes = {\n PreMatch: \"PreMatch\",\n FirstHalf: \"FirstHalf\",\n HalfTime: \"HalfTime\",\n SecondHalf: \"SecondHalf\",\n FullTime90: \"FullTime90\",\n ExtraFirstHalf: \"ExtraFirstHalf\",\n ExtraHalfTime: \"ExtraHalfTime\",\n ExtraSecondHalf: \"ExtraSecondHalf\",\n ShootOut: \"ShootOut\",\n FullTimePens: \"FullTimePens\",\n FullTime: \"FullTime\",\n Abandoned: \"Abandoned\",\n Postponed: \"Postponed\",\n Cancelled: \"Cancelled\",\n Delayed: \"Delayed\",\n PenaltyShootout: \"PenaltyShootout\",\n scheduled: \"scheduled\",\n preMatch: \"preMatch\",\n half: \"half\",\n penalty: \"penalty\",\n prePenalty: \"prePenalty\",\n preExtra: \"preExtra\",\n halfExtra: \"halfExtra\",\n finalWhistle: \"finalWhistle\",\n firstHalf: \"firstHalf\",\n half: \"half\",\n secondHalf: \"secondHalf\",\n preExtra: \"preExtra\",\n firstHalfExtra: \"firstHalfExtra\",\n halfExtra: \"halfExtra\",\n secondHalfExtra: \"secondHalfExtra\",\n prePenalty: \"prePenalty\",\n penalty: \"penalty\",\n finalWhistle: \"finalWhistle\",\n secondHalf: \"secondHalf\",\n secondHalfExtra: \"secondHalfExtra\",\n};\n\nexport const resultTypes = {\n NormalResult: \"NormalResult\",\n AfterExtraTime: \"AfterExtraTime\",\n Abandoned: \"Abandoned\",\n Shootout: \"PenaltyShootout\",\n Cancelled: \"Cancelled\",\n Aggregate: \"Aggregate\",\n AwayGoals: \"AwayGoals\",\n};\n\nexport const matchTypes = {\n FirstLeg: \"1st Leg\",\n SecondLeg: \"2nd Leg\",\n SecondLegAway: \"2nd Leg Away Goal\",\n Cup: \"Cup\",\n CupGold: \"Cup Gold\",\n CupShort: \"Cup Short\",\n Regular: \"Regular\",\n SecondLegCupShort: \"2nd Leg Cup Short\",\n};\n\nexport function composeLeg(leg, t, isScoreboard = false) {\n if (!leg) {\n return \"\";\n }\n\n if (leg === matchTypes.FirstLeg) {\n if (isScoreboard) {\n return t(\"l1\");\n }\n return t(\"1st_leg\");\n } else if (leg === matchTypes.SecondLeg) {\n if (isScoreboard) {\n return t(\"l2\");\n }\n return t(\"2nd_leg\");\n } else if (leg === matchTypes.Cup) {\n if (isScoreboard) {\n return t(\"c\");\n }\n return t(\"cup\");\n } else if (leg === matchTypes.CupGold) {\n if (isScoreboard) {\n return t(\"cg\");\n }\n return t(\"cup_gold\");\n } else if (leg === matchTypes.CupShort) {\n if (isScoreboard) {\n return t(\"cs\");\n }\n return t(\"cup_short\");\n } else if (leg === matchTypes.Regular) {\n if (isScoreboard) {\n return t(\"r\");\n }\n return t(\"regular\");\n } else if (leg === matchTypes.SecondLegCupShort) {\n if (isScoreboard) {\n return t(\"l2cs\");\n }\n return t(\"2nd_leg_cup_short\");\n } else if (leg === matchTypes.SecondLegAway) {\n if (isScoreboard) {\n return t(\"l2aG\");\n }\n return t(\"2nd_leg_away_goal\");\n } else {\n return leg;\n }\n}\n\nexport const getMatchListOdds = (oddsData) => {\n let data = {};\n if (!oddsData || !oddsData?.length) {\n return null;\n }\n\n const range = (firstNum, secondNum) =>\n [\n ...Array(\n firstNum >= secondNum ? firstNum - secondNum : secondNum - firstNum,\n ).keys(),\n ].map((i) => i + (firstNum <= secondNum ? firstNum : secondNum)).length;\n\n const market = oddsData[0]?.markets?.find((odd) => {\n return (\n odd?.marketType === \"3way\" &&\n odd?.name?.text === \"Match Result\" &&\n odd?.isDisplayed === true\n );\n });\n\n const overUnderMarket = oddsData[0].markets\n ?.filter((odd) => {\n return (\n odd?.marketType === \"Over/Under\" &&\n odd?.name?.text === \"Total Goals\" &&\n odd?.isDisplayed === true\n );\n })\n .reduce(\n (accumulator, market) => {\n const overUnderOptions = market?.options;\n const overOption = overUnderOptions?.find(\n (option) =>\n option?.name?.text?.includes(\"Over\") &&\n option?.isDisplayed === true,\n );\n const underOption = overUnderOptions?.find(\n (option) =>\n option?.name?.text?.includes(\"Under\") &&\n option?.isDisplayed === true,\n );\n const overPrice = overOption?.price?.usOdds;\n const underPrice = underOption?.price?.usOdds;\n if (typeof overPrice === \"number\" && typeof underPrice === \"number\") {\n const rangePrice = range(overPrice, underPrice);\n if (accumulator?.range === null || rangePrice <= accumulator?.range) {\n accumulator = { range: rangePrice, market };\n return accumulator;\n } else {\n return accumulator;\n }\n } else {\n return accumulator;\n }\n },\n { range: null },\n )?.market;\n\n const options = market ? market?.options : [];\n const overUnderOptions = overUnderMarket?.options || [];\n\n if (market && options.length) {\n const homeOption = options[0] && options[0].isDisplayed ? options[0] : null;\n const tieOption =\n options[1] && options[1].isDisplayed && options[1].name.text === \"X\"\n ? options[1]\n : null;\n const awayOption =\n options[2] && options[2].isDisplayed\n ? options[2]\n : options[1] && options[1].name.text !== \"X\"\n ? options[1]\n : null;\n\n if (homeOption && awayOption && tieOption) {\n const homePrice = homeOption?.price?.usOdds;\n const awayPrice = awayOption?.price?.usOdds;\n const tiePrice = tieOption?.price?.usOdds;\n\n data = {\n homePrice: homePrice\n ? homePrice < 0\n ? `${homePrice}`\n : `+${homePrice}`\n : \"0\",\n tiePrice: tiePrice\n ? tiePrice < 0\n ? `${tiePrice}`\n : `+${tiePrice}`\n : \"0\",\n awayPrice: awayPrice\n ? awayPrice < 0\n ? `${awayPrice}`\n : `+${awayPrice}`\n : \"0\",\n overPrice: \"0\",\n underPrice: \"0\",\n };\n }\n }\n\n if (overUnderMarket && overUnderOptions.length) {\n const properties = [\"0,5\", \"1,5\", \"2,5\", \"3,5\", \"4,5\", \"5,5\"];\n\n const overOption = overUnderOptions?.find(\n (option) =>\n option?.name?.text?.includes(\"Over\") && option?.isDisplayed === true,\n );\n const underOption = overUnderOptions?.find(\n (option) =>\n option?.name?.text?.includes(\"Under\") && option?.isDisplayed === true,\n );\n const property = properties?.find(\n (prop) =>\n overOption?.name?.text?.includes(prop) ||\n underOption?.name?.text?.includes(prop),\n );\n\n if (overOption && underOption) {\n const overPrice = overOption?.price?.usOdds;\n const underPrice = underOption?.price?.usOdds;\n\n data.overPrice = overPrice\n ? overPrice < 0\n ? `${overPrice}`\n : `+${overPrice}`\n : \"0\";\n data.underPrice = underPrice\n ? underPrice < 0\n ? `${underPrice}`\n : `+${underPrice}`\n : \"0\";\n data.totalGoals = property?.replace(\",\", \".\");\n }\n }\n\n return data;\n};\n\nexport const getPhaseTypeFromSlug = (competitions, competitionSlug) => {\n return competitions?.find((comp) => comp?.slug === competitionSlug)\n ?.mlsPhaseType;\n};\n\nexport function isPromoLinkValid(callToAction = {}) {\n if (callToAction?.url && callToAction?.displayText) {\n return true;\n }\n\n return false;\n}\n\nexport function isMatchPromoValid(matchPromo = {}) {\n return (\n matchPromo.headline ||\n matchPromo.description ||\n isPromoLinkValid(matchPromo.callToAction1) ||\n isPromoLinkValid(matchPromo.callToAction2)\n );\n}\n\nexport function slugifyMatch(str) {\n if (!str) {\n return \"\";\n }\n\n const slug = str.toLowerCase().split(\" \").join(\"_\");\n\n return \"match_\" + slug;\n}\n\n// mls\nexport function mergeMlsAndD3Matches({ mlsMatches, d3Matches }) {\n const d3MatchesList = new Map(d3Matches?.map(match => [match?.sportecId, match]));\n\n\n\n return mlsMatches?.map(match => {\n const d3Match = d3MatchesList.get(match?.match_id);\n return { ...match, ...d3Match };\n });\n}\n\nexport function composeForgeClubs(clubs = []) {\n const allClubsOption = {\n slug: null,\n name: filterTypes.allClubs,\n shortName: filterTypes.allClubs,\n sportecId: filterTypes.all.toLowerCase(),\n abbreviation: filterTypes.allClubs,\n backgroundColor: null,\n logoBWSlug: null,\n logoColorSlug: null,\n logoColorUrl: null,\n crestColorSlug: null,\n };\n\n const clubsList = clubs?.map(club => {\n return {\n slug: club?.slug,\n name: club?.fields?.name,\n shortName: club?.fields?.shortName,\n sportecId: club?.fields?.sportecId,\n abbreviation: club?.fields?.abbreviation,\n backgroundColor: club?.fields?.backgroundColor,\n logoBWSlug: club?.fields?.logoBWSlug,\n logoColorSlug: club?.fields?.logoColorSlug,\n logoColorUrl: club?.fields?.logoColorUrl,\n crestColorSlug: club?.fields?.crestColorSlug,\n };\n });\n\n return [allClubsOption, ...clubsList];\n}\n\nexport function isAllOptionSelected(value) {\n return value?.toLowerCase()?.includes(\"all\");\n}\n\nexport function composeAllOption(value) {\n if (isAllOptionSelected(value)) {\n return filterTypes.all?.toLowerCase();\n }\n\n return value;\n}\n\n\nexport function filterMlsMatchesByCompetitionsToSkip(mlsMatches) {\n const competitionsToSkip = getCompetitionsToSkip();\n\n return mlsMatches?.filter(match => {\n if (competitionsToSkip?.includes(match?.competition_id)) {\n return false;\n }\n\n return true;\n });\n}\n\n\nexport function getCompetitionsToSkip() {\n const { mlsCompetitionsToSkip } = window?.forgeVariables?.match || {};\n\n if (!mlsCompetitionsToSkip) {\n return [];\n }\n\n return mlsCompetitionsToSkip?.split(\",\");\n}\n\nexport function getWhiteListCompetitions(competitions) {\n const competitionsToSkip = getCompetitionsToSkip();\n\n return competitions?.filter(competition => !competitionsToSkip?.includes(competition?.competition_id));\n}\n\nexport function getDefaultMlsCompetitionId() {\n const { mlsDefaultCompetitionId = \"\" } = window?.forgeVariables?.match || {};\n\n\n return mlsDefaultCompetitionId;\n}\n\nexport function getCurrentDatePoint(date) {\n const currentDatePoint = isDate(date) ? date : new Date(date);\n\n return currentDatePoint;\n}\n\nexport function getFirstDateOfYear(date = new Date()?.getFullYear()) {\n const initialDate = startOfYear(new Date(date, 0));\n return initialDate;\n}\n\nexport function getLastDateOfYear(date = new Date()?.getFullYear()) {\n const lastDate = endOfYear(new Date(date, 0));\n return lastDate;\n}\n\n\nexport function getFirstDateOfMonth(date = new Date()) {\n const initialDate = startOfMonth(date);\n return initialDate;\n}\n\n\nexport function getLastDateOfMonth(date = new Date()) {\n const lastDate = endOfMonth(date);\n return lastDate;\n}\n\nexport function getNewCurrentDatePoint({ currentDatePoint, hashQueryObject, seasonFirstYear, seasonLastYear }) {\n const formattedCurrentDatePoint = format(new Date(currentDatePoint), \"yyyy-MM-dd\");\n let newCurrentDatePoint = formattedCurrentDatePoint === hashQueryObject?.date ? currentDatePoint\n : new Date(hashQueryObject.date || currentDatePoint);\n\n if (isBefore(newCurrentDatePoint, seasonFirstYear) || isAfter(newCurrentDatePoint, seasonLastYear)) {\n newCurrentDatePoint = new Date();\n }\n\n return newCurrentDatePoint;\n}\n\n\n\n\n","import { removeLeadingSlash, removeTrailingSlash } from \"../utils\";\n\nasync function fetchClient({ endpoint, data, apiURL, token, headers: customHeaders, ...customConfig }) {\n const config = {\n method: data ? 'POST' : 'GET',\n body: data ? JSON.stringify(data) : undefined,\n headers: {\n Authorization: token ? `Bearer ${token}` : undefined,\n 'Content-Type': data ? 'application/json' : undefined,\n ...customHeaders,\n },\n ...customConfig,\n };\n\n const url = `${apiURL ? `${removeTrailingSlash(apiURL)}/` : \"\"}${endpoint ? removeLeadingSlash(endpoint) : \"\"}`;\n\n return window.fetch(url, config).then(async response => {\n const data = await response.json();\n if (response.ok) {\n return data;\n } else {\n return Promise.reject(data);\n }\n }).catch(error => {\n throw new Error(`${apiURL ? apiURL : ''}${endpoint ? `/${endpoint}` : ''}: ${JSON.stringify(error)}`);\n });\n}\n\nasync function fetchClientHtml({ endpoint, data, apiURL, token, headers: customHeaders, ...customConfig }) {\n const config = {\n method: data ? 'POST' : 'GET',\n body: data ? data : undefined,\n headers: {\n Authorization: token ? `Bearer ${token}` : undefined,\n 'Content-Type': data ? 'text/html' : undefined,\n ...customHeaders,\n },\n ...customConfig,\n };\n\n const url = `${apiURL ? `${apiURL}/` : \"\"}${endpoint ? endpoint : \"\"}`;\n\n return window.fetch(url, config).then(async res => {\n const data = await res.text();\n if (res.ok) {\n return data;\n } else {\n return Promise.reject(data);\n }\n }).catch(error => {\n throw new Error(`${apiURL}/${endpoint}: ${error}`);\n });\n}\n\nconst apiTypes = {\n statsAPI: \"statsAPI\",\n d3SportsAPI: \"d3SportsAPI\",\n forgeDAPI: \"forgeDAPI\"\n};\n\nexport { fetchClient, fetchClientHtml, apiTypes };\n","import { replaceAmpersand, splitAndTrimStr } from \"../../../libraries/_helpers\";\nimport { statsApiHash, cardTypes, filterTypes, mlsPhaseTypes, playerStatsPositionTypes } from \"../utils\";\nimport { apiTypes } from \"./fetching\";\nimport { formatISO } from \"date-fns\";\nimport dayjs from 'dayjs';\nimport { matchTypes } from \"../../mls-match-list/utils\";\n\nexport const token = window?.forgeVariables?.apiList?.statsAPIToken || null;\nexport const culture = window?.forgeVariables?.currentSite?.culture?.toLowerCase() || \"en-us\";\n\nexport const getDefaultCompetitionSportecId = () => window?.forgeVariables?.match?.mlsDefaultCompetitionId || null;\n\nexport const composeForgeVariables = () => {\n const {\n fullGameTags,\n condensedGameTags,\n gameHighlightsTags\n } = window?.forgeVariables?.videoTags || {};\n\n const composedFullGame = fullGameTags != null ? splitAndTrimStr(fullGameTags) : null;\n const composedCondensedGame = condensedGameTags != null ? splitAndTrimStr(condensedGameTags) : null;\n const composedGameHighlights = gameHighlightsTags != null ? splitAndTrimStr(gameHighlightsTags) : null;\n\n return {\n apiList: {\n statsAPIToken: window?.forgeVariables?.apiList?.statsAPIToken,\n forgeDAPI: window?.forgeVariables?.apiList?.forgeDAPI,\n d3SportsAPI: window?.forgeVariables?.apiList?.d3SportsAPI,\n statsAPI: window?.forgeVariables?.apiList?.statsAPI\n },\n directoryList: {\n matchHubDir: window?.forgeVariables?.directoryList?.matchHubDir || \"competitions\",\n playerStatsDir: window?.forgeVariables?.directoryList?.playerStatsDir || \"stats/players\",\n clubStatsDir: window?.forgeVariables?.directoryList?.clubStatsDir || \"stats/clubs\",\n scheduleDir: window?.forgeVariables?.directoryList?.scheduleDir || \"schedule\",\n storiesDir: window?.forgeVariables?.directoryList?.storiesDir || \"news\",\n visualStoriesDir: window?.forgeVariables?.directoryList?.visualStoriesDir || \"visual-stories\",\n },\n match: window?.forgeVariables?.match,\n urlList: {\n defaultAdUrl: replaceAmpersand(window?.forgeVariables?.urlList?.defaultAdUrl),\n venueBgUrl: window?.forgeVariables?.urlList.venueBgUrl,\n baseUrl: window?.forgeVariables?.urlList?.baseUrl || \"\",\n imageBaseUrl: window?.forgeVariables?.urlList?.imageBaseUrl || \"https://images.mlssoccer.com\",\n ticketMasterPostMatchUrl: replaceAmpersand(window?.forgeVariables?.urlList?.ticketMasterPostMatchUrl),\n calendarUrl: window?.forgeVariables?.urlList?.calendarUrl || \"\",\n remindMeUrl: window?.forgeVariables?.urlList?.remindMeUrl || \"\",\n },\n videoTags: {\n fullGameTags: composedFullGame,\n condensedGameTags: composedCondensedGame,\n gameHighlightsTags: composedGameHighlights\n },\n isLeague: forgeVariableToBool(window?.forgeVariables?.currentSite?.isLeague),\n isClub: forgeVariableToBool(window?.forgeVariables?.currentSite?.isClub),\n clubOptaId: window?.forgeVariables?.currentSite?.clubOptaId,\n clubSportecId: window?.forgeVariables?.currentSite?.clubSportecId,\n brackets: {\n ThirdPlaceMatchTitle: window?.forgeVariables?.brackets?.ThirdPlaceMatchTitle\n },\n betMgmUrl: window?.forgeVariables?.currentSite?.betMgmUrl,\n freemiumPopupImageUrl: window?.forgeVariables?.currentSite?.freemiumPopupImageUrl || \"\"\n };\n};\n\nexport const urlList = window?.forgeVariables?.urlList || \"\";\n\nexport const forgeVariableToBool = (forgeVariable) => {\n if (!forgeVariable) {\n return false;\n }\n\n return forgeVariable?.toLowerCase() === \"true\";\n};\n\nexport const apiURL = {\n statsAPI: window?.forgeVariables?.apiList?.statsAPI\n ? window.forgeVariables.apiList.statsAPI\n : \"https://stats-api.mlsdigital.net/v1\",\n forgeDAPI: window?.forgeVariables?.apiList?.forgeDAPI\n ? window.forgeVariables.apiList.forgeDAPI\n : \"https://forge-dapipublic.mls-dev.deltatre.digital/v1\",\n d3SportsAPI: window?.forgeVariables?.apiList?.d3SportsAPI\n ? window.forgeVariables.apiList.d3SportsAPI\n : \"https://host-public-sportdataapi.mls-dev.deltatre.digital/api\",\n forgeDAPIv1: window?.forgeVariables?.apiList?.forgeDAPIv1\n ? window.forgeVariables.apiList.forgeDAPIv1\n : \"https://forge-dapipublic.mls-dev.deltatre.digital/v1\",\n leagueForgeDAPIv1: window?.forgeVariables?.apiList?.leagueForgeDAPIv1\n ? window.forgeVariables.apiList.leagueForgeDAPIv1\n : \"https://forge-dapipublic.mls-dev.deltatre.digital/v1\",\n};\n\nexport const addDays = function (str, days) {\n const date = dayjs(str).toDate();\n date.setDate(date.getDate() + parseInt(days));\n return formatISO(date, { representation: 'date' });\n};\n\nexport const subDays = function (str, days) {\n const date = dayjs(str).toDate();\n date.setDate(date.getDate() - parseInt(days));\n return formatISO(date, { representation: 'date' });\n};\n\n// SportsAPI\nexport const d3DateRangeAPI = ({ isoStringRS, isoStringRE, competitionOptaId = filterTypes.allCompetitions, matchType, clubOptaId, excludeSecondaryTeams = false, extendDays = false }) => {\n if (!isoStringRS || !isoStringRE) {\n return null;\n }\n\n const rs = extendDays ? subDays(isoStringRS, 1) : isoStringRS;\n const re = extendDays ? addDays(isoStringRE, 1) : isoStringRE;\n\n return `matches?` +\n `culture=en-us` +\n `&dateFrom=${rs}` +\n `&dateTo=${re}` +\n `${composeCompetitionOptaIdQueryString(competitionOptaId, apiTypes.d3SportsAPI)}` +\n `${composeMatchType(matchType, competitionOptaId)}` +\n `${!isNaN(clubOptaId) ? \"&clubOptaId=\" + clubOptaId : \"\"}` +\n `${excludeSecondaryTeams ? \"&excludeSecondaryTeams=true\" : \"\"}`;\n};\n\nexport const d3DateRangeScoreboardAPI = ({ isoStringRS, isoStringRE, competitionOptaId = filterTypes.allCompetitions, matchType, clubOptaId, excludeSecondaryTeams = false, extendDays = false, excludeVenue = false, matchDay = null, roundNumber = null, seasonOptaId = null }) => {\n\n const rs = isoStringRS ? (extendDays ? subDays(isoStringRS, 1) : isoStringRS) : null;\n const re = isoStringRE ? (extendDays ? addDays(isoStringRE, 1) : isoStringRE) : null;\n\n return `matches?` +\n `culture=en-us` +\n `${rs ? `&dateFrom=${rs}` : \"\"}` +\n `${re ? `&dateTo=${re}` : \"\"}` +\n `&excludeVenue=${excludeVenue}` +\n `${matchDay ? `&matchDay=${matchDay}` : \"\"}` +\n `${roundNumber ? `&roundNumber=${roundNumber}` : \"\"}` +\n `${composeCompetitionOptaIdQueryString(competitionOptaId, apiTypes.d3SportsAPI)}` +\n `${composeMatchType(matchType, competitionOptaId)}` +\n `${clubOptaId ? \"&clubOptaId=\" + clubOptaId : \"\"}` +\n `${seasonOptaId ? \"&seasonOptaId=\" + seasonOptaId : \"\"}` +\n `${excludeSecondaryTeams ? \"&excludeSecondaryTeams=true\" : \"\"}`;\n};\n\nexport const d3BettingAPI = ({ mgmId, mgmCompetitionId }) => {\n if (!mgmId) {\n return null;\n }\n\n return `betting/${mgmId}?` +\n `culture=${culture}` +\n (mgmCompetitionId ? `&betMGMcompetitionIds=${mgmCompetitionId}` : \"\");\n};\n\nexport const d3ClubsBySportecIdsAPI = ({ clubSportecIds = [] }) => {\n if (!clubSportecIds?.length) {\n return null;\n }\n\n return `clubs/bySportecIds/${clubSportecIds.join(\",\")}`;\n};\n\nexport const d3ClubBySportecIdAPI = ({ clubSportecId }) => {\n if (!clubSportecId) {\n return null;\n }\n\n return `clubs/bySportecId/${clubSportecId}`;\n};\n\nexport const d3ClubsAPI = ({ competitionOptaId, season }) => {\n if (!competitionOptaId || !season) {\n return null;\n }\n\n return `clubs/${season}/${competitionOptaId}?culture=en-us`;\n};\n\nexport const d3StandingsAPI = ({ competitionSportecId, season, isLive = false }) => {\n if (!season || !competitionSportecId) {\n return null;\n }\n\n return `standings/live?isLive=${isLive}&${season ? `seasonId=${season}` : \"\"}${competitionSportecId ? `&competitionId=${competitionSportecId}` : \"\"}`;\n};\n\nexport const d3FormGuideAPI = ({ competitionOptaId, season }) => {\n let matchType = \"\";\n\n if (!season && !competitionOptaId) {\n return null;\n }\n\n if (competitionOptaId == \"98\") {\n matchType = `/?matchType=${matchTypes.Regular}`;\n }\n\n return `formguide/${competitionOptaId}/${season}${matchType}`;\n};\n\nexport const d3FormGuidePageAPI = ({ path, season }) => {\n if (!season && !path) {\n return null;\n }\n\n return `${path}/${season}`;\n};\n\nexport const d3MatchesLiteAPI = ({ year, competitionOptaId = filterTypes.allCompetitions, clubAbbreviation, clubOptaId, matchType }) => {\n if (!year) {\n return null;\n }\n\n return `matchesLite/${year}?` +\n `culture=${culture}` +\n `${composeCompetitionOptaIdQueryString(competitionOptaId, apiTypes.d3SportsAPI)}` +\n `${composeClubOptaIdQuery(clubOptaId, apiTypes.d3SportsAPI)}` +\n `${composeClubQuery(clubAbbreviation, apiTypes.d3SportsAPI)}` +\n `${composeMatchType(matchType, competitionOptaId)}`;\n};\n\nexport const d3NextMatchAPI = ({ startDate, competitionOptaId, clubOptaId, matchType }) => {\n return `nextMatches?startDate=${startDate}` +\n `&culture=${culture}` +\n `${composeCompetitionOptaIdQueryString(competitionOptaId, apiTypes.d3SportsAPI)}` +\n `${composeClubOptaIdQuery(clubOptaId, apiTypes.d3SportsAPI)}` +\n `${composeMatchType(matchType, competitionOptaId)}`;\n};\n\nexport const d3MatchesAPI = () => {\n return `matches?culture=en-us`;\n};\n\nexport const d3SingleMatchAPI = ({ matchSportecId, competitionOptaId }) => {\n if (!matchSportecId) {\n return null;\n }\n\n return `matches/${matchSportecId}?${competitionOptaId ? `competition=${competitionOptaId}` : \"\"}`;\n};\n\nexport const d3PlayerAPI = ({ matchSportecId }) => {\n if (!matchSportecId) {\n return null;\n }\n\n return `players/byMatch/${matchSportecId}?culture=${culture}`;\n};\n\nexport const d3PlayerByIdsAPI = ({ playerIds }) => {\n if (!playerIds?.length) {\n return null;\n }\n\n const joinedIds = playerIds.join(\",\");\n\n return `/players/byPlayerIds/${joinedIds}?culture=${culture}`;\n};\n\nexport const d3PlayerBySportecIdAPI = ({ sportecId, culture = \"en-us\" }) => {\n if (!sportecId) {\n return null;\n }\n\n return `players/nocache/${sportecId}?culture=${culture}`;\n};\n\nexport const d3AggregateAPI = ({ matchOptaId }) => {\n if (!matchOptaId) {\n return null;\n }\n\n return `aggregate/${matchOptaId}?culture=${culture}`;\n};\n\nexport const d3BracketsAPI = ({ slug }) => {\n if (!slug) {\n return null;\n }\n\n return `brackets/${slug}?culture=${culture}`;\n};\n\nexport const d3CompetitionAPI = ({ optaID, matchType }) => {\n if (!optaID) {\n return null;\n }\n\n return `content/en-us/competitions?fields.optaId=${optaID}&fields.mlsPhaseType=${matchType}`;\n};\n\nexport const d3PlayersByClubAPI = ({ clubOptaId }) => {\n if (!clubOptaId) {\n return null;\n }\n\n return `players/byClub/${clubOptaId}?culture=en-us`;\n};\n\nexport const d3PreviousMatchesAPI = ({ homeOptaId, awayOptaId, previousMatchesCount = 3, matchDate, formGuideMatchesCount = 5 }) => {\n if (!homeOptaId) {\n return null;\n }\n\n return `previousMatches/${homeOptaId}?culture=en-us${awayOptaId ? `&secondClub=${awayOptaId}` : \"\"}${matchDate ? `&matchDate=${matchDate}` : \"\"}&maxItems=${previousMatchesCount}${formGuideMatchesCount ? `&formGuideMatchesCount=${formGuideMatchesCount}` : \"\"}`;\n};\n\nexport const d3TeamsBySportecIdsAPI = ({ teamSportecIds = [] }) => {\n if (!teamSportecIds?.length) {\n return null;\n }\n\n return `clubs/bySportecIds/${teamSportecIds.join(\",\")}`;\n};\n\nexport const d3MatchesBySportecIdsAPI = ({ matchSportecIds = [] }) => {\n if (!matchSportecIds?.length) {\n return null;\n }\n\n return `matches/bySportecIds/${matchSportecIds.join(\",\")}`;\n};\n\n\n// StatsAPI\nexport const mlsStatisticsAPI = ({ competitionSportecId, seasonSportecId, perPage = 100 }) => {\n if (!competitionSportecId || !seasonSportecId) {\n return null;\n }\n\n return `statistics/clubs/competitions/${competitionSportecId}/seasons/${seasonSportecId}?per_page=${perPage}`;\n};\n\nexport const d3PlayerStatsAPI = ({ competitionSportecId, page = 1, seasonSportecId, sortColumn, sortOrder, pageSize = 100, clubSportecId }) => {\n if (!competitionSportecId || !seasonSportecId) {\n return null;\n }\n\n const params = [\n clubSportecId ? `clubId=${clubSportecId}` : null,\n pageSize ? `pageSize=${pageSize}` : null,\n page ? `page=${page}` : null,\n ].filter(Boolean);\n\n return `stats/players/competition/${competitionSportecId}/season/${seasonSportecId}/order/${sortColumn}/${sortOrder}?${params.join(\"&\")}`\n};\n\nexport const mlsPlayerMatchLogStatsAPI = ({\n route = 'matches',\n playerOptaId,\n pageParam = 0,\n pageSize = 30,\n desc = false,\n orderBy = \"date\",\n competition = \"all\"\n}) => {\n let orderQuery;\n let competitionQuery = \"\";\n\n if (orderBy === \"date\") {\n orderQuery = \"match_date\";\n } else {\n orderQuery = `player_match_stat_${orderBy}`;\n }\n\n if (competition && competition !== \"all\") {\n competitionQuery = `&competition_opta_id=${competition}`;\n }\n\n if (!playerOptaId) {\n return null;\n }\n\n return `players/${route}?${composeToken(\n token\n )}&player_opta_id=${playerOptaId}&page=${pageParam}&page_size=${pageSize}&include=competition&include=statistics&include=match&include=club&include=club_match&include=opponent_club&include=opponent_club_match&order_by=${desc ? \"-\" : \"\"\n }${orderQuery}${competitionQuery}`;\n};\n\nexport const mlsPlayerMatchLogStatsAPIv2 = ({playerId, competitionId, page_token}) => {\n const url = `statistics/players/${playerId}/matches`;\n const searchParams = new URLSearchParams();\n\n if (competitionId && competitionId !== 'all') {\n searchParams.set('competition_id', competitionId);\n }\n if (page_token) {\n searchParams.set('page_token', page_token);\n }\n if (searchParams.toString()) {\n return `${url}?${searchParams.toString()}`\n }\n return url;\n}\n\nexport const mlsGetMatches = ({ seasonSportecId, from, to, competitionSportecId, clubSportecId, sort, perPage = 100 }) => {\n let params = [\n from ? `match_date[gte]=${from}` : null,\n to ? `match_date[lte]=${to}` : null,\n competitionSportecId ? `competition_id=${competitionSportecId}` : null,\n clubSportecId ? `team_id=${clubSportecId}` : null,\n perPage ? `per_page=${perPage}` : null,\n sort ? `sort=${sort}` : null,\n ].filter(Boolean);\n\n\n return `matches/seasons/${seasonSportecId}?${params.join(\"&\")}`\n}\n\nexport const mlsCompetitionsAPI = () => {\n return `competitions`;\n}\n\nexport const mlsSeasonsAPI = ({ competitionSportecId }) => {\n if (!competitionSportecId) {\n return null;\n }\n\n return `competitions/${competitionSportecId}/seasons`;\n}\n\nexport const mlsStandingsAPI = ({ competitionSportecId, seasonSportecId, category, type, isLive }) => {\n if (!competitionSportecId || !seasonSportecId) {\n return null;\n }\n\n const filters = [\n category ? `category=${category}` : null,\n type ? `type=${type}` : null,\n isLive ? `is_live=${isLive}` : null,\n ].filter(Boolean);\n\n return `competitions/${competitionSportecId}/seasons/${seasonSportecId}/standings?${filters.join(\"&\")}`;\n}\n\nexport const mlsStatsComparisonAPI = ({ matchOptaId }) => {\n if (!matchOptaId) {\n return null;\n }\n\n return `clubs/matches?` +\n `${composeToken(token)}` +\n `${composeMatchOptaId(matchOptaId)}` +\n `&include=club&include=match&include=competition&include=statistics`;\n};\n\nexport const mlsStatsStandingsAPI = ({ seasonSportecId, competitionSportecId, clubSportecIds = [] }) => {\n if (!seasonSportecId && !competitionSportecId) {\n return null;\n }\n\n return `standings?` +\n `${composeToken(token)}` +\n `${composeSeasonQueryString(seasonSportecId)}` +\n `${composeCompetitionOptaIdQueryString(competitionSportecId)}` +\n `${composeMultipleClubOptaIdQuery(clubSportecIds)}` +\n \"&include=club\";\n};\n\nexport const mlsClubMatchAPI = ({ matchOptaId }) => {\n if (!matchOptaId) {\n return null;\n }\n\n return `clubs/matches?` +\n `${composeToken(token)}` +\n `${composeMatchOptaId(matchOptaId)}`;\n};\n\nexport const mlsClubMatchPossessionAPI = ({ matchOptaId }) => {\n if (!matchOptaId) {\n return null;\n }\n\n return `clubs/matches/possessions?` +\n `${composeToken(token)}` +\n `${composeMatchOptaId(matchOptaId)}`;\n};\n\nexport const mlsSeasonStatsComparisonAPI = ({ homeOptaId, awayOptaId, season, competitionOptaId, }) => {\n if (!homeOptaId || !awayOptaId || !season || !competitionOptaId) {\n return null;\n }\n\n return `clubs/seasons?` +\n `${composeToken(token)}` +\n `&include=club&include=statistics&club_opta_id=${homeOptaId}` +\n `&club_opta_id=${awayOptaId}` +\n `&season_opta_id=${season}` +\n `&competition_opta_id=${competitionOptaId}`;\n};\n\nexport const mlsPossessionIntervalsAPI = ({ matchOptaId }) => {\n if (!matchOptaId) {\n return null;\n }\n\n return `matches/possessions?` +\n `${composeToken(token)}` +\n `${composeMatchOptaId(matchOptaId)}` +\n `&match_possession_duration=5&match_possession_category=Territorial&match_possession_type=IntervalLengths`;\n};\n\nexport const mlsPossessionOverallAPI = ({ matchOptaId }) => {\n if (!matchOptaId) {\n return null;\n }\n\n return `matches/possessions?` +\n `${composeToken(token)}` +\n `${composeMatchOptaId(matchOptaId)}` +\n `&match_possession_category=Territorial&match_possession_type=Overall`;\n};\n\nexport const mlsMatchOfficialsAPI = ({ matchOptaId }) => {\n if (!matchOptaId) {\n return null;\n }\n\n return `officials/matches?` +\n `${composeToken(token)}` +\n `${composeMatchOptaId(matchOptaId)}` +\n `&include=official`;\n};\n\nexport const mlsMatchCommentariesAPI = ({ matchSportecId, page_token, perPage = 25 }) => {\n if (!matchSportecId) {\n return null;\n }\n\n return `matches/${matchSportecId}/commentary?${page_token ? `page_token=${page_token}` : \"\"}`\n};\n\n/**\n * [Description of your function]\n *\n * @param {string} matchSportecId - The sportec ID of the match\n * @param {string} pageSize - The number of key events to fetch\n * @returns {string} - The endpoint to fetch the key events\n */\nexport const mlsMatchKeyEventsAPI = ({ matchSportecId, pageSize }) => {\n if (!matchSportecId) {\n return null;\n }\n\n return `matches/${matchSportecId}/key_events${pageSize ? `?per_page=${pageSize}` : \"\"}`\n};\n\nexport const mlsPenaltyKicksAPI = ({ matchOptaId }) => {\n if (!matchOptaId) {\n return null;\n }\n\n return `penaltykicks?` +\n `${composeToken(token)}` +\n `${composeMatchOptaId(matchOptaId)}` +\n `&include=club&include=player&order_by=match_opta_id`;\n};\n\nexport const mlsBookingsAPI = ({ matchOptaId }) => {\n if (!matchOptaId) {\n return null;\n }\n\n return `bookings?` +\n `${composeToken(token)}` +\n `${composeMatchOptaId(matchOptaId)}` +\n `&include=player`;\n};\n\nexport const mlsPlayersMatchAPI = ({ matchOptaId }) => {\n if (!matchOptaId) {\n return null;\n }\n\n return `players/matches?` +\n `${composeToken(token)}` +\n `${composeMatchOptaId(matchOptaId)}` +\n `&include=player&include=club`;\n};\n\nexport const mlsPlayerAPI = ({ playerOptaId }) => {\n if (!playerOptaId) {\n return null;\n }\n\n return `players/${playerOptaId}`;\n};\n\nexport const mlsSubstitutionsAPI = ({ matchSportecId, eventType }) => {\n if (!matchSportecId) {\n return null;\n }\n\n return `matches/${matchSportecId}/key_events${eventType ? `?event=${eventType}` : \"\"}`\n};\n\nexport const mlsManagersAPI = ({ matchOptaId }) => {\n if (!matchOptaId) {\n return null;\n }\n\n return `managers/matches?` +\n `${composeToken(token)}` +\n `${composeMatchOptaId(matchOptaId)}` +\n `&include=manager&include=club`;\n};\n\nexport const mlsNeedToKnowAPI = ({ matchOptaId }) => {\n if (!matchOptaId) {\n return null;\n }\n\n return `matchfacts?` +\n `${composeToken(token)}` +\n `&matchfact_language=en` +\n `${composeMatchOptaId(matchOptaId)}`;\n};\n\nexport const mlsSingleMatchStatsAPI = ({ matchSportecId }) => {\n if (!matchSportecId) {\n return null;\n }\n\n return `/matches/${matchSportecId}`\n};\n\nexport const mlsMatchesStatsAPI = ({ matchesOptaIds }) => {\n if (!matchesOptaIds) {\n return null;\n }\n\n return `matches?` +\n `${composeToken(token)}` +\n `${composeMatchesOptaIds(matchesOptaIds)}` +\n `&include=away_club_match&include=home_club_match&include=venue&include=home_club&include=away_club`;\n};\n\n\nexport const mlsClubsAPI = ({ competitionSportecId, seasonSportecId }) => {\n if (!competitionSportecId || !seasonSportecId) {\n return null;\n }\n return `clubs/competitions/${competitionSportecId}/seasons/${seasonSportecId}`;\n};\n\nexport const mlsGoalsAPI = ({ matchOptaId, includeClub = true, includePlayer = false, includeAssists = false }) => {\n if (!matchOptaId) {\n return null;\n }\n\n return `goals?` +\n `${composeToken(token)}` +\n `${composeMatchOptaId(matchOptaId)}` +\n `&order_by=goal_minute${includeClub ? \"&include=club\" : \"\"}` +\n `${includePlayer ? \"&include=player\" : \"\"}` +\n `${includeAssists ? \"&include=first_assist_player&include=second_assist_player\" : \"\"}`;\n};\n\nexport const mlsPlayerCareerStatsAPI = ({\n route = 'seasons',\n filterType,\n playerOptaId,\n desc = false,\n competitionId = \"98\",\n orderBy = \"date\"\n}) => {\n if (!playerOptaId || !filterType) {\n return null;\n }\n\n let orderQuery;\n\n if (orderBy === \"date\") {\n orderQuery = \"season_opta_id\";\n } else {\n orderQuery = `player_season_stat_${orderBy}`;\n }\n\n switch (filterType) {\n case \"MLS Regular Season\":\n return `players/${route}?${composeToken(token)}&player_opta_id=${playerOptaId}&include=season&include=regular_season_statistics&include=club&competition_opta_id=98&order_by=${desc ? \"-\" : \"\"}${orderBy === \"date\" ? orderQuery : \"regular_season_\" + orderQuery}`;\n case \"MLS Post Season\":\n return `players/${route}?${composeToken(token)}&player_opta_id=${playerOptaId}&include=season&include=postseason_statistics&include=club&competition_opta_id=98&order_by=${desc ? \"-\" : \"\"}${orderBy === \"date\" ? orderQuery : \"postseason_\" + orderQuery}`;\n case \"Custom Competition\":\n return `players/${route}?${composeToken(token)}&player_opta_id=${playerOptaId}&include=season&include=statistics&include=club&competition_opta_id=${competitionId}&order_by=${desc ? \"-\" : \"\"}${orderQuery}`;\n default:\n return null;\n }\n};\n\nexport const mlsClubStatsAPI = ({ competitionSportecId, seasonSportecId }) => {\n if (!competitionSportecId || !seasonSportecId) {\n return null;\n }\n\n return `statistics/clubs/competitions/${competitionSportecId}/seasons/${seasonSportecId}`;\n};\n\n// Forge DAPI\nexport const dapiMatchAPI = ({ matchSlug }) => {\n if (!matchSlug) {\n return null;\n }\n\n return `content/en-us/matches/${matchSlug}`;\n};\n\nexport const dapiClubPlayersAPI = ({ clubSportecId, culture = \"en-us\", perPage = 100 }) => {\n if (!clubSportecId) {\n return null;\n }\n\n return `content/${culture}/players?fields.clubSportecId=${clubSportecId}&fields.isActiveMLSPlayer=true&$skip=0&$limit=${perPage}`;\n}\n\nexport const dapiSeasonAPI = ({ competitionSportecId, sportecId, culture = \"en-us\" }) => {\n if (!competitionSportecId || !sportecId) {\n return null;\n }\n\n return `content/${culture}/seasons?fields.competitionSportecId=${competitionSportecId}&fields.sportecId=${sportecId}`;\n}\n\nexport const dapiSeasonContentAPI = ({ slug, culture = \"en-us\" }) => {\n if (!slug) {\n return null;\n }\n\n return `content/${culture}/seasons/${slug}`;\n}\n\nexport const forgeEditorialSelectionAPI = ({ slug }) => {\n if (slug == null) {\n return null;\n }\n\n return `content/${culture}/sel-${slug}`;\n};\n\nexport const forgeMatchVideosAPI = ({ matchSportecId }) => {\n if (!matchSportecId) {\n return null;\n }\n\n return `content/${culture}/brightcovevideos?fields.sportecMatchId=${matchSportecId}`;\n};\n\nexport const forgeMatchContentVideosAPI = ({ matchSlug }) => {\n if (!matchSlug) {\n return null;\n }\n\n return `content/${culture}/brightcovevideos?tags.slug=${matchSlug}`;\n};\n\nexport const forgeVisualStoriesAPI = ({ matchSlug }) => {\n if (!matchSlug) {\n return null;\n }\n\n return `content/${culture}/visualstories?tags.slug=${matchSlug}`;\n};\n\nexport const forgeMatchStoriesAPI = ({ matchSlug }) => {\n if (!matchSlug) {\n return null;\n }\n\n return `content/${culture}/stories?tags.slug=${matchSlug}`;\n};\n\nexport const forgeMatchRelatedVideosAPI = ({ matchOptaId }) => {\n if (!matchOptaId) {\n return null;\n }\n\n return `relatedVideos/${matchOptaId}?culture=${culture}`;\n};\n\nexport const forgeSeasonAPI = ({ seasonOptaId }) => `content/${culture}/seasons?fields.optaId=${seasonOptaId}`;\n\nexport const forgeSeasonAPILeague = ({ seasonOptaId }) => `content/en-us/seasons?fields.optaId=${seasonOptaId}`;\n\nexport const forgePlayerDAPI = ({ sportecId }) => {\n if (!sportecId) {\n return null;\n }\n\n return `content/en-us/players?fields.sportecId=${sportecId}`;\n};\n\nexport const forgeClubDAPI = ({ optaId }) => {\n if (!optaId) {\n return null;\n }\n\n return `content/en-us/clubs?fields.optaId=${optaId}`;\n};\n\nexport const forgeSuperDraftAPI = ({ superDraftSlug }) => `content/${culture}/superdraft/${superDraftSlug}`;\n\nexport const forgeSuperDraftPicksAPI = ({ superDraftSlugTag }) => {\n if (!superDraftSlugTag) return \"\";\n return `content/${culture}/superdraftpicks?tags.slug=${superDraftSlugTag}&$limit=100`;\n};\n\n//URL composing functions\nfunction composeSeasonQueryString(season) {\n return season ? `&season_opta_id=${season}` : '';\n}\n\nfunction composeCompetitionOptaIdQueryString(competitionOptaId, apiType = apiTypes.statsAPI) {\n return competitionOptaId && competitionOptaId !== filterTypes.allCompetitions ? `&${apiType === apiTypes.statsAPI ? \"competition_opta_id\" : \"competition\"}=${competitionOptaId}` : \"\";\n}\n\nfunction composeOrderByQueryString(statType, route = \"seasons\", desc, mlsPhaseType, type = \"player\", allYears = false) {\n const phasePrefix = mlsPhaseType === mlsPhaseTypes.regular\n ? `regular_season_`\n : mlsPhaseType === mlsPhaseTypes.cup\n ? `postseason_`\n : \"\";\n\n return statType\n ? (allYears ? `&order_by=${desc ? \"-\" : \"\"}${phasePrefix}${type}_stat_${statType}` : `&order_by=${desc ? \"-\" : \"\"}${phasePrefix}${type}_${route === 'seasons' ? 'season' : 'match'}_stat_${statType}`)\n : \"\";\n}\n\nfunction composeAppearancesQueryString(appearances, route) {\n return appearances && appearances !== filterTypes.all && route === 'seasons' ? `&player_season_stat_appearances[$eq]=${appearances}` : \"\";\n}\n\nfunction composePageQueryString(page) {\n return page ? `&page=${page}` : \"\";\n}\n\nfunction composePageSizeQueryString(pageSize) {\n return pageSize != null ? `&page_size=${pageSize}` : \"\";\n}\n\nfunction composePositionQuery(position, route) {\n if (!position || position && position === filterTypes.all) {\n return \"\";\n }\n\n if (position.toUpperCase() === \"OUTFIELD PLAYERS\") {\n return `&player_${route === 'seasons' ? 'season_position_generic' : 'match_position'}[$ne]=Goalkeeper`;\n }\n\n return `&player_${route === \"seasons\" ? \"season_position_generic\" : \"match_position\"}=${position}`;\n}\n\nfunction composeClubQuery(club, apiType = apiTypes.statsAPI) {\n return club != null && club !== filterTypes.allClubs ? `&${apiType === apiTypes.statsAPI ? \"club_abbreviation\" : \"clubAbbreviation\"}=${club}` : \"\";\n}\n\nfunction composeClubOptaIdQuery(clubOptaId, apiType = apiTypes.statsAPI) {\n return clubOptaId != null && clubOptaId !== filterTypes.allClubs ? `&${apiType === apiTypes.statsAPI ? \"club_opta_id\" : \"clubOptaId\"}=${clubOptaId}` : \"\";\n}\n\nfunction composeMultipleClubOptaIdQuery(clubOptaIds) {\n if (!clubOptaIds?.length) {\n return \"\";\n }\n\n return clubOptaIds.map((clubOptaId, i) => `&club_opta_id=${clubOptaId}`).join(\"\");\n}\n\nfunction composeRestOfCommentaries(includeRest) {\n return includeRest ? \"&commentary_type=lineup&commentary_type=start&commentary_type=end%201&commentary_type=end%202&commentary_type=end%203&commentary_type=end%204&commentary_type=end%205&commentary_type=end%2014&commentary_type=start%20delay&commentary_type=end%20delay&commentary_type=postponed&commentary_type=free%20kick%20lost&commentary_type=free%20kick%20won&commentary_type=attempt%20blocked&commentary_type=attempt%20saved&commentary_type=miss&commentary_type=post&commentary_type=corner&commentary_type=offside&commentary_type=penalty%20won&commentary_type=penalty%20lost&commentary_type=penalty%20miss&commentary_type=penalty%20saved&commentary_type=player%20retired&commentary_type=contentious%20referee%20decisions&commentary_type=VAR%20cancelled%20goal\" : \"\";\n}\n\nfunction composePhaseType(phase, competitionOptaId) {\n switch (phase) {\n case mlsPhaseTypes.regular:\n return `&include=regular_season_statistics`;\n case mlsPhaseTypes.cup:\n return `&include=postseason_statistics`;\n default:\n return `&include=statistics`;\n }\n}\n\nfunction composeRoute(route) {\n return route === 'matches' ? \"&include=match\" : '';\n}\n\nfunction composeMatchOptaId(matchOptaId) {\n return matchOptaId ? `&match_game_id=${matchOptaId}` : \"\";\n}\n\nfunction composeMatchesOptaIds(matchesOptaIds) {\n return matchesOptaIds?.length ? matchesOptaIds?.map((optaId) => \"&match_game_id=\" + optaId)?.join(\"\") : \"\";\n}\n\nfunction composeMatchType(matchType, competitionOptaId = \"98\") {\n return competitionOptaId !== \"98\" || matchType == null\n ? \"\"\n : `&matchType=${matchType}`;\n}\n\nfunction composeToken(statsAPIToken) {\n return statsAPIToken ? `token=${statsAPIToken}` : '';\n}\n","import { createContext, useContext } from \"react\";\n\nexport const ReactAppState = createContext();\nReactAppState.displayName = 'ReactMLS';\n\nexport function useReactAppState() {\n const context = useContext(ReactAppState);\n if (context === undefined) {\n throw new Error('useAppState must be used within a ');\n }\n return context;\n}\n","import { fetchClient } from \"./api/fetching\";\nimport { calculatePercentage, calculateSubtractedValues, calculateSum, round, decimalRound, getPercentageFromDecimal } from \"../../libraries/_helpers\";\nimport { apiURL, forgeClubDAPI, forgePlayerDAPI, culture } from \"./api/variables\";\nimport { enUS, fr, es } from 'date-fns/locale';\n\nexport const test = \"test\";\n\nexport const statsApiHash = {\n appearances: \"appearances\",\n games_started: 'game_started',\n games_played: \"games_played\",\n goals: \"goals\",\n minutes: \"mins_played\",\n expected_goals: \"expected_goals\",\n goal_assist: \"goal_assist\",\n assists: \"goal_assist\",\n expected_assists: \"expected_assists\",\n offsides: \"total_offside\",\n substitute_appearances: \"total_sub_on\",\n key_passes: \"total_att_assist\",\n won_tackles: \"won_tackle\",\n yellow_card: \"yellow_card\",\n successful_dribble: \"successful_dribble\",\n goals_inside_18: \"att_ibox_goal\",\n shots: \"total_scoring_att\",\n goals_outside_18: \"att_obox_goal\",\n penalty_kick_goals_for: \"att_pen_goal\",\n penalty_kick_attempts_for: \"att_pen_taken\",\n shots_on_target: \"ontarget_scoring_att\",\n passes_completed: \"total_pass\",\n passes_in_the_opposition_half: \"accurate_fwd_zone_pass\",\n passes_in_the_own_half: \"accurate_back_zone_pass\",\n short_passes: \"successful_short_pass\",\n penalty_kicks_against: 'penalty_faced',\n penalty_kicks_saved: \"penalty_save\",\n passing_percentage: \"accurate_pass_per\",\n interceptions: \"interception\",\n clean_sheets: \"clean_sheet\",\n expected_goals_against: \"expected_goals_conceded\",\n goals_against: \"goals_conceded\",\n successful_crosses: \"accurate_cross\",\n long_passes: \"accurate_long_balls\",\n headed_goals: \"att_hd_goal\",\n red_card: \"red_card\",\n total_red_card: \"total_red_card\",\n passes_attempted: \"total_pass\",\n corner_kicks: \"corner_taken\"\n};\n\nexport const statsApiPositionTypes = {\n GK: \"Goalkeeper\",\n LB: \"Left Back\",\n LCB: \"Left Centre Back\",\n CB: \"Centre Back\",\n RCB: \"Right Centre Back\",\n RB: \"Right Back\",\n WLDM: \"Wide-Left Defensive Midfielder\",\n LDM: \"Left Defensive Midfielder\",\n CDM: \"Central Defensive Midfielder\",\n RDM: \"Right Defensive Midfielder\",\n WRDM: \"Wide-Right Defensive Midfielder\",\n LM: \"Left Midfielder\",\n HLM: \"Half-Left Midfielder\",\n CM: \"Central Midfielder\",\n HRM: \"Half-Right Midfielder\",\n RM: \"Right Midfielder\",\n LAM: \"Left Attacking Midfielder\",\n HLAM: \"Half-Left Attacking Midfielder\",\n CAM: \"Central Attacking Midfielder\",\n HRAM: \"Half-Right Attacking Midfielder\",\n RAM: \"Right Attacking Midfielder\",\n SS: \"Supporting Striker\",\n LW: \"Left Wide Player\",\n LS: \"Left Striker\",\n CF: \"Centre Forward\",\n RS: \"Right Striker\",\n RW: \"Right Wide Player\"\n};\n\nexport const statsApiFormationMatrix = {\n \"3-1-4-2\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"CDM\"], [\"RM\", \"HRM\", \"HLM\", \"LM\"], [\"RS\", \"LS\"]],\n \"3-3-2-2\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"CDM\", \"WRDM\", \"HRM\"], [\"HLM\", \"WLDM\"], [\"RS\", \"LS\"]],\n \"3-3-2-2 Double-10\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"CDM\", \"RM\", \"HRAM\"], [\"HLAM\", \"LM\"], [\"RS\", \"LS\"]],\n \"3-3-3-1\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"RDM\", \"CDM\", \"LDM\"], [\"RAM\", \"CAM\", \"LAM\"], [\"CF\"]],\n \"3-4-1-2\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"RM\", \"RDM\", \"LDM\", \"LM\"], [\"CAM\"], [\"RS\", \"LS\"]],\n \"3-4-1-2 Defensive Midfielder\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"WRDM\", \"RDM\", \"LDM\", \"WLDM\"], [\"CAM\"], [\"RS\", \"LS\"]],\n \"3-4-2-1\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"RM\", \"RDM\", \"LDM\", \"LM\"], [\"RAM\", \"LAM\"], [\"CF\"]],\n \"3-4-2-1 Defensive Midfielder\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"WRDM\", \"RDM\", \"LDM\", \"WLDM\"], [\"RAM\", \"LAM\"], [\"CF\"]],\n \"3-4-2-1 Double-10\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"WRDM\", \"RDM\", \"LDM\", \"WLDM\"], [\"HRAM\", \"HLM\"], [\"CF\"]],\n \"3-4-3\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"RM\", \"RDM\", \"LDM\", \"LM\"], [\"RW\", \"CF\", \"LW\"]],\n \"3-4-3 Defensive Midfielder\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"WRDM\", \"RDM\", \"LDM\", \"WLDM\"], [\"RW\", \"CF\", \"LW\"]],\n \"3-4-3 Diamond\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"CDM\", \"RM\", \"LM\", \"CAM\"], [\"RW\", \"CF\", \"LW\"]],\n \"3-5-1-1\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"RM\", \"RDM\", \"CM\", \"LDM\", \"LM\"], [\"SS\"], [\"CF\"]],\n \"3-5-1-1 Defensive Outliner\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"WRDM\", \"RDM\", \"CM\", \"LDM\", \"WLDM\"], [\"SS\"], [\"CF\"]],\n \"3-5-2\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"RM\", \"RDM\", \"CM\", \"LDM\", \"LM\"], [\"RS\", \"LS\"]],\n \"3-5-2 Attacking Wingers\": [[\"GK\"], [\"RCB\", \"CB\", \"LCB\"], [\"RAM\", \"HRM\", \"CDM\", \"HLM\", \"LAM\"], [\"RS\", \"LS\"]],\n \"4-1-3-2\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"CDM\"], [\"RAM\", \"CAM\", \"LAM\"], [\"RS\", \"LS\"]],\n \"4-1-4-1\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"CDM\"], [\"RM\", \"HRM\", \"HLM\", \"LM\"], [\"CF\"]],\n \"4-1-4-1 Central Double 10\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"CDM\"], [\"RM\", \"HRAM\", \"HLM\", \"LM\"], [\"CF\"]],\n \"4-1-4-1 Offensive Midfielder\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"CDM\"], [\"RAM\", \"HRAM\", \"HLM\", \"LAM\"], [\"CF\"]],\n \"4-2-3-1\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"RDM\", \"LDM\"], [\"RAM\", \"CAM\", \"LAM\"], [\"CF\"]],\n \"4-3-1-2\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"RDM\", \"CDM\", \"LDM\"], [\"CAM\"], [\"RS\", \"LS\"]],\n \"4-3-2-1\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"RM\", \"CM\", \"LM\"], [\"RAM\", \"LAM\"], [\"CF\"]],\n \"4-3-3\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"HRM\", \"CM\", \"HLM\"], [\"RW\", \"CF\", \"LW\"]],\n \"4-3-3 Double-6\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"RDM\", \"CAM\", \"LDM\"], [\"RW\", \"CF\", \"LW\"]],\n \"4-3-3 with 6\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"HRM\", \"CDM\", \"HLM\"], [\"RW\", \"CF\", \"LW\"]],\n \"4-4-1-1\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"RM\", \"RDM\", \"LDM\", \"LM\"], [\"SS\"], [\"CF\"]],\n \"4-4-1-1 Offensive Outliner\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"RAM\", \"RDM\", \"LAM\"], [\"SS\"], [\"CF\"]],\n \"4-4-2 Diamond\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"CDM\", \"HRM\", \"HLM\", \"CAM\"], [\"RS\", \"LS\"]],\n \"4-4-2 Double-6\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"RM\", \"RDM\", \"LDM\", \"LM\"], [\"RS\", \"LS\"]],\n \"4-4-2 Double-6 Offensive Outliner\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"RAM\", \"RDM\", \"LAM\"], [\"RS\", \"LS\"]],\n \"4-5-1\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"RM\", \"RDM\", \"CM\", \"LDM\", \"LM\"], [\"CF\"]],\n \"4-5-1 Offensive Outliner\": [[\"GK\"], [\"RB\", \"RCB\", \"LCB\", \"LB\"], [\"RAM\", \"HRM\", \"CDM\", \"HLM\", \"LAM\"], [\"CF\"]],\n \"5-3-1-1\": [[\"GK\"], [\"RB\", \"RCB\", \"CB\", \"LCB\", \"LB\"], [\"RM\", \"CM\", \"LM\"], [\"SS\"], [\"CF\"]],\n \"5-3-1-1 with 6\": [[\"GK\"], [\"RB\", \"RCB\", \"CB\", \"LCB\", \"LB\"], [\"RM\", \"CDM\", \"LM\"], [\"SS\"], [\"CF\"]],\n \"5-3-2\": [[\"GK\"], [\"RB\", \"RCB\", \"CB\", \"LCB\", \"LB\"], [\"RM\", \"CM\", \"LM\"], [\"RS\", \"LS\"]],\n \"5-3-2 Double-6\": [[\"GK\"], [\"RB\", \"RCB\", \"CB\", \"LCB\", \"LB\"], [\"RDM\", \"CAM\", \"LDM\"], [\"RS\", \"LS\"]],\n \"5-3-2 with 6\": [[\"GK\"], [\"RB\", \"RCB\", \"CB\", \"LCB\", \"LB\"], [\"HRM\", \"CDM\", \"HLM\"], [\"RS\", \"LS\"]],\n \"5-4-1\": [[\"GK\"], [\"RB\", \"RCB\", \"CB\", \"LCB\", \"LB\"], [\"RM\", \"RDM\", \"LDM\", \"LM\"], [\"CF\"]],\n \"5-4-1 Diamond\": [[\"GK\"], [\"RB\", \"RCB\", \"CB\", \"LCB\", \"LB\"], [\"HLM\", \"CDM\", \"CAM\", \"HRM\"], [\"CF\"]],\n \"5-4-1 Offensive Outliner\": [[\"GK\"], [\"RB\", \"RCB\", \"CB\", \"LCB\", \"LB\"], [\"RAM\", \"RDM\", \"LAM\"], [\"CF\"]],\n}\n\nexport const statsApiCardTypes = {\n yellow: \"yellow\",\n red: \"red\",\n yellowRed: \"yellowRed\"\n};\n\nexport const statsApiManagerTypes = {\n headCoach: \"headcoach\",\n assistantCoach: \"assistantcoach\",\n goalKeeperCoach: \"goalkeepercoach\"\n}\n\nexport const getCultureLocalizer = () => {\n switch (culture.substr(0, 2)) {\n case \"fr\":\n return fr;\n case \"es\":\n return es;\n default:\n return enUS;\n }\n};\n\nexport const entityTypes = {\n story: \"story\",\n customEntity: \"customentity\"\n};\n\nexport const entityCodes = {\n brightcoveVideo: \"brightcovevideo\"\n};\n\nexport const highlightTypes = {\n gameHighlights: \"gameHighlights\",\n condensedGame: \"condensedGame\",\n fullGame: \"fullGame\"\n};\n\n// TODO: We should update variables names with new broadcaster names.\nexport const broadcasterTypes = {\n usNational: \"US TV\",\n usStreaming: \"US Streaming\",\n canadianNational: \"Canada TV\",\n canadianStreaming: \"Canada Streaming\",\n canadaRadio: \"Canada Radio\",\n usRadio: \"US Radio\",\n linearTv: \"Linear TV\",\n radio: \"Radio\",\n streaming: \"Streaming\",\n internationalStreaming: \"International Streaming\"\n};\n\nexport const svgSizes = {\n xSmall: \"x-small\",\n small: \"small\",\n medium: \"medium\",\n large: \"large\",\n xLarge: \"xLarge\",\n};\n\nexport const roleTypes = {\n clubs: 'clubs',\n players: 'players'\n};\n\nexport const cardTypes = {\n club: 'club',\n player: 'player'\n};\n\nexport const filterTypes = {\n all: 'All',\n allCompetitions: \"All Competitions\",\n allClubs: \"All Clubs\",\n allPositions: \"All Positions\"\n};\n\nexport const playerPositionTypes = {\n all: \"All\",\n outfieldPlayers: \"Outfield Players\",\n defender: \"Defender\",\n forward: \"Forward\",\n goalkeeper: \"Goalkeeper\",\n midfielder: \"Midfielder\",\n substitute: \"Substitute\"\n};\n\nexport const playerStatsPositionTypes = {\n all: \"All\",\n defender: \"Defender\",\n forward: \"Forward\",\n goalkeeper: \"Goalkeeper\",\n midfielder: \"Midfielder\",\n};\n\nexport const translateTypes = (t, typeLabel) => {\n switch (typeLabel) {\n case \"All Competitions\":\n return t(\"match_all_competitions\");\n case \"All Clubs\":\n return t(\"match_all_clubs\");\n case \"All\":\n return t(\"match_all\");\n case \"Defender\":\n return t(\"defender\");\n case \"Forward\":\n return t(\"forward\");\n case \"Goalkeeper\":\n return t(\"goalkeeper\");\n case \"Midfielder\":\n return t(\"midfielder\");\n case \"Substitute\":\n return t(\"substitute\");\n case \"Outfield Players\":\n return t(\"outfield_players\");\n }\n return typeLabel;\n};\n\nexport const directionTypes = {\n prev: \"prev\",\n next: \"next\"\n};\n\nexport const queryStatusTypes = {\n idle: \"idle\",\n loading: \"loading\",\n error: \"error\",\n success: \"success\"\n};\n\nexport const mlsPhaseTypes = {\n regular: \"Regular\",\n cup: \"Cup\"\n};\n\nexport const getEmptyStatTableValues = (count = 30) => {\n return {\n header: '',\n items: [...Array(count)].map(() => {\n return {\n player: null,\n club: null,\n appearances: null,\n game_started: null,\n games_played: null,\n total_sub_off: null,\n mins_played: null,\n goals: null,\n pass_percentage: null,\n total_assists: null,\n expected_assists: null,\n expected_goals_assists: null,\n key_passes: null,\n won_tackle: null,\n duel: null,\n ground_duel_percentage: null,\n dribbles_completed: null,\n dribbles_completed_percentage: null,\n fk_foul_lost: null,\n accurate_fwd_zone_pass: null,\n accurate_back_zone_pass: null,\n accurate_cross: null,\n goal_assist: null,\n total_att_assist: null,\n accurate_long_balls: null,\n att_ibox_goal: null,\n att_obox_goal: null,\n att_hd_goal: null,\n att_pen_goal: null,\n att_pen_taken: null,\n total_offside: null,\n yellow_card: null,\n total_red_card: null,\n successful_dribble: null,\n };\n })\n };\n};\n\nexport const getEmptyStatTableValuesAccessors = (count = 30, accessors = []) => {\n return {\n header: 'loading...',\n items: [...Array(count)].map(() => {\n const obj = {};\n accessors.forEach((accessor) => obj[accessor] = null);\n return obj;\n })\n };\n};\n\nexport const formatImageUrl = (\n url,\n imageFormat = { format: \"w_300,c_scale\", extension: \"f_auto\" },\n isFallback = false\n) => {\n if (!url && typeof url !== \"string\") {\n return;\n }\n\n const { format, extension } = imageFormat;\n\n return {\n highQuality: url.replace(\n \"{formatInstructions}\",\n `${format}/${extension}`\n ),\n lowQuality: url.replace(\n \"{formatInstructions}\",\n `${format}/${extension\n }/e_blur:1000,q_1,f_auto/e_grayscale/`\n ),\n title: \"\",\n isFallback\n };\n};\n\nexport function getSeasonsData(response) {\n if (!response) {\n return [];\n }\n\n return response.seasons.map(entry => entry.season);\n}\n\nexport function getForgeSeason(response, competitionOptaId) {\n if (!response || !response.items) {\n return [];\n }\n\n return response.items.find(competition => {\n const { fields } = competition || {};\n const { competitionOptaId: optaId } = fields || {};\n\n return competitionOptaId\n ? optaId.toString() === competitionOptaId.toString()\n : null;\n });\n}\n\nexport function getForgeVideos(response) {\n if (!response || !response.items) {\n return [];\n }\n\n return response.items;\n}\n\nexport function getForgeCompetitionsSportecId(response, includeAll = false) {\n if (!response || !response.items) {\n return [];\n }\n\n const competitions = response.items.filter?.(competition => !!competition.fields?.sportecId)?.map(competition => {\n const { fields, slug } = competition || {};\n const {\n sportecId,\n name,\n shortName,\n blockheaderName,\n nameOverwrite,\n mlsPhaseType\n } = fields || {};\n\n return {\n sportecId,\n name,\n shortName: shortName ? shortName : name,\n blockheaderName,\n nameOverwrite,\n mlsPhaseType,\n slug\n };\n });\n\n return includeAll\n ? [\n {\n sportecId: filterTypes.allCompetitions,\n name: filterTypes.allCompetitions,\n shortName: filterTypes.allCompetitions,\n mlsPhaseType: mlsPhaseTypes.regular,\n slug: \"all-competitions\"\n }, ...competitions]\n : competitions;\n}\n\nexport function formatForgeAllClubsData(clubsData) {\n if (!clubsData || !clubsData.items) {\n return [];\n }\n\n return clubsData.items\n .map(forgeClubData => formatForgeClubData({}, forgeClubData.fields))\n .filter(club => club?.optaId);\n}\n\nexport function getClubsData(response, activeClubs = []) {\n if (!response) {\n return [];\n }\n\n const allClubs = {\n team_id: filterTypes.allClubs,\n team_name: filterTypes.allClubs,\n team_short_name: filterTypes.allClubs,\n team_three_letter_code: filterTypes.allClubs,\n backgroundColor: null,\n logoBWSlug: null,\n logoColorSlug: null,\n logoColorUrl: null,\n crestColorSlug: null,\n slug: null\n };\n\n return [allClubs, ...response.team_statistics\n .filter(club => activeClubs?.length ? activeClubs.includes(club?.team_id?.toString()) : club?.team_id)];\n}\n\nexport function getPureClubsData(response) {\n if (!response) {\n return [];\n }\n\n return [...response\n .filter(club => club.abbreviation)\n .map(club => club.abbreviation)];\n}\n\nexport function getIdClubsData(response) {\n if (!response) {\n return [];\n }\n\n return [...response\n .filter(club => club.abbreviation && club.opta_id)\n .map(club => { return { abbreviation: club.abbreviation, opta_id: club.opta_id }; })];\n}\n\nexport function getAdInsertPosition(arrayLength) {\n if (!arrayLength || arrayLength === 1) {\n return -1;\n }\n\n if (arrayLength % 2 === 0) {\n return arrayLength / 2;\n }\n\n return Math.round(arrayLength / 2);\n}\n\nexport function getSeasonStatsData({ key, response, cardType }) {\n const sanitizeFn = cardType === cardTypes.club\n ? sanitizeClubStats\n : sanitizePlayerStats;\n\n return Promise.all(response.map(statsObj => sanitizeFn(statsObj)))\n .then(data => {\n return { header: key, items: data };\n }).catch(err => {\n throw new Error(`getClubSeasonStatsData: ${err}`);\n });\n}\n\nexport function getSeasonClubStatsData(header, clubsData) {\n if (!clubsData) {\n return {\n header: null,\n items: null\n };\n }\n\n const sanitizedClubData = clubsData.map(club => sanitizeClubStats(club));\n\n return {\n header,\n items: sanitizedClubData\n };\n}\n\nexport function formatForgePlayerData(mlsPlayer, forgePlayer, position = null) {\n if (!forgePlayer && !mlsPlayer) {\n return null;\n }\n\n const { fields, thumbnail, slug, selfUrl, position: forgePosition } = forgePlayer || {};\n const { firstName, lastName, biography, clubOptaId, fullName, knownName, optaId } = fields || {};\n const { known_name, first_name, last_name, opta_id, full_name, birth_city, birth_country, birth_date, birth_state, height, weight, preferred_foot } = mlsPlayer || {};\n\n return {\n birthCity: birth_city || null,\n birthCountry: birth_country || null,\n birthDate: birth_date || null,\n birthState: birth_state || null,\n preferredFoot: preferred_foot || null,\n weight,\n height,\n knownName: knownName || known_name || null,\n firstName: firstName || first_name || null,\n lastName: lastName || last_name || null,\n image: thumbnail || null,\n optaId: optaId || opta_id,\n biography: biography || null,\n clubOptaId: clubOptaId || null,\n fullName: fullName || full_name || null,\n selfUrl: selfUrl || null,\n slug: slug || null,\n isOptaKnownName: !knownName && known_name,\n position: forgePosition || position || null\n };\n}\n\nexport async function getForgePlayerData(player) {\n if (!player) {\n return null;\n }\n\n const forgePlayerEndpoint = forgePlayerDAPI(player.opta_id);\n const forgePlayerData = await fetchClient({ key: `player-${player.opta_id ? player.opta_id : \"no-opta-id\"}`, endpoint: forgePlayerEndpoint, apiURL: apiURL.forgeDAPI });\n const forgePlayer = forgePlayerData?.items?.[0];\n\n const { fields, thumbnail, slug, selfUrl } = forgePlayer || {};\n const { firstName, lastName, biography, clubOptaId, fullName, knownName, optaId } = fields || {};\n\n return {\n knownName: knownName || null,\n firstName: firstName || player.first_name || null,\n lastName: lastName || player.last_name || null,\n image: thumbnail || null,\n optaId: optaId || player.opta_id,\n biography: biography || null,\n clubOptaId: clubOptaId || null,\n fullName: fullName || null,\n selfUrl: selfUrl || null,\n slug: slug || null\n };\n}\n\nexport function formatForgeClubData(mlsClubData, forgeClubData) {\n if (!forgeClubData && !mlsClubData) {\n return null;\n }\n\n const {\n abbreviation,\n backgroundColor,\n crestColorUrl,\n fullName,\n logoBWUrl,\n logoColorUrl,\n optaId,\n shortName,\n slug\n } = forgeClubData || {};\n const { name: mlsName, abbreviation: mlsAbbreviation, opta_id, year_founded } = mlsClubData || {};\n\n return {\n name: name || mlsName || null,\n abbreviation: abbreviation || mlsAbbreviation || null,\n shortName: shortName || null,\n fullName: fullName || null,\n logoColorUrl: logoColorUrl || null,\n logoBWUrl: logoBWUrl || null,\n sportecId: optaId || opta_id || null,\n backgroundColor: backgroundColor || null,\n crestColorUrl: crestColorUrl || null,\n yearFounded: year_founded || null,\n slug: slug || null\n };\n}\n\nexport async function getForgeClubData(club) {\n if (!club) {\n return null;\n }\n\n const forgeClubEndpoint = forgeClubDAPI(club.opta_id);\n const forgeClubData = await fetchClient({ key: `forge-player-${club.opta_id ? club.opta_id : \"no-opta-id\"}`, endpoint: forgeClubEndpoint, apiURL: apiURL.forgeDAPI });\n const forgeClub = forgeClubData?.items?.[0];\n\n const { fields, thumbnail, slug, selfUrl } = forgeClub || {};\n const { name, homeVenueOptaId, optaId, backgroundColor, shortName } = fields || {};\n\n return {\n name: shortName || name || club.name || null,\n abbreviation: club.abbreviation || null,\n image: thumbnail || null,\n optaId: optaId || club.opta_id,\n homeVenueOptaId: homeVenueOptaId || null,\n selfUrl: selfUrl || null,\n slug: slug || null,\n backgroundColor: backgroundColor || null\n };\n}\n\nexport function formatPlayerStats(statistics) {\n if (!statistics) {\n return null;\n }\n\n return {\n fouls_won: statistics?.fouls_suffered || 0,\n team_short_name: statistics?.team_short_name || null,\n team_three_letter_code: statistics?.team_three_letter_code || null,\n team_id: statistics?.team_id || null,\n team_name: statistics?.team_name || null,\n player_first_name: statistics?.player_first_name || null,\n player_last_name: statistics?.player_last_name || null,\n player_id: statistics?.player_id || null,\n sportecId: statistics?.player_id || null,\n player: {\n player_id: statistics?.player_id || null,\n firstName: statistics?.player_first_name || null,\n lastName: statistics?.player_last_name || null,\n },\n club: {\n name: statistics?.team_short_name || null,\n abbreviation: statistics?.team_three_letter_code || null,\n },\n club_abbreviation: statistics?.team_three_letter_code || null,\n accurate_back_zone_pass: statistics?.accurate_back_zone_pass || 0,\n accurate_cross_per: statistics?.crosses_conversion_rate || 0,\n accurate_cross: statistics?.crosses_successful_sum || 0,\n accurate_fwd_zone_pass: statistics?.accurate_fwd_zone_pass || 0,\n accurate_long_balls: statistics?.passes_from_open_play_long_successful_ratio || 0,\n accurate_long_ball_per: statistics?.passes_from_open_play_long_successful_ratio || 0,\n accurate_pass_per: getPercentageFromDecimal(statistics?.passes_conversion_rate || 0),\n accurate_pass: statistics?.accurate_pass || 0,\n accurate_shooting_per: statistics?.accurate_shot_rate || 0,\n aerial_duel_per: 0,\n aerial_duel: statistics?.tackling_games_air_sum || 0,\n aerial_duels: statistics?.aerial_duels || 0,\n aerial_won: statistics?.aerial_won || 0,\n appearances: statistics?.appearances || 0,\n assists: statistics?.first_and_second_assists || 0,\n att_freekick_total: statistics?.passes_and_crosses_from_standards_sum || 0,\n att_hd_goal: statistics?.penalties_successful || 0,\n att_hd_total: statistics?.att_hd_total || 0,\n att_ibox_goal: statistics?.att_ibox_goal || 0,\n att_lf_total: statistics?.shots_at_goal_left_leg || 0,\n att_obox_goal: statistics?.att_obox_goal || 0,\n att_pen_goal: statistics?.penalties_successful || 0,\n att_pen_taken: statistics?.penalties_sum || 0,\n att_rf_total: statistics?.shots_at_goal_right_leg || 0,\n average_shot_distance_against: statistics?.average_shot_distance_against || 0,\n average_shot_distance: statistics?.average_shot_distance || 0,\n clean_sheet: statistics?.clean_sheet || 0,\n clearances: statistics?.defensive_clearances || 0,\n corner_taken: statistics?.corner_kicks_sum || 0,\n defensive_third_passes_against: statistics?.defensive_third_passes_against || 0,\n dribbles_completed_percentage: statistics?.dribbles_completed_percentage || 0,\n dribbles_completed: statistics?.dribbles_completed || 0,\n duel_lost: statistics?.duel_lost || 0,\n duel_won: statistics?.duel_won || 0,\n duel: statistics?.duel || 0,\n expected_assists: statistics?.expected_assists || 0,\n expected_goals_conceded: statistics?.expected_goals_conceded || 0,\n expected_goals: statistics?.xg || 0,\n final_third_passes_against: statistics?.final_third_passes_against || 0,\n fk_foul_lost: statistics?.fouls_sum || 0,\n fk_foul_won: statistics?.fouls_suffered || 0,\n fouls: statistics?.fouls || 0,\n game_started: statistics?.matches_played - statistics?.substitutions_in < 0 ? 0 : statistics?.matches_played - statistics?.substitutions_in,\n games_played: statistics?.matches_played || 0,\n goal_assist: statistics?.first_and_second_assists || statistics?.assists || 0,\n goal_kicks: statistics?.goal_kicks || 0,\n goal_conversion_per: statistics?.shots_conversion_rate || 0,\n goals_90: 0,\n goals_plus_assists: statistics?.goals_plus_first_and_second_assists || statistics?.goals_plus_assists || 0,\n goals_assists: statistics?.first_and_second_assists || statistics?.assists || 0,\n goals_conceded: statistics?.goals_conceded || 0,\n goal_differential: statistics?.goal_differential || 0,\n goals: statistics?.goals || 0,\n interception: statistics?.interceptions_sum || 0,\n interceptions: statistics?.interceptions_sum || 0,\n keeper_throws: statistics?.keeper_throws || 0,\n key_passes: statistics?.assists_shot_at_goal || 0,\n lost_corners: statistics?.lost_corners || 0,\n long_ball_percentage: statistics?.passes_from_open_play_long_successful_ratio || 0,\n midfield_third_passes_against: statistics?.midfield_third_passes_against || 0,\n mins_played: statistics?.normalized_player_minutes || 0,\n ontarget_scoring_att: statistics?.shots_on_target || 0,\n shots_on_target: statistics?.shots_on_target || 0,\n pass_percentage: statistics?.pass_percentage || 0,\n passing_percentages_against: statistics?.passing_percentages_against || 0,\n penalty_conceded: statistics?.penalty_conceded || 0,\n pen_goals_conceded: statistics?.pen_goals_conceded || 0,\n penalty_faced: statistics?.penalties_faced || 0,\n penalty_save: statistics?.penalties_saved || 0,\n penalty_saved: statistics?.penalties_saved || 0,\n pressing_actions: statistics?.pressing_actions || 0,\n punches: statistics?.punches || 0,\n red_card: statistics?.red_card || 0,\n saves_percentage: statistics?.saves_percentage || 0,\n saves: statistics?.goalkeeper_saves || 0,\n shots_on_target_against: statistics?.shots_on_target_against || 0,\n successful_dribble: statistics?.successful_dribble || 0,\n successful_passes: statistics?.successful_passes || 0,\n successful_short_pass: statistics?.passes_from_open_play_short_successful_ratio || 0,\n total_assists: statistics?.total_assists || 0,\n total_att_assist: statistics?.assists_shot_at_goal || 0,\n total_clearance: statistics?.defensive_clearances || 0,\n total_contest: statistics?.total_contest || 0,\n total_draws: statistics?.total_draws || 0,\n total_matches: statistics?.matches_played || 0,\n total_launches: statistics?.total_launches || 0,\n total_long_balls: statistics?.total_long_balls || 0,\n total_losses: statistics?.total_losses || 0,\n total_offside: statistics?.offsides || 0,\n total_pass: statistics?.passes_sum || 0,\n total_starts: statistics?.matches_started || 0,\n total_red_card: statistics?.cards_red || 0,\n total_scoring_att: statistics?.shots_at_goal_sum || 0,\n total_sub_off: statistics?.total_sub_off || 0,\n total_sub_on: statistics?.substitutions_in || 0,\n total_wins: statistics?.total_wins || 0,\n touches: statistics?.ball_actions || 0,\n turnover: statistics?.turnover || 0,\n was_fouled: statistics?.was_fouled || 0,\n won_tackle: statistics?.won_tackle || 0,\n yellow_card: statistics?.cards_yellow || 0,\n };\n}\n\nexport async function sanitizePlayerStats(statsObj) {\n if (!statsObj) {\n return null;\n }\n\n const player = await getForgePlayerData(statsObj?.player);\n const club = await getForgeClubData(statsObj?.club);\n const statistics = statsObj && statsObj.statistics;\n const dribble_percentage = calculatePercentage(statistics?.successful_dribble, statistics?.successful_dribble + statistics?.failed_dribble);\n const expected_assists_minus_assists = calculateSubtractedValues(statistics?.expected_assists, statistics?.goal_assist);\n const launches_attempted = calculateSum(statistics?.accurate_Launches, statistics?.failed_launches);\n const expected_goals_minus_goals = calculateSubtractedValues(statistics?.expected_goals, statistics?.goals);\n const att_pen_percentage = calculatePercentage(statistics?.att_pen_goal, statistics?.att_pen_taken);\n const goals_assists = calculateSum(statistics?.goals, statistics?.goal_assist);\n const expected_goals_assists = calculateSum(statistics?.expected_goals, statistics?.expected_assists);\n const shots_against = calculateSum(statistics?.attempts_conceded_ibox, statistics?.attempts_conceded_obox);\n const goals_against_expected_goals_against = calculateSubtractedValues(statistics?.goals_against, statistics?.expected_goals_against);\n const long_ball_percentage = calculatePercentage(statistics?.accurate_long_balls, statistics?.accurate_long_balls + statistics?.failed_long_balls);\n const save_percentage = calculatePercentage(statistics?.goals_conceded, statistics?.attempts_conceded_ibox + statistics?.attempts_conceded_obox);\n const headed_duel_percentage = calculatePercentage(statistics?.aerial_won, statistics?.aerial_won + statistics?.aerial_lost);\n const ground_duel_percentage = calculatePercentage(statistics?.ground_duel_won, statistics?.ground_duel_won + statistics?.ground_duel_lost);\n const duel_percentage = calculatePercentage(statistics?.duel_won, statistics?.duel);\n const penalty_kick_save_percentage = calculatePercentage(statistics?.penalty_save, statistics?.penalty_conceded);\n const assist_90 = !isNaN(statistics?.goal_assist) && !isNaN(statistics?.mins_played) ? round(statistics?.goal_assist / (statistics?.mins_played / 90), 2) : 0;\n const goals_90 = !isNaN(statistics?.goals) && !isNaN(statistics?.mins_played) ? round(statistics?.goals / (statistics?.mins_played / 90), 2) : 0;\n const shot_conversion = !isNaN(statistics?.goals) && !isNaN(statistics?.total_scoring_att) ? calculatePercentage(statistics?.goals, statistics?.total_scoring_att) : 0;\n const goals_allowed_average = !isNaN(statistics?.goals_conceded) && !isNaN(statistics?.mins_played) ? round((statistics?.goals_conceded / statistics?.mins_played) * 90, 2) : 0;\n const save_percentage_gk = calculatePercentage(statistics?.saves, calculateSum(statistics?.saves, statistics?.goals_conceded));\n const win_percentage = calculatePercentage(statistics?.total_wins, statistics?.matchesStarted);\n\n return {\n player,\n club,\n assist_90,\n goals_90,\n shot_conversion,\n goals_allowed_average,\n save_percentage_gk,\n appearances: statistics?.appearances || 0,\n game_started: statistics?.game_started || 0,\n games_played: statistics?.games_played || 0,\n total_sub_off: statistics?.total_sub_off || 0,\n mins_played: statistics?.mins_played || 0,\n goals: statistics?.goals || 0,\n goals_assists,\n expected_goals: statistics?.expected_goals || 0,\n expected_goals_minus_goals,\n expected_assists_minus_assists,\n launches_attempted,\n att_pen_percentage,\n accurate_shooting_per: decimalRound(statistics?.accurate_shooting_per || 0, 1),\n total_scoring_att: statistics?.total_scoring_att || 0,\n average_shot_distance: statistics?.average_shot_distance || 0,\n ontarget_scoring_att: statistics?.shots_on_target || 0,\n pass_percentage: statistics?.pass_percentage || 0,\n total_assists: statistics?.total_assists || 0,\n expected_assists: statistics?.expected_assists || 0,\n expected_goals_assists,\n key_passes: statistics?.key_passes || 0,\n won_tackle: statistics?.won_tackle || 0,\n duel: statistics?.duel || 0,\n duel_won: statistics?.duel_won || 0,\n duel_lost: statistics?.duel_lost || 0,\n duel_percentage,\n ground_duel_percentage,\n dribbles_completed: statistics?.dribbles_completed || 0,\n dribbles_completed_percentage: statistics?.dribbles_completed_percentage || 0,\n fk_foul_lost: statistics?.fk_foul_lost || 0,\n fk_foul_won: statistics?.fk_foul_won || 0,\n accurate_fwd_zone_pass: statistics?.accurate_fwd_zone_pass || 0,\n accurate_back_zone_pass: statistics?.accurate_back_zone_pass || 0,\n accurate_cross: statistics?.accurate_cross || 0,\n goal_assist: statistics?.goal_assist || 0,\n total_att_assist: statistics?.total_att_assist || 0,\n accurate_long_balls: statistics?.accurate_long_balls || 0,\n successful_short_pass: statistics?.successful_short_pass || 0,\n att_ibox_goal: statistics?.att_ibox_goal || 0,\n att_obox_goal: statistics?.att_obox_goal || 0,\n att_hd_goal: statistics?.att_hd_goal || 0,\n att_pen_goal: statistics?.att_pen_goal || 0,\n att_pen_taken: statistics?.att_pen_taken || 0,\n total_offside: statistics?.total_offside || 0,\n yellow_card: statistics?.yellow_card || 0,\n red_card: statistics?.red_card || 0,\n total_red_card: statistics?.total_red_card || 0,\n successful_dribble: statistics?.successful_dribble || 0,\n dribble_percentage,\n penalty_faced: statistics?.penalty_faced || 0,\n penalty_save: statistics?.penalty_save || 0,\n accurate_pass_per: round(statistics?.accurate_pass_per || 0, 1),\n interception: statistics?.interception || 0,\n clean_sheet: statistics?.clean_sheet || 0,\n expected_goals_conceded: statistics?.expected_goals_conceded || 0,\n goals_conceded: statistics?.goals_conceded || 0,\n total_clearance: statistics?.total_clearance || 0,\n turnover: statistics?.turnover || 0,\n total_pass: statistics?.total_pass || 0,\n pen_goals_conceded: statistics?.pen_goals_conceded || 0,\n penalty_kick_save_percentage,\n defensive_third_passes_against: statistics?.defensive_third_passes_against || 0,\n midfield_third_passes_against: statistics?.midfield_third_passes_against || 0,\n final_third_passes_against: statistics?.final_third_passes_against || 0,\n interceptions: statistics?.interception || 0,\n pressing_actions: statistics?.pressing_actions || 0,\n passing_percentages_against: statistics?.passing_percentages_against || 0,\n headed_duel_percentage,\n save_percentage,\n average_shot_distance_against: statistics?.average_shot_distance_against || 0,\n shots_on_target_against: statistics?.shots_on_target_against || 0,\n saves: statistics?.saves || 0,\n saves_percentage: statistics?.saves_percentage || 0,\n long_ball_percentage,\n shots_against,\n goals_against_expected_goals_against,\n clearances: statistics?.clearances || 0,\n total_wins: statistics?.total_wins || 0,\n total_losses: statistics?.total_losses || 0,\n total_draws: statistics?.total_draws || 0,\n win_percentage,\n att_hd_total: statistics?.att_hd_total || 0,\n att_freekick_total: statistics?.att_freekick_total || 0,\n att_lf_total: statistics?.att_lf_total || 0,\n att_rf_total: statistics?.att_rf_total || 0,\n touches: statistics?.touches || 0,\n aerial_won: statistics?.aerial_won || 0,\n aerial_duel_per: calculatePercentage(statistics?.aerial_won, statistics?.aerial_duel),\n accurate_cross_per: statistics?.accurate_cross_per || 0,\n };\n}\n\nexport function formatClubStats(statsObj, forgeClubData) {\n if (!statsObj) {\n return null;\n }\n\n const club = forgeClubData?.club;\n const statistics = forgeClubData?.statistics;\n const penalty_kick_save_percentage = calculatePercentage(statistics?.penalties_saved, calculateSum(statistics?.penalties_saved, statistics?.penalties_caused));\n const expected_goals_minus_against = calculateSubtractedValues(statistics?.xG, statistics?.xG_efficiency);\n const expected_goals_minus_goals = calculateSubtractedValues(statistics?.expected_goals, statistics?.goals);\n const att_pen_percentage = calculatePercentage(statistics?.att_pen_goal, statistics?.att_pen_taken);\n const shots_against = calculateSum(statistics?.attempts_conceded_ibox, statistics?.attempts_conceded_obox);\n const expected_assists_minus_assists = calculateSubtractedValues(statistics?.expected_assists, statistics?.goal_assist);\n const pass_percentage = calculatePercentage(statistics?.passes_successful_sum, statistics?.passes_sum);\n const long_ball_percentage = calculatePercentage(statistics?.accurate_long_balls, statistics?.accurate_long_balls + statistics?.failed_long_balls);\n const save_percentage = calculatePercentage(statistics?.goals_conceded, statistics?.attempts_conceded_ibox + statistics?.attempts_conceded_obox);\n const headed_duel_percentage = calculatePercentage(statistics?.aerial_won, statistics?.aerial_won + statistics?.aerial_lost);\n const ground_duel_percentage = calculatePercentage(statistics?.ground_duel_won, statistics?.ground_duel_won + statistics?.ground_duel_lost);\n const duel_percentage = calculatePercentage(statistics?.duel_won, statistics?.duel);\n const total_goal_differential = calculateSubtractedValues(statistics?.goals, statistics?.goals_conceded);\n\n return {\n assists: statistics?.first_and_second_assists,\n passes_completed: statistics?.passes_successful_sum,\n corner_kicks: statistics?.corner_kicks_sum,\n club,\n att_pen_percentage,\n shots_against,\n long_ball_percentage,\n pass_percentage,\n ground_duel_percentage,\n duel_percentage,\n total_goal_differential,\n clean_sheet: statistics?.clean_sheet || 0,\n accurate_pass: statistics?.accurate_pass || 0,\n total_pass: statistics?.total_pass || 0,\n expected_assists_minus_assists,\n save_percentage,\n average_shot_distance: statistics?.average_shot_distance || 0,\n total_scoring_att: statistics?.total_scoring_att || 0,\n ontarget_scoring_att: statistics?.ontarget_scoring_att || 0,\n accurate_shooting_per: decimalRound(statistics?.accurate_shooting_per || 0, 1),\n appearances: statistics?.appearances || 0,\n game_started: statistics?.game_started || 0,\n goals_conceded: statistics?.goals_conceded || 0,\n total_clearance: statistics?.total_clearance || 0,\n expected_goals_conceded: statistics?.expected_goals_conceded || 0,\n expected_goals_minus_against,\n expected_goals_minus_goals,\n penalty_conceded: statistics?.penalty_conceded || 0,\n total_sub_off: statistics?.total_sub_off || 0,\n mins_played: statistics?.mins_played || 0,\n goals: statistics?.goals || 0,\n turnover: statistics?.turnover || 0,\n total_assists: statistics?.total_assists || 0,\n expected_goals_assists: statistics?.expected_goals_assists || 0,\n won_tackle: statistics?.won_tackle || 0,\n interception: statistics?.interception || 0,\n duel: statistics?.duel || 0,\n duel_won: statistics?.duel_won || 0,\n duel_lost: statistics?.duel_lost || 0,\n dribbles_completed: statistics?.dribbles_completed || 0,\n dribbles_completed_percentage: statistics?.dribbles_completed_percentage || 0,\n fk_foul_lost: statistics?.fk_foul_lost || 0,\n accurate_fwd_zone_pass: statistics?.accurate_fwd_zone_pass || 0,\n accurate_back_zone_pass: statistics?.accurate_back_zone_pass || 0,\n accurate_cross: statistics?.accurate_cross || 0,\n total_att_assist: statistics?.total_att_assist || 0,\n accurate_long_balls: statistics?.accurate_long_balls || 0,\n successful_short_pass: statistics?.successful_short_pass || 0,\n att_ibox_goal: statistics?.att_ibox_goal || 0,\n att_obox_goal: statistics?.att_obox_goal || 0,\n att_hd_goal: statistics?.att_hd_goal || 0,\n att_pen_goal: statistics?.att_pen_goal || 0,\n att_pen_taken: statistics?.att_pen_taken || 0,\n total_offside: statistics?.total_offside || 0,\n red_card: statistics?.red_card || 0,\n total_red_card: statistics?.total_red_card || 0,\n successful_dribble: statistics?.successful_dribble || 0,\n shots_on_target_against: statistics?.shots_on_target_against || 0,\n average_shot_distance_against: statistics?.average_shot_distance_against || 0,\n clearances: statistics?.clearances || 0,\n headed_duel_percentage,\n penalty_faced: statistics?.penalty_faced || 0,\n penalty_save: statistics?.penalty_save || 0,\n pen_goals_conceded: statistics?.pen_goals_conceded || 0,\n penalty_kick_save_percentage,\n pressing_actions: statistics?.pressing_actions || 0,\n passing_percentages_against: statistics?.passing_percentages_against || 0,\n defensive_third_passes_against: statistics?.defensive_third_passes_against || 0,\n midfield_third_passes_against: statistics?.midfield_third_passes_against || 0,\n final_third_passes_against: statistics?.final_third_passes_against || 0,\n saves: statistics?.saves || 0,\n att_hd_total: statistics?.att_hd_total || 0,\n fk_foul_won: statistics?.fk_foul_won || 0,\n att_freekick_total: statistics?.att_freekick_total || 0,\n interceptions: statistics?.interceptions || 0,\n att_lf_total: statistics?.att_lf_total || 0,\n att_rf_total: statistics?.att_rf_total || 0,\n touches: statistics?.touches || 0,\n aerial_won: statistics?.aerial_won || 0,\n aerial_duel_per: calculatePercentage(statistics?.aerial_won, statistics?.aerial_duel),\n accurate_cross_per: statistics?.accurate_cross_per || 0,\n corner_taken: statistics?.corner_kicks_sum || 0,\n red_card: statistics?.cards_red || 0,\n club_id: statistics?.sportecId || 0,\n clubSportecId: statistics?.sportecId || 0,\n accurate_pass: statistics?.passes_and_crosses_successful_sum || 0,\n expected_goals: statistics?.xG || 0,\n expected_assists: statistics?.passes_conversion_rate || 0,\n games_played: statistics?.matches_played || 0,\n goal_assist: statistics?.first_and_second_assists || statistics?.assists || 0,\n key_passes: statistics?.goal_opportunities || 0,\n yellow_card: statistics?.cards_yellow || 0,\n total_matches: statistics?.matches_played || 0,\n };\n}\n\nexport function sanitizeClubStats(statistics, mlsPhaseType) {\n if (!statistics) {\n return null;\n }\n\n const penalty_kick_save_percentage = calculatePercentage(statistics?.penalties_saved, statistics?.penalties_sum);\n const expected_goals_minus_against = calculateSubtractedValues(statistics?.expected_goals, statistics?.expected_goals_conceded);\n const expected_goals_minus_goals = calculateSubtractedValues(statistics?.expected_goals, statistics?.goals);\n const expected_assists_minus_assists = calculateSubtractedValues(statistics?.expected_assists, statistics?.goal_assist);\n const pass_percentage = calculatePercentage(statistics?.passes_successful_sum, statistics?.passes_sum);\n const save_percentage = calculatePercentage(statistics?.shots_faced, statistics?.goalkeeper_saves);\n const headed_duel_percentage = calculatePercentage(statistics?.aerial_won, statistics?.aerial_won + statistics?.aerial_lost);\n const ground_duel_percentage = calculatePercentage(statistics?.ground_duel_won, statistics?.ground_duel_won + statistics?.ground_duel_lost);\n const duel_percentage = calculatePercentage(statistics?.duel_won, statistics?.duel);\n const total_goal_differential = calculateSubtractedValues(statistics?.goals, statistics?.goals_conceded);\n\n return {\n accurate_back_zone_pass: statistics?.accurate_back_zone_pass || 0,\n accurate_cross_per: statistics?.accurate_cross_per || 0,\n accurate_cross: statistics?.accurate_cross || 0,\n accurate_fwd_zone_pass: statistics?.accurate_fwd_zone_pass || 0,\n accurate_long_balls: statistics?.crosses_successful_sum || 0,\n accurate_pass: statistics?.passes_successful_sum || 0,\n accurate_shooting_per: calculatePercentage(statistics?.shots_on_target, statistics?.shots_at_goal_sum),\n aerial_duel_per: calculatePercentage(statistics?.tackling_games_air_won, statistics?.tackling_games_air_sum),\n aerial_won: statistics?.aerial_won || 0,\n appearances: statistics?.appearances || 0,\n att_freekick_total: statistics?.free_kicks_sum || 0,\n att_hd_goal: statistics?.att_hd_goal || 0,\n att_hd_total: statistics?.att_hd_total || 0,\n att_ibox_goal: statistics?.att_ibox_goal || 0,\n att_lf_total: statistics?.att_lf_total || 0,\n att_obox_goal: statistics?.att_obox_goal || 0,\n att_pen_goal: statistics?.penalties_successful || 0,\n att_pen_percentage: getPercentageFromDecimal(statistics?.penalty_conversion_rate || 0),\n att_pen_taken: statistics?.penalties_sum || 0,\n att_rf_total: statistics?.att_rf_total || 0,\n average_shot_distance_against: statistics?.average_shot_distance_against || 0,\n average_shot_distance: statistics?.average_shot_distance || 0,\n clean_sheet: statistics?.clean_sheets || 0,\n clearances: statistics?.defensive_clearances || 0,\n club_id: statistics?.team_id || statsObj?.club?.team_id,\n club: statistics?.club,\n corner_taken: statistics?.corner_kicks_sum || 0,\n defensive_third_passes_against: statistics?.defensive_third_passes_against || 0,\n dribbles_completed_percentage: statistics?.dribbles_completed_percentage || 0,\n dribbles_completed: statistics?.dribbles_completed || 0,\n duel_lost: statistics?.duel_lost || 0,\n duel_percentage,\n duel_won: statistics?.duel_won || 0,\n duel: statistics?.duel || 0,\n expected_assists_minus_assists,\n expected_assists: statistics?.passes_conversion_rate || 0,\n expected_goals_assists: statistics?.expected_goals_assists || 0,\n expected_goals_conceded: statistics?.expected_goals_conceded || 0,\n expected_goals_minus_against,\n expected_goals_minus_goals,\n expected_goals: statistics?.xG || 0,\n final_third_passes_against: statistics?.final_third_passes_against || 0,\n fk_foul_lost: statistics?.fouls_against_opponent || 0,\n fk_foul_won: statistics?.fouls_suffered || 0,\n game_started: statistics?.game_started || 0,\n games_played: statistics?.matches_played || 0,\n goal_assist: statistics?.assists || 0,\n goals_conceded: statistics?.goals_conceded || 0,\n goals: statistics?.goals || 0,\n ground_duel_percentage,\n headed_duel_percentage,\n interception: statistics?.interception || 0,\n interceptions: statistics?.interceptions || 0,\n key_passes: statistics?.goal_opportunities || 0,\n long_ball_percentage: statistics?.passes_from_open_play_long_successful_ratio || 0,\n midfield_third_passes_against: statistics?.midfield_third_passes_against || 0,\n mins_played: statistics?.mins_played || 0,\n ontarget_scoring_att: statistics?.shots_on_target || 0,\n pass_percentage,\n passing_percentages_against: statistics?.passing_percentages_against || 0,\n pen_goals_conceded: statistics?.pen_goals_conceded || 0,\n penalty_conceded: statistics?.penalties_caused || 0,\n penalty_faced: statistics?.penalties_sum || 0,\n penalty_kick_save_percentage,\n penalty_save: statistics?.penalties_saved || 0,\n pressing_actions: statistics?.pressing_actions || 0,\n red_card: statistics?.cards_red || 0,\n save_percentage,\n saves: statistics?.saves || 0,\n shots_against: statistics?.shots_faced || 0,\n shots_on_target_against: statistics?.shots_on_target_against || 0,\n successful_dribble: statistics?.successful_dribble || 0,\n successful_short_pass: statistics?.successful_short_pass || 0,\n team_id: statistics?.team_id || statistics?.club?.team_id,\n total_assists: statistics?.first_and_second_assists || 0,\n total_att_assist: statistics?.second_assists || 0,\n total_clearance: statistics?.defensive_clearances || 0,\n total_goal_differential,\n total_matches: statistics?.matches_played || 0,\n total_offside: statistics?.offsides || 0,\n total_pass: statistics?.passes_sum || 0,\n total_red_card: statistics?.cards_red || 0,\n total_scoring_att: statistics?.shots_at_goal_sum || 0,\n total_sub_off: statistics?.total_sub_off || 0,\n touches: statistics?.touches || 0,\n turnover: statistics?.turnover || 0,\n won_tackle: statistics?.won_tackle || 0,\n yellow_card: statistics?.cards_yellow || 0,\n };\n}\n\nexport function mapStatTypeToStatsApi(statType) {\n const statsApiHash = {\n accurate_pass: \"accurate_pass\",\n aerial_duels_won: \"aerial_won\",\n appearances: \"appearances\",\n assists: \"first_and_second_assists\",\n clean_sheets: \"clean_sheet\",\n clearances: \"total_clearance\",\n corner_taken: \"corner_taken\",\n expected_assists: \"expected_assists\",\n expected_goals_against: \"expected_goals_conceded\",\n expected_goals: \"expected_goals\",\n fouls_won: \"fouls_suffered\",\n free_kicks: \"att_freekick_total\",\n games_played: \"games_played\",\n games_started: 'game_started',\n goal_assist: \"goal_assist\",\n goalkeeper_saves: \"saves\",\n goals_against: \"goals_conceded\",\n goals_inside_18: \"att_ibox_goal\",\n goals_outside_18: \"att_obox_goal\",\n goals: \"goals\",\n headed_goals: \"att_hd_goal\",\n headed_shots: \"att_hd_total\",\n interceptions: \"interception\",\n key_passes: \"assists_shot_at_goal\",\n left_footed_shots: \"att_lf_total\",\n long_passes: \"accurate_long_balls\",\n minutes: \"mins_played\",\n offsides: \"total_offside\",\n passes_attempted: \"total_pass\",\n passes_completed: \"total_pass\",\n passes_in_the_opposition_half: \"accurate_fwd_zone_pass\",\n passes_in_the_own_half: \"accurate_back_zone_pass\",\n passing_percentage: \"accurate_pass_per\",\n penalty_kick_attempts_for: \"att_pen_taken\",\n penalty_kick_goals_for: \"att_pen_goal\",\n penalty_kicks_against: 'penalty_faced',\n penalty_kicks_saved: \"penalty_save\",\n player_interception: \"interception\",\n red_card: \"red_card\",\n right_footed_shots: \"att_rf_total\",\n short_passes: \"successful_short_pass\",\n shots_assists: \"total_att_assist\",\n shots_on_target: \"shots_on_target\",\n shots: \"shots_at_goal_sum\",\n substitute_appearances: \"substitution_in\",\n successful_crosses: \"accurate_cross\",\n successful_dribble: \"successful_dribble\",\n total_red_card: \"total_red_card\",\n touches: \"ball_actions\",\n won_tackles: \"won_tackle\",\n yellow_card: \"yellow_card\",\n corner_kicks: \"corner_taken\",\n };\n\n if (statType in statsApiHash) {\n return {\n key: statType,\n value: statsApiHash[statType]\n };\n }\n return null;\n}\n\nexport const checkNextPage = (items, itemCount = 30) => {\n if (items) {\n return items.length === itemCount;\n }\n\n return false;\n};\n\nexport const countryTypes = {\n unitedStates: \"US\",\n canada: \"CA\"\n};\n\nexport function composeGeoLocatedProviders(providers, country) {\n const geoObj = {\n national: [],\n streaming: [],\n radio: [],\n allProviders: [],\n international: []\n };\n\n if (providers == null || country == null) {\n return geoObj;\n }\n\n\n if (Array.isArray(providers?.allProvidersList)) {\n const internationalProviders = providers.allProvidersList.filter(provider => provider.broadcasterType === broadcasterTypes.internationalStreaming);\n\n geoObj.international = internationalProviders;\n }\n\n const { canadianStreaming, canadianNational, usStreaming, usNational, radio } = providers || {};\n\n switch (country) {\n case countryTypes.unitedStates:\n if (usNational != null && usNational.length > 0) {\n geoObj.national = usNational;\n geoObj.allProviders = [...usNational];\n }\n if (usStreaming != null && usStreaming.length > 0) {\n geoObj.streaming = usStreaming;\n geoObj.allProviders = [...geoObj.allProviders, ...usStreaming];\n }\n if (radio != null && radio.length > 0) {\n geoObj.radio = radio.filter((broadcaster) => broadcaster?.broadcasterType === broadcasterTypes.usRadio);\n geoObj.allProviders = [...geoObj.allProviders, ...radio];\n }\n break;\n case countryTypes.canada:\n if (canadianNational != null && canadianNational.length > 0) {\n geoObj.national = canadianNational;\n geoObj.allProviders = [...canadianNational];\n }\n if (canadianStreaming != null && canadianStreaming.length > 0) {\n geoObj.streaming = canadianStreaming;\n geoObj.allProviders = [...geoObj.allProviders, ...canadianStreaming];\n }\n if (radio != null && radio.length > 0) {\n geoObj.radio = radio.filter((broadcaster) => broadcaster?.broadcasterType === broadcasterTypes.canadaRadio);\n geoObj.allProviders = [...geoObj.allProviders, ...radio];\n }\n break;\n default:\n if (usNational != null && usNational.length > 0) {\n geoObj.national = usNational;\n geoObj.allProviders = [...usNational];\n }\n if (usStreaming != null && usStreaming.length > 0) {\n geoObj.streaming = usStreaming;\n geoObj.allProviders = [...geoObj.allProviders, ...usStreaming];\n }\n if (canadianNational != null && canadianNational.length > 0) {\n geoObj.national = [...geoObj.national, ...canadianNational];\n geoObj.allProviders = [...geoObj.allProviders, ...canadianNational];\n }\n if (canadianStreaming != null && canadianStreaming.length > 0) {\n geoObj.streaming = [...geoObj.streaming, ...canadianStreaming];\n geoObj.allProviders = [...geoObj.allProviders, ...canadianStreaming];\n }\n if (radio != null && radio.length > 0) {\n geoObj.radio = radio;\n geoObj.allProviders = [...geoObj.allProviders, ...radio];\n }\n }\n\n return geoObj;\n}\n\nexport function stringifyGeoProviders(providers) {\n if (providers == null || providers.length === 0) {\n return null;\n }\n\n return providers.map(provider => {\n const { broadcasterShortName, broadcasterName } = provider || {};\n return broadcasterShortName ? broadcasterShortName : broadcasterName;\n }).join(\", \");\n}\n\nexport function stringifyProviders(providers) {\n if (providers == null || providers.length === 0) {\n return null;\n }\n\n return providers.map(provider => {\n const { broadcasterShortName, broadcasterName } = provider || {};\n return broadcasterShortName ? broadcasterShortName : broadcasterName;\n }).join(\", \");\n}\n\nfunction composeStatistics(statsObj, phase) {\n if (statsObj == null || (statsObj.statistics == null && statsObj.regular_season_statistics == null && statsObj.postseason_statistics == null)) {\n return null;\n }\n\n if (phase === mlsPhaseTypes.regular) {\n // Added this small fix for MNP\n // When it's MNP the .statistics prop is populated but the phase is Regular\n // regular_season_statistics is null in those cases\n if (!statsObj.regular_season_statistics && statsObj.statistics) {\n return statsObj.statistics;\n }\n\n return statsObj.regular_season_statistics;\n }\n\n if (phase === mlsPhaseTypes.cup) {\n return statsObj.postseason_statistics;\n }\n\n return statsObj.statistics;\n}\n\nexport const matchHighlightsTagSlug = \"match-highlights\";\n\nexport const appleTvTypes = {\n appleTv: \"appletv\",\n appleTvPlus: \"appletv-plus\",\n appleTvSeasonPass: \"appletv-season-pass\"\n};\n\nexport const appleProvidersType = {\n appleTv: \"Apple TV\",\n appleTvPlus: \"Apple TV+\",\n appleTvSeasonPass: \"MLS Season Pass\"\n};\n\nexport const getClubsDir = () => {\n const clubsDir = window?.forgeVariables?.directoryList?.clubsDir || \"clubs\";\n\n return clubsDir;\n}\n\nexport const removeLeadingSlash = (str) => str?.replace(/^\\//, '') || '';\nexport const removeTrailingSlash = (str) => str?.replace(/\\/$/, '') || '';\n\nexport function getHotelBookingIconUrl({ variant = \"light\" }) {\n const forgeMatchVariables = window?.forgeVariables?.match;\n const { hotelBookingIconLightUrl, hotelBookingIconDarkUrl } = forgeMatchVariables || {};\n\n return variant === \"light\" ? hotelBookingIconLightUrl : hotelBookingIconDarkUrl;\n}\n\nexport function getTicketMasterIconUrl({ variant = \"light\" }) {\n const forgeMatchVariables = window?.forgeVariables?.match;\n const { ticketmasterIconDarkUrl, ticketmasterIconLightUrl } = forgeMatchVariables || {};\n\n return variant === \"light\" ? ticketmasterIconLightUrl : ticketmasterIconDarkUrl;\n}\n\nexport function getTicketMasterUrl(urls = []) {\n return urls?.find(url => url?.includes(\"ticketmaster\"));\n}\n"],"names":[],"sourceRoot":""}