Not a member of GistPad yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name Improve SCC
- // @description Adds shortcut buttons; Colour codes search results; additional package history information; and more…
- // @version 13.0.4
- // @author David King (dkingamz@)
- // Translator-de Stephanie Petke (petke@)
- // Translator-es Carlos de la Peña (cacalzad@)
- // Translator-fr Karl-Emmanuel Etifier (karleme@)
- // Translator-it Andrea La Rosa (anrosam@)
- // Thanks-cortex Dennis Leonhardt (leoden@)
- // @namespace https://phonetool.amazon.com/users/dkingamz
- // @match https://*/station/dashboard/*
- // @match https://*.last-mile.amazon.dev/?*
- // @match https://midway-auth.amazon.com/*
- // @exclude https://*.geostudio.last-mile.amazon.dev/*
- // @grant GM.xmlHttpRequest
- // @grant GM.info
- // @grant GM.setValue
- // @grant GM_getValue
- // @connect midway-auth.amazon.com
- // @connect routingtools-viz-dub.dub.proxy.amazon.com
- // @connect logistics.amazon.co.uk
- // @connect ie-logistics.amazon.co.uk
- // @connect logistics.amazon.de
- // @connect at-logistics.amazon.de
- // @connect logistics.amazon.es
- // @connect logistics.amazon.fr
- // @connect logistics.amazon.it
- // @connect logistics.amazon.nl
- // @connect logistics.amazon.sa
- // @connect logistics.amazon.com
- // @connect logistics.amazon.com.mx
- // @connect logistics.amazon.ca
- // @connect logistics.amazon.com.br
- // @connect logistics.amazon.in
- // @connect logistics.amazon.ae
- // @connect logistics.amazon.eg
- // @connect logistics.amazon.co.jp
- // @connect logistics.amazon.com.au
- // @connect gamtools-eu.aka.amazon.com
- // @connect gamtools-na.aka.amazon.com
- // @connect eagleeye-eu.amazon.com
- // @connect eagleeye-na.amazon.com
- // @connect geoweb-eu.amazon.com
- // @connect geoweb-na.amazon.com
- // @connect amazonlogistics-eu.com
- // @connect amazonlogistics.com
- // @connect pandash.amazon.com
- // @connect corp.amazon.com
- // @connect last-mile.amazon.dev
- // @connect trans-logistics-eu.amazon.com
- // @connect trans-logistics.amazon.com
- // @connect routingtools-viz-dub.dub.proxy.amazon.com
- // @connect routingtools-viz-iad.iad.proxy.amazon.com
- // @connect transportation-taxonomy-dub.aka.amazon.com
- // @connect transportation-taxonomy-iad.aka.amazon.com
- // @connect hero.eu.picking.aft.a2z.com
- // @connect hero.na.picking.aft.a2z.com
- // @connect trans-app-prod-eu.amazon.com
- // @connect trans-app-prod-na.amazon.com
- // @connect honeypot.amazon.dev
- // @run-at document-end
- // ==/UserScript==
- //#region Utilities/Types
- /// <reference path="./GM.d.ts" />
- /// <reference path="./simple-dom.d.ts" />
- /// <reference path="./Improve-SCC.d.ts" />
- const { _, _svg, $, $$, wait$, delay, _css, O, dict, lock } = simpleDOM;
- const
- /** @type {<A extends unknown[]>(...bindArgs: A) => <R extends unknown>(cb: (...boundArgs: A) => R) => R} */
- bindWith = (...args) => (cb) => cb(...args),
- /** @type {(href:string, filename?:string)=>void} */
- download = (href, filename) => _('a', { href, download: filename ?? "" }).do('click').remove();
- //#endregion
- //#region: Config data
- const
- debug = GM_getValue('debugMode', false),
- ver = GM.info.script.version,
- s = dict({
- en: {
- //Script Name broken into 3 pieces Text before phonetool link, phonetool link, and text after phonetool link
- scriptNameBefore: 'Improve SCC Script by ',
- scriptNameAfter: '',
- translatedBy: 'Translated by {{name}}',
- translatorName: 'David King',
- translatorAlias: 'dkingamz',
- formatTable: 'Format History Table:',
- onRoadOption: 'On Road',
- inStationOption: 'In Station',
- pleaseWait: 'Please Wait',
- EagleEye: 'EagleEye',
- EagleEye2: 'EagleEye 2.0',
- getContents: 'Get Package Contents',
- CSC: 'CSC',
- SIM: 'Search SIM Issues',
- COMP: 'COMP',
- Hero: 'Hero',
- SlamOps: 'SlamOps',
- DEXTER: 'DEXTER',
- FixIt: 'Fixit Details & History (Rodeo)',
- TT: 'Troubleshooting Tool',
- OBLT: 'Outbound Lookup Tool',
- GDE: 'Geo Data Editor',
- oId: 'Order ID: ',
- customerId: 'Customer ID: ',
- sameOrderID: 'Same Order ID: ',
- shipMethod: 'Ship Method: ',
- shipOption: 'Ship Option: ',
- serviceType: 'Service Type: ',
- lTId: 'Linked Tracking ID: ',
- AVD: 'AVD',
- OTP: 'OTP',
- SIG: 'Signature',
- HAZMAT: 'HAZMAT',
- HV: 'High Value',
- VH: 'Very Heavy',
- H: 'Heavy',
- LB: 'Letterbox Sized',
- OVER: 'Oversize',
- metPDD: 'Met Promise Date',
- metEAD: 'Met Estimated Date',
- missPDD: 'Missed Promise Date',
- missEAD: 'Missed Estimated Date',
- calcText: '(approx. {{ft#}} / {{m#}} from delivery location', // move the {{}} in the sentence, these will be filled with the correct numbers
- BH: 'Business hours: ',
- Driver: 'Driver: ',
- Route: 'Route Code: ',
- RouteVis: 'Route Visualisation',
- RouteDiver: 'Route Diver',
- RouteEagle: 'RouteIQ: Eagle',
- cortexItinerary: 'Driver itinerary (Cortex)',
- cortexLinkRoute: 'Cortex (Route)',
- cortexLinkStop: 'Cortex (Stop {{stop#}})', // move the {{}} in the sentence, this will be filled with the correct number
- GAM: 'GAM Tools',
- Hours: 'Hours:',
- LockerStatus: 'Locker Status',
- LockerReserve: 'Locker Reservation',
- Address: 'Address',
- Locker: 'Locker',
- Counter: 'Counter',
- LatLon: 'Lat Lon',
- GAM404: 'Address not in GAM',
- GAMnoHours: 'No Hours in GAM',
- FailedAttempt: 'Failed Attempts:',
- GAMhint: 'GAM DELIVERY_HINT',
- qrCode: 'QR Code',
- viewPOD: 'View POD Images',
- honeypot: 'Honeypot',
- GCRS: 'GCRS',
- Passage: 'Passage',
- RoyalMail: 'Royal Mail',
- TransTax: 'Transportation Taxonomy',
- plannedTime: 'Planned Delivery Time: {{time}}', // move the {{}} in the sentence, this will be filled with the correct time
- plannedStartTime: 'Planned Start Time: {{time}}', // move the {{}} in the sentence, this will be filled with the correct time
- windowTime: 'Time Window: {{time}}', // move the {{}} in the sentence, this will be filled with the correct time
- delTo: 'Delivered To',
- NoHistData: 'No History Data: {{reason}}', // move the {{}} in the sentence, this will be filled with the correct reason
- NoSiteData: 'No Sitemap Data: {{reason}}', // move the {{}} in the sentence, this will be filled with the correct reason
- NoPackData: 'No Package Data: {{reason}}', // move the {{}} in the sentence, this will be filled with the correct reason
- NoGeoData: 'No Geo Data: {{reason}}', // move the {{}} in the sentence, this will be filled with the correct reason
- NoGAMData: 'No GAM Data: {{reason}}', // move the {{}} in the sentence, this will be filled with the correct reason
- },
- 'en-US': {
- RouteVis: 'Route Visualization',
- },
- de: {
- scriptNameBefore: 'Improve SCC Script von ',
- scriptNameAfter: '',
- translatedBy: 'Translated von {{name}}',
- translatorName: 'Stephanie Petke',
- translatorAlias: 'petke',
- formatTable: 'Format History Tabelle:',
- onRoadOption: 'On Road',
- inStationOption: 'In der Station',
- pleaseWait: 'Bitte warten',
- getContents: 'Inhalt anzeigen',
- metPDD: 'PDD eingehalten',
- metEAD: 'EAD eingehalten',
- missPDD: 'PDD verfehlt',
- missEAD: 'EAD verfehlt',
- calcText: '(ca. {{ft#}} / {{m#}} vom Geopunkt',
- BH: 'Öffnungszeiten: ',
- Hours: 'Uhrzeit:',
- LockerReserve: 'Locker Reservierung',
- Address: 'Adresse',
- LatLon: 'Breiten/Längengrad',
- GAM404: 'Addresse nicht in GAM',
- GAMnoHours: 'Keine Öffnungszeiten in GAM',
- FailedAttempt: 'fehlgeschlagene Zustellversuche:',
- },
- es: {
- translatedBy: 'Traducido por {{name}}',
- translatorName: 'Carlos de la Peña',
- translatorAlias: 'cacalzad',
- formatTable: 'Formato de tabla:',
- onRoadOption: 'En carretera',
- inStationOption: 'En estación',
- pleaseWait: 'Por favor espere',
- getContents: 'Obtener productos',
- FixIt: 'Detalles & Histórico FixIt (Rodeo)',
- GDE: 'Editor Geo Data',
- oId: 'Número de Pedido: ',
- shipMethod: 'Método de envío: ',
- lTId: 'Código ID relacionado: ',
- HV: 'Alto Valor',
- VH: 'Muy Pesado',
- H: 'Pesado',
- LB: 'Sobre',
- OVER: 'Voluminoso (Oversize)',
- metPDD: 'Fecha Entrega Prometida Cumplida',
- metEAD: 'Fecha Llegada Estimada Cumplida',
- missPDD: 'Fecha Entrega Prometida Fallada',
- missEAD: 'Fecha Entrega Estimada Fallada',
- calcText: '(aprox. {{ft#}} / {{m#}} del punto de entrga',
- BH: 'Horario de Apertura: ',
- RouteVis: 'Visualizador de Ruta',
- cortexItinerary: 'Itinerario del Conductor (Cortex)',
- cortexLinkRoute: 'Cortex (Ruta)',
- cortexLinkStop: 'Cortex (Parada {{stop#}})',
- Hours: 'Horario:',
- LockerStatus: 'Estado del locker',
- Address: 'Dirección',
- LatLon: 'Lat y Long',
- GAM404: 'Dirección no en GAM',
- GAMnoHours: 'Horario no en GAM',
- FailedAttempt: 'Intento de Entrega Fallido:',
- qrCode: 'Código QR ',
- plannedTime: 'Hora Prevista de Reparto: {{time}}',
- plannedStartTime: 'Planned Start Time: {{time}}',
- },
- fr: {
- translatorName: 'etifier, karl-emmanuel',
- translatorAlias: 'karleme',
- },
- it: {
- translatorName: 'Andrea La Rosa',
- translatorAlias: 'anrosam',
- formatTable: 'Formato Tabella Cronologica:',
- onRoadOption: 'In Transito',
- inStationOption: 'In Station',
- pleaseWait: 'Prego Attendere',
- getContents: 'Vedi Contenuto Pacco',
- FixIt: 'Dettaglio e Cronologia da Fixit (Rodeo)',
- oId: 'ID Ordine: ',
- lTId: 'Tracking Id Collegato: ',
- HV: 'Alto Valore',
- VH: 'Molto Pesante',
- H: 'Pesante',
- LB: 'Tasca Di Libro',
- metPDD: 'Data Promessa Corretta',
- metEAD: 'Data Stimata Corretta',
- missPDD: 'Data Promessa Mancata',
- missEAD: 'Data Stimata Mancata',
- calcText: '(appross. {{ft#}} / {{m#}} dall\'indirizzo di spedizione',
- BH: 'Orario d\'Apertura: ',
- RouteVis: 'Visualizza Rotta',
- cortexLinkRoute: 'Cortex (Rotta)',
- cortexLinkStop: 'Cortex (Fermata {{stop#}})',
- Hours: 'Orario Tentativi:',
- LockerStatus: 'Stato del Locker',
- LockerReserve: 'Locker Reservation',
- Address: 'Indirizzo',
- LatLon: 'Lat e Lon',
- GAM404: 'Indirizzo non in GAM',
- GAMnoHours: 'Orario non in GAM',
- FailedAttempt: 'Tentativi di Consegna Falliti:',
- },
- jp: {
- translatedBy: 'Translated by {{name}}',
- translatorName: 'Saki Uchida',
- translatorAlias: 'duchidsa',
- }
- }),
- /** Strings that must match what's already in SCC so that the script can detect it. */
- searchStrings = {
- en: {
- //Search/Package details
- searchHeader: 'Search', //The header at the top of the search page
- packageHeader: 'Package', //(partial match)The header at the top of the detail (search results) page
- GAMdays: '|SUN|MON|TUE|WED|THU|FRI|SAT|', //Days as seen in GAM Business Hours separated by |. I've tested and it seems these will probably match english.
- ShipMethod: 'Ship Method', //Search results column header
- //Outbound > Pick/Stage tabs
- associate: 'Associate',
- cartID: 'Cart ID',
- driver: 'Driver',
- //Problem Solve tabs
- Reportedby: 'Reported by'
- },
- de: {
- //Search/Package details
- searchHeader: 'Suche',
- packageHeader: 'Paket',
- ShipMethod: 'Ship Method',
- //Outbound > Pick/Stage tabs
- associate: 'Mitarbeiter',
- cartID: 'Wagen-ID',
- //Problem Solve tabs
- Reportedby: 'Reported by'
- },
- es: {
- //Search/Package details
- searchHeader: 'Búsqueda',
- packageHeader: 'Paquete',
- ShipMethod: 'Ship Method',
- //Outbound > Pick/Stage tabs
- associate: 'Asociado',
- cartID: 'Código ID Carro',
- //Problem Solve tabs
- Reportedby: 'Reportado por'
- }, fr: {
- //Search/Package details
- searchHeader: 'Rechercher',
- packageHeader: 'Colis',
- ShipMethod: 'Ship Method',
- //Outbound > Pick/Stage tabs
- associate: 'Associé',
- cartID: 'ID de l\'itinéraire',
- //Problem Solve tabs
- Reportedby: 'Signalé par'
- },
- it: {
- //Search/Package details
- searchHeader: 'Cerca',
- packageHeader: 'Pacco',
- ShipMethod: 'Ship Method',
- //Outbound > Pick/Stage tabs
- associate: 'Associate',
- cartID: 'ID carrello',
- //Problem Solve tabs
- Reportedby: 'Reported by'
- },
- jp: {
- //Search/Package details
- searchHeader: '検索',
- packageHeader: 'パッケージ',
- ShipMethod: 'パッケージ概要',
- //Outbound > Pick/Stage tabs
- associate: 'アソシエイト',
- cartID: 'ルートID',
- driver: 'ドライバー',
- //Problem Solve tabs
- Reportedby: '修正対象'
- }
- },
- /** @type {string[]} */
- logData = [],
- /** @type {(...log: any[]) => void} */
- debuglog = debug ? (...log) => {
- logData.push(`${Date.now()}: ${log.map(line => {
- try { return JSON.stringify(line); } catch (e) { return line.toString(); }
- }).join('\n\t')}`);
- console.log(location.origin, '[Improve-SCC]', ...log);
- } : (...log) => { },
- superlog = debug ? debuglog : console.log,
- mutationComment = document.createComment("Mutate");
- //#endregion
- //#region: Global Defaults, State, and Constants
- let
- /** @type {PageInfo} */ page,
- /** @type {SCCPromises} */ promises,
- /** @type {WindowProxy?} */ midwayWindow = null,
- /** @type {string?} */ globalOrigin,
- /** @type {Notification?} */ notification;
- function defaults() {
- debuglog('defaults()');
- page = { url: window.location.href.split('/') };
- promises = /** @type {SCCPromises} */ ({});
- midwayWindow = null;
- }
- const now = new Date().getTime();
- //#endregion
- //#region: Prototypes and DOM Functions
- const
- /** @type {FormatterFunction} */
- dateTimeFormatter = options => {
- const /** @type {Record<string, Intl.DateTimeFormat>} */ cache = {};
- return (value, timeZone) => ((`${timeZone}`) in cache ? cache[`${timeZone}`] : (cache[`${timeZone}`] = new Intl.DateTimeFormat(navigator.languages, { ...options, timeZone }))).format((typeof value === 'string') ? new Date(value) : value);
- },
- toLocaleTZString = dateTimeFormatter({ hour: '2-digit', minute: '2-digit', second: '2-digit', }),
- toWeekdayDateString = dateTimeFormatter({ weekday: "short", year: "2-digit", month: "2-digit", day: "2-digit", }),
- toWeekdayDateTimeString = dateTimeFormatter({ weekday: "short", year: "2-digit", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: '2-digit' });
- class ExtendedDate extends Date {
- toISODateString() { return `${this.getFullYear()}-${(this.getMonth() + 1).toString().padStart(2, "0")}-${this.getDate().toString().padStart(2, "0")}`; }
- toISODateTimeString() { return `${this.toISODateString()} ${this.getHours().toString().padStart(2, "0")}:${this.getMinutes().toString().padStart(2, "0")}:${this.getSeconds().toString().padStart(2, "0")}`; }
- /** @type {DateToString} */
- toYMDKey(timeZone) { return `${this.toLocaleString('en-GB', { timeZone, year: 'numeric' })}${this.toLocaleString('en-GB', { timeZone, month: '2-digit' })}${this.toLocaleString('en-GB', { timeZone, day: '2-digit' })}`; }
- toMidnightLocal() { return new Date(this.getFullYear(), this.getMonth(), this.getDate()).valueOf(); }
- };
- /** @type {(value?: number | string | Date) => ExtendedDate} */
- const D = (value) => value ? new ExtendedDate(value) : new ExtendedDate();
- class ExtendedString extends String {
- /** @type {TestString} */
- in(test) { return test.toLowerCase().includes(this.toLowerCase()); }
- /** @type {TestString} */
- contains(test) { return this.toLowerCase().includes(test.toLowerCase()); }
- /** @type {(...tests: string[]) => boolean} */
- containsAny(...tests) { return tests.reduce((bool, test) => bool || this.contains(test), false); }
- toSentenceCase() { return `${this.charAt(0).toUpperCase()}${this.slice(1).toLowerCase()}`; }
- toWordCase() { return this.toLowerCase().replace(/(^|\s)\S/g, letter => letter.toUpperCase()); }
- /** @type {TestString} */
- inDict(key) { return O(searchStrings).reduce((bool, [_, langDict]) => (bool || this.in(langDict[key])), false); }
- /** @type {TestString} */
- dictContains(key) { return O(searchStrings).reduce((bool, [_, langDict]) => (bool || this.contains(langDict[key])), false); };
- }
- /** @type {(value: any) => ExtendedString} */
- const S = (value) => new ExtendedString(value);
- const /** @type {(test: string)=>boolean} */ hrefContains = (test) => S(location.href).contains(test);
- // Cortex auth/signing code provided by Dennis Leonhardt (leoden@)
- let /** @type {CortexSession | undefined} */ cortexAuthPromise = undefined;
- /** @type {()=>CortexSession} */
- const initializeCortexAuth = () => cortexAuthPromise ?? (cortexAuthPromise = XHR('GET', `${globalOrigin}/internal/operations/execution`).then(
- (response) => new Promise((resolve) => ([...new DOMParser().parseFromString(response.text, 'text/html').querySelectorAll('script[type="a-state"][data-a-state*="hmacSession"]')].reduce((flagFound, script) => {
- if (flagFound) return flagFound;
- const data = JSON.parse(script.textContent.trim());
- if (!(data.hmacSession && data.hmacSession.enabled)) return false;
- crypto.subtle.importKey(
- 'raw',
- new TextEncoder().encode(data.hmacSession.sessionKey),
- { name: 'HMAC', hash: 'SHA-256' },
- false,
- ['sign']
- ).then(cryptoKey => (debuglog(data.hmacSession), resolve({ sessionKey: data.hmacSession.sessionKey, sessionId: data.hmacSession.sessionId, cryptoKey })));
- return true;
- }, false)))
- ).catch(
- error => debuglog('Cortex authentication failed:', error)
- ));
- /** @type {(method: "GET"|"POST", url: string, json?: any) => Promise<XHRResponse>} */
- const XHR = (method, url, json) => (!globalOrigin || !url.includes(globalOrigin) || location.origin === globalOrigin) ? systemXHR(method, url, json) : new Promise((resolve, reject) => {
- debuglog(`${method} XHR Request: ${url}`, json);
- const id = `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 10)}`,
- /** @type {(data:any)=>void} */ handler = ({ data }) => {
- if (data.method !== 'XHR') return;
- if (data.id !== id) return;
- debuglog(`${data.response.status} XHR Response: ${url}`, data.response);
- window.removeEventListener("message", handler);
- (data.response.ok ? resolve : reject)({ ...data.response, json: () => JSON.parse(data.response.text) });
- };
- debuglog('Posting XHR', id, url);
- window.addEventListener("message", handler);
- window.parent.postMessage({ method: 'XHR', id, params: { method, url, json } }, globalOrigin ?? '');
- });
- /** @type {(method: "GET"|"POST", url: string, json?: any) => Promise<XHRResponse>} */
- const systemXHR = (method, url, json) => new Promise((resolve, reject) => {
- debuglog(`${method} XHR Request: ${url}`, json);
- /** @type {XHROptions} */
- const options = {
- method, url, onload: (response) => {
- debuglog(`${response.status} XHR Response: ${url}`, response.responseText);
- const r = {
- status: response.status,
- statusText: response.statusText,
- text: response.responseText,
- ok: response.status >= 200 && response.status <= 299,
- json: () => JSON.parse(response.responseText)
- };
- (r.ok ? resolve : reject)(r);
- },
- headers: {}
- };
- json !== null && (options.headers['Content-Type'] = 'application/json', options.data = (typeof json) === 'string' ? json : JSON.stringify(json));
- // Cortex auth/signing code provided by Dennis Leonhardt (leoden@)
- (url.includes(`${globalOrigin}/internal/operations/execution/api`) ? initializeCortexAuth().then(({ sessionId, cryptoKey }) => {
- const { pathname, searchParams } = new URL(url), timestamp = Date.now().toString();
- return crypto.subtle.sign(
- 'HMAC',
- cryptoKey,
- new TextEncoder().encode([
- method,
- pathname,
- searchParams.toString(),
- `x-cortex-session:${sessionId}`,
- `x-cortex-timestamp:${timestamp}`,
- '',
- 'x-cortex-session;x-cortex-timestamp'
- ].join('\n'))
- ).then(signature => {
- options.headers['X-Cortex-Hmac-Signature'] = btoa(String.fromCharCode(...new Uint8Array(signature)));
- options.headers['X-Cortex-Session'] = sessionId;
- options.headers['X-Cortex-Timestamp'] = timestamp;
- }).finally(() => debuglog(`${method} XHR Headers: ${url}`, options.headers));
- }) : Promise.resolve()).then(() => {
- GM.xmlHttpRequest(options);
- delay(10).then(() => reject(`Timed-out: ${method} ${url}`));
- }, reject);
- });
- /** @type {<T>({json}:{json:()=>T})=>T} */
- const json = ({ json }) => json();
- const
- unitMap = { cm: 'centimeter', kg: 'kilogram' },
- /** @type {({value, unit}:{value:number, unit:string})=>string} */
- formatUnit = ({ value, unit }) => {
- try {
- if (unit in unitMap) unit = unitMap[unit];
- return new Intl.NumberFormat(navigator.languages, { style: 'unit', unit }).format(value).replace(/\s/g, '\u00A0');
- } catch (e) {
- debuglog(e);
- return `${value}_${unit}`;
- }
- },
- /** @type {({value, currency}:{value:number, currency:string})=>string} */
- formatCurrency = ({ value, currency }) => {
- try {
- return new Intl.NumberFormat(navigator.languages, { style: 'currency', currency }).format(value).replace(/\s/g, '\u00A0');
- } catch (e) {
- debuglog(e);
- return `${value}_${currency}`;
- }
- };
- //#endregion
- //#region: Pages and Tabs
- function startup() {
- wait$('html').then(() => {
- if (hrefContains('logistics.amazon.')) return SCCStartup();
- document.documentElement.dataset.improveSccCssIframe = '';
- window.addEventListener("message", ({ data }) => {
- switch (data.method) {
- case 'sendDarkModeStatus': return void (document.documentElement.dataset.improveSccCssDarkMode = data.childData.capability);
- case 'sendOrigin': return void (globalOrigin = data.childData);
- case 'sendLocaleResponse': return;
- default:
- debuglog('postMessage', data);
- }
- });
- new Promise((resolve) => {
- const interval = setInterval(() => {
- if (!globalOrigin) return;
- clearInterval(interval);
- resolve(globalOrigin);
- debuglog('Origin:', globalOrigin);
- }, 500);
- }).then(initialise);
- });
- }
- function SCCStartup() {
- document.documentElement.dataset.improveSccCssNoframe = '';
- globalOrigin = location.origin;
- console.log(`%c${s('scriptNameBefore')} David King (dkingamz@) ${s('scriptNameAfter')} %c${ver}`, 'font-size: 200%; font-weight: bold;', 'font-size: 200%; color: red; text-decoration: underline;');
- console.log(`%c${s('translatedBy').replace('{{name}}', `${s('translatorName')} (${s('translatorAlias')}@)`)}`, 'font-size: 150%');
- console.log(`%cFormatting: ${new Intl.ListFormat(navigator.languages, { type: 'conjunction' }).format(navigator.languages.map(lang => new Intl.DisplayNames(navigator.languages, { type: 'language' }).of(lang)).filter(lang => lang !== undefined))}`, 'font-size: 125%; color: cyan;');
- wait$('.boson-meridian-frame-dimension', { style: { top: '' } });
- wait$('#main_row').then(mainRow => {
- const verdiv = _('div', { id: 'verdiv' })._(_('strong')._(
- s('scriptNameBefore'), _('a', { href: 'https://phonetool.amazon.com/users/dkingamz', target: '_blank' })._('David King (dkingamz@)'), s('scriptNameAfter'), `\u2003 ${ver}`,
- )).on('click', () => verdiv.classList.toggle('hidden'));
- mainRow._(verdiv);
- new MutationObserver(() => {
- $$('iframe', { attributeList: { 'allow': 'clipboard-write https://ui.package-summary-eu.last-mile.amazon.dev https://ui.package-summary-na.last-mile.amazon.dev https://onebox.ui.package-summary-eu.last-mile.amazon.dev https://onebox.ui.package-summary-na.last-mile.amazon.dev;' } });
- }).observe(mainRow, { characterData: false, attributes: false, childList: true, subtree: true });
- });
- wait$('ul[role=tree]').then(ul => {
- $("#Help > div > span")?._(' (River)');
- const updateAvailableLi = _('li');
- let lastCheckDate, /** @type {string?}*/ master;
- const updateAvailable = () => {
- updateAvailableLi.__(master && GM.info.script.downloadURL && (ver == master ? null : _('a', { href: GM.info.script.downloadURL, target: '_blank', classList: ['css-11g0wa3'] })._(_('div', { classList: ['css-1u8dqdz'] })._(_('span', { classList: ['css-1bkd0di'] })._(`Update to version ${master}`)))));
- }, updateCheck = () => GM.info.script.downloadURL ? XHR('GET', GM.info.script.downloadURL).then(response => {
- master = (/@version\s+(.*)/i.exec(response.text) ?? '')[1];
- debuglog(`masterVer: ${master}`);
- if (!master) return;
- localStorage.setItem('ImproveSCCupdateTimestamp', `${Date.now()}`);
- localStorage.setItem('ImproveSCCmaster', master);
- }) : Promise.resolve();
- ((master = localStorage.getItem('ImproveSCCmaster')) && ((lastCheckDate = localStorage.getItem('ImproveSCCupdateTimestamp')) && Number(lastCheckDate) > Date.now() - 24 * 60 * 60 * 1000) ? () => Promise.resolve() : updateCheck)().then(updateAvailable);
- ul._(
- ($('#dkingamzNav') || _('div', { id: 'dkingamzNav' })).__(
- _('strong')._(s('scriptNameBefore'), _('a', { href: 'https://phonetool.amazon.com/users/dkingamz', target: '_blank' })._('David King (dkingamz@)'), s('scriptNameAfter'), `\u2003 ${ver}`,),
- _('li')._(_('button', { classList: ['css-11g0wa3'] })._(_('div', { classList: ['css-1u8dqdz'] })._(_('span', { classList: ['css-1bkd0di'] })._('Check For Updates'))).on('click', () => updateCheck().then(updateAvailable))),
- updateAvailableLi,
- _('li')._(_('a', { href: 'https://axzile.corp.amazon.com/-/carthamus/download_script/improve-scc-show-top-nav-menu.user.js', target: '_blank', classList: ['css-11g0wa3'] })._(_('div', { classList: ['css-1u8dqdz'] })._(_('span', { classList: ['css-1bkd0di'] })._('Show Top Nav Menu')))),
- _('li')._(_('button', { classList: ['css-11g0wa3'] })._(_('div', { classList: ['css-1u8dqdz'] })._(_('span', { classList: ['css-1bkd0di'] })._(`Toggle Debug Mode ${debug ? 'Off' : 'On'}`))).on('click', () => GM.setValue('debugMode', !debug).then(() => location.reload(true)))),
- debug && _('li')._(_('button', { classList: ['css-11g0wa3'] })._(_('div', { classList: ['css-1u8dqdz'] })._(_('span', { classList: ['css-1bkd0di'] })._('Export Improve-SCC Sidebar logs'))).on('click', () => {
- const modal = _('dialog', { style: { background: 'canvas' } })._(
- _('div', { id: 'debugModalButtons' })._(
- _('button')._('Export').on('click', () => bindWith(URL.createObjectURL(new Blob([logData.join('\n')], { type: 'text/plain' })))(blobUrl => (download(blobUrl, `Improve-SCC-Log-Export${Date.now()}.txt`), URL.revokeObjectURL(blobUrl)))),
- _('button')._('Close').on('click', () => modal.close()),
- ),
- ...logData.map(line => _('div')._(line)),
- ).on('close', () => modal.remove());
- $('body')?._(modal);
- queueMicrotask(() => modal.showModal());
- })),
- _('li')._(_('a', { href: 'https://sim.amazon.com/issues/create?template=5ee8e705-a508-4820-86f4-1d87b978d630', target: '_blank', classList: ['css-11g0wa3'] })._(_('div', { classList: ['css-1u8dqdz'] })._(_('span', { classList: ['css-1bkd0di'] })._('Create SIM', _('br'), _('small')._('Improve SCC Script'))))),
- )
- );
- });
- wait$('body').then(body => {
- (new MutationObserver(() => (document.documentElement.dataset.improveSccCssDarkMode = body.classList.contains('dark-mode') ? 'dark' : 'light'))).observe(body, { attributes: true, subtree: false, childList: false, characterData: false });
- debug && body._(_('iframe', {
- dataset: { debug: '' },
- srcdoc: `<html><head><meta name="color-scheme" content="light dark"><style>:root{background:canvas}</style></head><body>${Date.now()}<br/>SCC: ${globalOrigin}<br/>UA: ${navigator.userAgent}<br/>Default Language: ${navigator.language}<br/>All Languages: ${JSON.stringify(navigator.languages)}</body></html>`,
- style: { position: 'fixed', insetInlineEnd: '1rem', insetBlockEnd: '1rem', width: '36rem', height: '12rem' }
- }));
- });
- hrefContains('/search') && (document.documentElement.dataset.improveSccCssHideAlerts = '');
- navigator.languages.includes('en-GB') && Promise.all([wait$('title'), wait$('h4')]).then(texts => texts.forEach(text => (text.textContent = text.textContent?.replace('Center', 'Centre') ?? 'SCC')));
- const iframe = () => wait$('iframe', undefined, 2).then(iframe => ({ contentWindow: iframe.contentWindow, origin: new URL(iframe.src).origin })).catch((...e) => { throw debuglog('Selecting iFrame', ...e); });
- window.addEventListener("message", ({ data }) => {
- switch (data.method) {
- case 'XHR':
- Promise.all([systemXHR(data.params.method, data.params.url, data.params.json).catch(r => r), iframe()]).then(([{ json, ...response }, { contentWindow, origin }]) => contentWindow?.postMessage({ method: 'XHR', id: data.id, response }, origin));
- break;
- case 'requestUsername':
- // wait$('iframe').then(iframe => iframe.contentWindow?.postMessage({ method: "sendUsername", childData: sessionStorage.getItem('boson.tcpEmployeeLogin') }, new URL(iframe.src).origin));
- break;
- default:
- debuglog('postMessage', data);
- }
- });
- setInterval(() => iframe().then(({ contentWindow, origin }) => contentWindow?.postMessage({ method: "sendOrigin", childData: globalOrigin }, origin)), 1000);
- }
- function initialise() {
- defaults();
- debuglog('initialise()');
- wait$('body').then(body => {
- const oldURL = window.location.href;
- new MutationObserver((_, observer) => {
- // debuglog(`${oldURL} - ${window.location.href}`);
- if (oldURL != window.location.href && !(hrefContains('receive'))) {//hrefContains('ui.package-summary-')) {
- observer.disconnect();
- window.ImproveSCC = false;
- startup();
- }
- }).observe(body, { characterData: true, attributes: false, childList: true, subtree: true });
- debug && body._(_('button', { id: 'exportLogs', style: { background: 'canvas' } })._('Export Improve-SCC Page logs').on('click', () => {
- const modal = _('dialog', { style: { background: 'canvas' } })._(
- _('div', { id: 'debugModalButtons' })._(
- _('button')._('Export').on('click', () => bindWith(URL.createObjectURL(new Blob([logData.join('\n')], { type: 'text/plain' })))(blobUrl => (download(blobUrl, `Improve-SCC-Log-Export${Date.now()}.txt`), URL.revokeObjectURL(blobUrl)))),
- _('button')._('Close').on('click', () => modal.close()),
- ),
- ...logData.map(line => _('div')._(line)),
- ).on('close', () => modal.remove());
- body._(modal);
- queueMicrotask(() => modal.showModal());
- }));
- });
- if (hrefContains('/settings')) return;
- if (hrefContains('ui.package-summary-')) {
- page.region = window.location.href.split('ui.package-summary-')[1].split('.')[0];
- page.region == 'in' && (page.region = 'eu');
- page.regionCode = { na: 'iad', eu: 'dub', fe: 'PDX', cn: 'PEK' }[page.region];
- if (!hrefContains('packageSearch') && (hrefContains('ageingBoard') || hrefContains('scrubBoard'))) return void debuglog('kill searchLoad()');
- sessionStorage.setItem('loadCount', `${Number(sessionStorage.getItem('loadCount')) + 1}`);
- if (!(document?.featurePolicy?.allowsFeature?.('clipboard-write') ?? true)) { if (Number(sessionStorage.getItem('loadCount')) < 5) { location.reload(); return; } } else { sessionStorage.setItem('loadCount', '0'); }
- wait$('h1, h2, h3, table', undefined, 12).then(h => {
- debuglog(`main(${h.innerText})`);
- if (S(h.innerText).inDict('searchHeader')) return queueMicrotask(searchPage);
- if (S(h.innerText).dictContains('packageHeader')) return queueMicrotask(detailPage);
- }).catch(() => (debuglog("Can't find header… Reloading"), (debug ? confirm("Can't find header\n\nReload") : true) && location.reload(true)));
- return;
- }
- if (hrefContains('associate')) return associate();
- if (hrefContains('ui.pvs') || hrefContains('ui.stagewebsite') || hrefContains('outbound')) return outbound();
- if (hrefContains('ui.ivs') || hrefContains('prod.svs')) return associate();
- if (hrefContains('node-exceptions')) return psTab();
- if (hrefContains('sort-paths')) return;
- }
- async function detailPage() {
- if (promises.detailPage) return;
- promises.detailPage = true;
- page.trackingId = await wait$('h1').then((h1) => wait$('h1 > span').then(() => h1.lastChild?.textContent?.trim()));
- superlog(`-${page.trackingId}-`);
- debuglog('detailPage()');
- document.documentElement.dataset.improveSccCssDetailsPage = '';
- $('ul.css-1duca4b')?.__(historyFormatMenu().menuElement);
- promises.topBar = new Promise(resolve => {
- const improveBox = $('div#improveRoot') || _('div', { id: 'improveRoot' }), improveBoxes = {};
- wait$('#root [role=tablist]').then(tabList => tabList.before(improveBox));
- improveBox.__(
- improveBoxes.head = _('div', { id: 'improveHead' }),
- improveBoxes.items = _('div'),
- improveBoxes.transport = _('div', { id: 'transport' })._(improveBoxes.van = _('div')),
- improveBoxes.gam = _('div', { id: 'gamrow' }),
- improveBoxes.buttons = _('div', { id: 'buttons' }),
- improveBoxes.podContainer = _('div', { id: 'podContainer' }),
- improveBoxes.taxonomyError = _('div', { id: 'taxonomyError', classList: ['errMsg'] }),
- improveBoxes.histTableError = _('div', { id: 'histTableError', classList: ['errMsg'] })
- );
- resolve(improveBoxes);
- });
- promises.sitemap = siteMap();
- promises.geo = getGeoData();
- promises.package = getPackageData();
- promises.gam = promises.package.then(getGAMData);
- // promises.oblt = getOBLT();
- promises.package.then(addrbuts);
- promises.boxes = Promise.all([promises.topBar, promises.package]).then(usePackageData);
- promises.topBar.then((improveBoxes) => {
- XHR('POST', `${globalOrigin}/station/proxyapigateway/data`, { resourcePath: '/os/batchGetPackageSummary', httpMethod: 'post', processName: 'oculus', requestBody: { idType: 'TRACKING_ID', identifiers: [page.trackingId], includeFields: [] } }).then(json).then(({ packageSummaryList }) => packageSummaryList[0]).then(packageDetailData => {
- improveBoxes.van.__(
- packageDetailData.driverId && _('strong')._(packageDetailData.driverId),
- packageDetailData.currentRouteCode && _('span')._(`Route: ${packageDetailData.currentRouteCode}`),
- packageDetailData.routeSequence && _('span')._(`Route Sequence: ${packageDetailData.routeSequence}`),
- (packageDetailData.vehicleStopNumber || packageDetailData.taskStopNumber) && _('span')._(`Van Stop: ${packageDetailData.vehicleStopNumber}-(${packageDetailData.taskStopNumber})`)
- );
- });
- });
- promises.topBar.then(() => {
- specialButtons();
- // _('button')._().on('click', () => buttonclick(`https://honeypot.amazon.dev/?id=${page.trackingId}&searchType=TRACKING_ID&imageType=PHOTO_ON_DELIVERY®ion=${AWS_POD_REGION_MAPPING[page.region]}&tab=pod-search`)),
- addButton(`https://honeypot.amazon.dev/?id=${page.trackingId}&searchType=TRACKING_ID&imageType=PHOTO_ON_DELIVERY®ion=${AWS_POD_REGION_MAPPING[page.region ?? '']}&tab=pod-search`, s('honeypot'), -1, { id: 'Honeypot' });
- addButton(`https://sim.amazon.com/issues/search?q=(${page.trackingId})&sort=lastUpdatedConversationDate`, s('SIM'), -1, { id: 'SIM' });
- addButton(`https://siw-${page.region}-${page.regionCode}.${page.regionCode}.proxy.amazon.com/query#${page.trackingId}`, s('GCRS'), 2, { name: 'GCRSsearch' });
- addButton(`https://${page.region}.geostudio.last-mile.amazon.dev/?searchId=${page.trackingId}#background=MAPNIK`, 'GeoStudio', 2);
- addButton(`https://${page.region}.geostudio.last-mile.amazon.dev/place?searchId=${page.trackingId}`, 'GeoStudio 2.0', 2);
- if (page.region == 'na') addButton(`https://ate-portal-na.amazon.com/single/getAttributes?inputId=${page.trackingId}&inputIdType=Tracking%20Id`, 'ATE Portal', 2);
- });
- Promise.all([promises.topBar, promises.package]).then(([_, packageData]) => addButton(`https://trans-logistics${(page.region != 'na' ? `-${page.region}` : '')}.amazon.com/sortcenter/tantei?nodeId=${packageData.routeInfo.stationCode}&searchType=Container&searchId=${page.trackingId}`, s('TT'), 2));
- Promise.all([promises.boxes, promises.geo]).then(useGeoData);
- Promise.all([promises.topBar, promises.gam, promises.histPromise]).then(useGAMData);
- // Promise.all([promises.topBar, promises.oblt]).then(useOBLTData);
- // promises.oblt.catch((e) => promises.boxes?.then(improveBoxes => improveBoxes.customerId.__('OBLT Error', e)));
- wait$('#root').then(root => {
- debuglog('DetailMutationObserver');
- new MutationObserver((_, observer) => {
- if ($('#SCC_Search_CONFIG') && $('h1, h2')) return void (($('table:not([data-improve-scc=true]')) && setTimeout(histTable));
- observer.disconnect();
- initialise();
- }).observe(root, { characterData: true, attributes: false, childList: true, subtree: true });
- }).then(() => {
- debuglog('clicking History button');
- Promise.all([wait$('.css-1gnngbt > .css-r8kn69'), wait$('[role=tablist] label:nth-of-type(4)')]).then(([_, label]) => label.do('click'));
- });
- }
- function searchPage() {
- debuglog('searchPage()');
- document.documentElement.dataset.improveSccCssSearchPage = '';
- wait$('#root .css-1gnngbt').then(searchArea => {
- debuglog('SearchMutationObserver');
- new MutationObserver(() => {
- const resultsTable = $('table');
- if (!resultsTable || resultsTable.dataset.improveScc == 'true' || resultsTable.$$('tr').length <= 1) return;
- resultsTable.dataset.improveScc = 'true';
- const /** @type {string[]} */trackingIdList = [];
- const /** @type {Record<String,Extended<HTMLTableRowElement>>} */ rowMap = {}, methodColumn = resultsTable.$$('th').reduce((/**@type {false | number}*/methodColumn, th, i) => methodColumn || S(th.innerText).dictContains('ShipMethod') && (i + 1), false);
- resultsTable.$$('tr').forEach(tr => {
- const a = tr.$('a');
- if (!a) return;
- debuglog(a.innerText);
- rowMap[a.innerText] = tr;
- trackingIdList.push(a.innerText);
- methodColumn && colourResult(tr.$(`td:nth-of-type(${methodColumn})`)?.innerText, tr);
- });
- if (methodColumn) return;
- XHR('POST', `${globalOrigin}/station/proxyapigateway/data`, {
- resourcePath: '/os/batchGetPackageSummary',
- httpMethod: 'post',
- processName: 'oculus',
- requestBody: {
- idType: 'TRACKING_ID',
- identifiers: trackingIdList,
- nodeId: (/.*stationCode=([A-Z0-9]+).*/.exec(page.url[3]) ?? '')[1],
- includeFields: []
- }
- }).then(json).then(searchResult => searchResult.packageSummaryList.forEach((resultRow) => {
- debuglog(`${resultRow.trackingId} - ${resultRow.shipMethod} - ${resultRow.shipOption}`);
- colourResult(resultRow.shipMethod, rowMap[resultRow.trackingId]);
- rowMap[resultRow.trackingId].dataset.exchangeId = resultRow.exchangeId;
- }));
- }).observe(searchArea, { characterData: true, attributes: false, childList: true, subtree: true });
- });
- }
- /** @type {(text: string, dateTime: string?, type?: string?) => void} */
- function newCustNote(text, dateTime, type) {
- promises.boxes?.then((improveBoxes) => {
- if (!S(improveBoxes.notes.textContent).contains(text)) {
- improveBoxes.notes._(custNoteDiv(text, dateTime, type));
- }
- });
- }
- /** @type {(text: string, dateTime: string?, type?: string?) => Extended<HTMLDivElement>} */
- function custNoteDiv(text, dateTime, type) {
- return _('div')._(S(text).contains('dog') && _('span', { style: { fontSize: '2em' } })._('\uD83D\uDC3A'), ...(dateTime ? [toWeekdayDateString(dateTime), '\u2003-\u2003'] : []), type ? `${type}\u2003-\u2003` : undefined, text);
- }
- const historyTableLock = lock('history-table'), histTable = () => historyTableLock(() => (debuglog('histTable()'), Promise.allSettled([
- wait$('table:not([data-improve-scc-table])', { dataset: { improveSccTable: '' } }, 20),
- getHistoryData(),
- promises.sitemap,
- promises.package,
- promises.geo,
- promises.gam
- ]).then(([tablePromise, histPromise, sitePromise, packPromise, geoPromise, gamPromise]) => {
- debuglog('histTable() allSettled', { status: tablePromise.status }, histPromise, sitePromise, packPromise, geoPromise, gamPromise);
- if (tablePromise.status == 'rejected') throw `Could not find history table\n\t${JSON.stringify(tablePromise.reason)}`;
- if (histPromise.status == 'rejected') throw (debuglog('History Promise Failed… Reloading'), /*(debug ? confirm('History Promise Failed\n\nReload') : true) && location.reload(true),*/ `Could not get history data\n\t${JSON.stringify(histPromise.reason)}`);
- if (packPromise.status == 'rejected') throw (debuglog('Package Promise Failed… Reloading'), /*(debug ? confirm('Package Promise Failed\n\nReload') : true) && location.reload(true),*/ `Could not get package data\n\t${JSON.stringify(packPromise.reason)}`);
- const historytable = tablePromise.value,
- historyData = histPromise.value,
- sitemap = sitePromise.status == 'fulfilled' ? sitePromise.value.data : undefined,
- packageData = packPromise.value,
- geoData = geoPromise.status == 'fulfilled' && geoPromise.value,
- gamData = gamPromise.status == 'fulfilled' && gamPromise.value;
- if (historytable.dataset.improveScc == 'true') return; historytable.dataset.improveScc = 'true';
- debuglog(historytable);
- const logBox = _('th', { colSpan: 99 });
- historytable._(
- _('thead')._(_('tr')._(_('th', { colSpan: 99 })._(
- sitePromise.status == 'rejected' && _('div')._(s('NoSiteData').replace('{{reason}}', JSON.stringify(sitePromise.reason))),
- geoPromise.status == 'rejected' && _('div')._(s('NoGeoData').replace('{{reason}}', JSON.stringify(geoPromise.reason))),
- // gamPromise.status == 'rejected' && _('div')._(s('NoGAMData').replace('{{reason}}', JSON.stringify(gamPromise.reason)))
- ))),
- _('tfoot')._(_('tr')._(logBox))
- );
- historytable.dataset.colours = JSON.parse(localStorage.getItem('SCC_Search_CONFIG') ?? '{}').colours ?? 'OnRoad';
- historytable.$$('tr:not(:first-child)').forEach((tr, i) => {
- const thisRow = tr.$$('td'), timestamp = D(historyData[i].stateTime);
- Object.assign(historyData[i], {
- timestamp,
- dateISO: timestamp.toISODateString(),
- YMDKey: timestamp.toYMDKey(),
- operation: historyData[i].operation?.[0] ?? '',
- reason: thisRow[5].innerText,
- user: thisRow[6].innerText,
- other: thisRow[10].innerText
- });
- });
- debuglog(historyData);
- historytable.$$('tr:not(:first-child)').forEach((tr, i) => setTimeout(() => {
- const newRow = {}, thisRow = tr.$$('td'), thisHistory = historyData[i];
- tr.$("td:nth-child(3) > span > p", { style: { width: 'max-content' } });
- tr.before(newRow.tr = _('tr', { classList: ['newRow'] })._(newRow.td = _('td', { colSpan: 99, style: { fontWeight: 'bold' } })));
- if (thisHistory.timestamp.toString() != 'Invalid Date') {
- (i == 0 || thisHistory.YMDKey != historyData[i - 1].YMDKey) && (tr.classList.add('newDay'), newRow.tr.classList.add('newDay'));
- thisRow[0].__(toWeekdayDateTimeString(thisHistory.timestamp, packageData.stationTimeZone));
- }
- if (thisHistory.deliveryLatitude && thisHistory.deliveryLongitude) {
- const copy = _('button', { title: `${thisHistory.deliveryLatitude} ${thisHistory.deliveryLongitude}`, classList: ['copyButton'] },)._('\uD83D\uDCCB').on('click', () => copyText(copy.title));
- thisRow[10].$('p')?.before(copy);
- }
- //if (thisHistory.stateTime == historyData[i - 1]?.stateTime && thisHistory.packageState == historyData[i - 1]?.packageState && thisHistory.reasonCode == historyData[i - 1]?.reasonCode) return void (tr.classList.add('die'), newRow.tr.remove());
- if (historytable.dataset.colours == 'OnRoad') {
- const serviceAreaId = sitemap && (thisHistory.destination && thisHistory.destination in sitemap ? sitemap[thisHistory.destination] : (thisHistory.source && thisHistory.source in sitemap ? sitemap[thisHistory.source] : undefined));
- if (thisHistory.packageState == 'DELIVERED' && thisHistory.operation == 'PACKAGE_STATE_UPDATE') {
- tr.classList.add('delSuc'); newRow.tr.classList.add('delSuc');
- newRow.td._(
- ...(thisHistory.recipientName ? [_('span')._(`${s('delTo')}: ${thisHistory.recipientName} (${S(thisHistory.reasonCode.replace('DELIVERED_TO_', '').replace('_', ' ')).toWordCase().trim()})`, _('br'))] : []),
- packageData.pddDate && (packageData.pddYMDKey >= thisHistory.YMDKey ? _('span', { classList: ['goodTime'] })._(`\u2713 ${s('metPDD')}`) : _('span', { classList: ['badTime'] })._(`\u2717 ${s('missPDD')}`)),
- packageData.eadDate && (packageData.eadYMDKey >= thisHistory.YMDKey ? _('span', { classList: ['goodTime'] })._(`\u2713 ${s('metEAD')}`) : _('span', { classList: ['poorTime'] })._(`\u2717 ${s('missEAD')}`)),
- geoPromise.status == 'fulfilled' && thisHistory.deliveryLatitude && thisHistory.deliveryLongitude && distanceNode(thisHistory.deliveryLatitude, thisHistory.deliveryLongitude)
- );
- }
- if (thisHistory.packageState == 'DELIVERY_FAILED' && thisHistory.operation == 'PACKAGE_STATE_UPDATE') {
- tr.classList.add("delFail"); newRow.tr.classList.add('delFail');
- newRow.td._(
- _('span')._(thisHistory.reasonCode == 'BUSINESS_CLOSED' && gamPromise.status == 'fulfilled' && gamData && gamData.hourText ? `${s('BH')}\u2002${gamData.hourText}` : thisHistory.reason),
- geoPromise.status == 'fulfilled' && thisHistory.deliveryLatitude && thisHistory.deliveryLongitude && distanceNode(thisHistory.deliveryLatitude, thisHistory.deliveryLongitude)
- );
- }
- if (thisHistory.operation == 'ROUTE_ASSIGNMENT') {
- const buttons = _('span'), startTime = _('span'), deliveryTime = _('span');
- newRow.td._(
- _('span')._(_('strong')._(`${s('Route')} ${thisHistory.routeCode}`)),
- buttons, startTime, deliveryTime
- );
- // serviceAreaId && buttons._(_('button')._(s('cortexLinkRoute')).on('click', () => buttonclick(`${globalOrigin}/internal/operations/execution/dv/routes?provider=ALL_DRIVERS&selectedDay=${thisHistory.dateISO}&serviceAreaId=${serviceAreaId}&summariesText=${thisHistory.routeCode}`)));
- new Promise((ok, x) => {
- if (!serviceAreaId) { x('No serviceAreaId'); throw 'No serviceAreaId'; };
- if (!(thisHistory.timestamp.getTime() > (now - 14 * 24 * 60 * 60 * 1000))) { x('Too old'); throw 'Too old'; };
- XHR('GET', `${globalOrigin}/internal/operations/execution/api/route-summaries?localDate=${thisHistory.dateISO}&serviceAreaId=${serviceAreaId}`).then(json).then(cortex => {
- debuglog('cortex XHR()', cortex);
- cortex.rmsRouteSummaries.filter((route) => route.routeCode == thisHistory.routeCode).forEach((route) => {
- debuglog(route);
- routeVisButton(route.routeId, buttons, thisHistory.timestamp);
- return XHR('GET', `${globalOrigin}/internal/operations/execution/api/routes/${route.routeId}`).then(json).then(cortex => {
- debuglog('inner cortex XHR()', cortex);
- if (cortex.routePlan.plannedStartTime) { startTime.__(`${s('plannedStartTime').replace('{{time}}', toLocaleTZString(cortex.routePlan.plannedStartTime, packageData.stationTimeZone))}`); }
- cortex.routePlan.stopList.filter((stop) => stop.stopPlanContext.stopType == 'DropOff').forEach((stop, i) => {
- stop.stopDetails.packageList.filter((package) => package.scannableId == page.trackingId).forEach((package) => {
- if (package.plannedDeliveryTime) { deliveryTime.__(`${s('plannedTime').replace('{{time}}', toLocaleTZString(package.plannedDeliveryTime, packageData.stationTimeZone))}`); }
- return XHR('POST', `${globalOrigin}/internal/operations/execution/api/trs/trDetails`, { "trAndObjectState": [{ "trId": package.trId, "objectState": package.trObjectState }] }).then(json).then(packData => {
- debuglog('package cortex XHR()', packData);
- packData.trStateDetails.filter((stateDetails) => stateDetails.packageNotes).forEach((stateDetails) => stateDetails.packageNotes.forEach((notes) => {
- debuglog(notes);
- notes.noteContent.forEach((/** @type {string} */ noteText) => newCustNote(noteText.replace(/\\\\\\\\r/gim, '\r').replace(/\\\\\\\\n/gim, '\n'), toWeekdayDateString(thisHistory.timestamp), `Cortex ${notes.packageNoteType}`));
- }));
- ok('Got Cortex Data');
- }).catch(x);
- });
- });
- }).catch(x);
- });
- }).catch(x);
- }).then(debuglog, (e) => {
- debuglog('Skipping Route Cortex: ', e, thisHistory);
- logBox._(_('span')._('Skipping Route Cortex: ', JSON.stringify(e)));
- debuglog('routeVisXHR()');
- routeVisButton(response.json()?.routes?.[0]?.unitPlanIdentifier, buttons, thisHistory.timestamp);
- }).catch(debuglog);
- });
- }
- if (thisHistory.operation == 'DRIVER_ASSIGNMENT') {
- const amConsoleBut = _('button')._(thisHistory.driverId),
- dspSpan = _('span'), cortexButtons = _('span'), plannedTime = _('span'), windowTime = _('span');
- newRow.td._(
- thisHistory.driverName && _('span')._(`${s('Driver')} ${thisHistory.driverName}`),
- thisHistory.driverId && [amConsoleBut, dspSpan], cortexButtons, plannedTime, windowTime
- );
- if (thisHistory.driverId) {
- amConsoleBut.on('click', () => buttonclick(`${globalOrigin}/amconsole/transporter/${thisHistory.driverId}`));
- XHR('GET', `${globalOrigin}/amconsole/da/dsp-info/template?id=${thisHistory.driverId}&type=transporter`).then(response => {
- if (response.text && S(response.text).contains('Business Name:')) {
- dspSpan.__(response.text.split('Business Name:')?.[1]?.split('>')?.[1]?.split('</')?.[0]);
- }
- }, debuglog);
- // serviceAreaId && cortexButtons._(_('button')._(s('cortexItinerary')).on('click', () => buttonclick(`${globalOrigin}/internal/operations/execution/dv/routes?provider=ALL_DRIVERS&selectedDay=${thisHistory.dateISO}&serviceAreaId=${serviceAreaId}&summariesText=${thisHistory.driverId}`)));
- new Promise((ok, x) => {
- if (!serviceAreaId) { x('No serviceAreaId'); throw 'No serviceAreaId'; };
- XHR('GET', `${globalOrigin}/internal/operations/execution/api/summaries?localDate=${thisHistory.dateISO}&serviceAreaId=${serviceAreaId}`).then(json).then(cortex => {
- cortex.itinerarySummaries?.filter((itinerary) => itinerary.transporterId == thisHistory.driverId).forEach((itinerary) => {
- cortexButtons._(_('button')._(s('cortexItinerary')).on('click', () => buttonclick(`${globalOrigin}/internal/operations/execution/itineraries/${itinerary.itineraryId}/documentType/Itinerary?operationView=true&selectedDay=${thisHistory.dateISO}&serviceAreaId=${serviceAreaId}`)));
- return XHR('GET', `${globalOrigin}/internal/operations/execution/api/itineraries/${itinerary.itineraryId}?documentType=Itinerary&itineraryId=${itinerary.itineraryId}`).then(json).then(cortex => {
- let offset = 0;
- cortex.itineraryDetails.stops.forEach((stop) => {
- if (!stop.sequenceNumber) { offset++; }
- stop.tasks.filter((task) => task.taskType == 'DROP_OFF' && task.domainMap.scannableId == page.trackingId).forEach((task) => {
- if (stop.sequenceNumber) cortexButtons._(_('button')._(s('cortexLinkStop').replace('{{stop#}}', stop.sequenceNumber)).on('click', () => buttonclick(`${globalOrigin}/internal/operations/execution/itineraries/${itinerary.itineraryId}/documentType/Itinerary/stops/${stop.sequenceNumber - 1 + offset}?operationView=true&selectedDay=${thisHistory.dateISO}&serviceAreaId=${serviceAreaId}`)));
- if (stop.plannedStartTime || stop.plannedEndTime) {
- plannedTime._(`\u2003${s('plannedTime').replace('{{time}}', `${toLocaleTZString(stop.plannedStartTime, packageData.stationTimeZone)} - ${toLocaleTZString(stop.plannedEndTime, packageData.stationTimeZone)}`)}`);
- } else if (task.expectedExecutionTime) {
- plannedTime._(`\u2003${s('plannedTime').replace('{{time}}', toLocaleTZString(task.expectedExecutionTime, packageData.stationTimeZone))}`);
- }
- if (task.timeWindowed && (task.windowStartTime || task.windowEndTime)) {
- windowTime._(`\u2003${s('windowTime').replace('{{time}}', `${toLocaleTZString(1000 * task.windowStartTime, packageData.stationTimeZone)} - ${toLocaleTZString(1000 * task.windowEndTime, packageData.stationTimeZone)}`)}`);
- }
- return ok('Got Cortex Data');
- });
- });
- }).catch(x);
- });
- }).catch(x);
- }).catch(e => {
- debuglog('Skipping Driver Cortex: ', e, thisHistory);
- logBox._(_('span')._('Skipping Driver Cortex: ', JSON.stringify(e)));
- });
- }
- }
- S(thisHistory.destination).contains('CUSTOMER_ADDRESS') && (thisHistory.operation == 'PACKAGE_STATE_UPDATE' || thisHistory.operation == 'ASSOCIATE_DEBRIEF') && (thisHistory.packageState == 'RECEIVED' || thisHistory.packageState == 'MARKED_FOR_REPROCESS') && tr.classList.add("rts");
- }
- if (historytable.dataset.colours == 'InStation') {
- if (thisHistory.operation == 'PACKAGE_STATE_UPDATE') {
- thisHistory.packageState == 'INDUCTED' && tr.classList.add('delSuc');
- thisHistory.packageState == 'STOWED' && tr.classList.add('delFail');
- thisHistory.packageState == 'PICKED' || thisHistory.packageState == ('STAGED') && tr.classList.add('rts');
- S(thisHistory.destination).contains('CUSTOMER_ADDRESS') && (thisHistory.packageState == 'RECEIVED' || thisHistory.packageState == 'MARKED_FOR_REPROCESS') && tr.classList.add('delSuc');
- thisHistory.reasonCode == 'STOW_INVALID_SCAN_DONE' && tr.classList.add('endFail');
- } else if (thisHistory.operation == 'SIDELINED') { tr.classList.add('delFail', 'bold4'); }
- }
- if (thisHistory.packageState == 'IN_TRANSIT' && thisHistory.operation == 'PACKAGE_STATE_UPDATE') { tr.classList.add("oor"); thisRow[2].$('div')?._(svg(S(thisHistory.destination).contains('CUSTOMER_ADDRESS') ? 'van' : thisHistory.destination?.[0] == 'D' ? 'in_trailer' : 'trailer')); }
- thisHistory.packageState == 'INDUCTED' && thisHistory.operation == 'PACKAGE_STATE_UPDATE' && thisRow[2].$('div')?._(svg('avery', thisHistory.scanLocation));
- if (thisHistory.operation == 'CANCELLED_BY_CUSTOMER' || (thisHistory.packageState == 'MARKED_FOR_REPROCESS' && thisHistory.destination == 'MIDDLE_MILE_NODE')
- || ['MARKED_FOR_PROBLEM', 'DELIVERY_REJECTED', 'MARKED_AS_MISSING', 'MARKED_AS_LOST', 'DISPOSED'].includes(thisHistory.packageState)
- || ['WRONG_NODE', 'OBJECT_MISSING', 'DAMAGED_FC_RETURN', 'LOCALLY_DISPOSED'].includes(thisHistory.reasonCode)) { tr.classList.add('endFail'); newRow.tr.classList.add('endFail'); }
- if (S(thisHistory.user).contains('@')) {
- const username = thisHistory.user.split('@')[0];
- thisRow[6].$('div')?._(_('a', { href: `https://fclm-portal.amazon.com/employee/ppaTimeDetails?employeeId=${username}`, target: '_blank', classList: ['minibadge'] })._(_('img', { src: `https://internal-cdn.amazon.com/badgephotos.amazon.com/?login=${username}`, loading: 'lazy', classList: ['minibadge'] },)));
- }
- if (thisHistory.scanContainer && S(thisHistory.scanContainer).contains('EU_')) {
- thisRow[2].$('div')?._(svg('bag', thisHistory.scanContainer, thisHistory.scanContainer.slice(-3)));
- }
- if ((S(thisHistory.scanContainer).containsAny('OVER-', 'CRT2-', '_DOLLY_')) || (thisHistory.packageState == 'PICKED' && S(thisHistory.scanLocation).contains('CRT2-'))) { thisRow[2].$('div')?._(svg('cart', thisHistory.scanLocation)); }
- if (thisHistory.imageUrl) {
- const photoImg = _('img', { src: thisHistory.imageUrl, loading: 'lazy', classList: ['photoImg', 'hide'] });
- newRow.td._(_('button')._('Show/Hide Photo').on('click', () => { photoImg.classList.toggle('hide'); }), photoImg);
- }
- setTimeout(() => newRow.td.textContent == '' && newRow.tr.remove());
- }));
- }).catch((e) => promises.topBar.then(improveBoxes => { debuglog('histTableError', e); improveBoxes.histTableError.__(`${e}`); }))));
- function outbound() {
- debuglog('outbound()');
- wait$('#root').then(root => {
- document.documentElement.dataset.improveSccCssOutboundPage = '';
- new MutationObserver(() => queueMicrotask(() => {
- const thead = $('thead'), tbody = $('tbody');
- if (!thead || !tbody) return;
- const [badgeCol, cartCol, driverCol] = thead?.$$('th').map(th => S(th?.innerText)).reduce(([badgeCol, cartCol, driverCol], th, i) => [
- th.dictContains('associate') ? i + 1 : badgeCol,
- th.dictContains('cartID') ? i + 1 : cartCol,
- th.dictContains('driver') ? i + 1 : driverCol
- ], [0, 0, 0]);
- debuglog(badgeCol, cartCol, driverCol);
- tbody?.$$('tr').forEach(tr => {
- if (badgeCol) {
- tr.$$(`td:nth-child(${badgeCol}) a`).forEach(a => {
- if (a?.$('input')) return;
- if (a?.$('img') || a?.parentNode?.querySelector('img')) { a?.classList.add('badge'); return; }
- [...a?.parentNode?.childNodes ?? []].filter((text) => (text.nodeName == '#text')).forEach((text) => text.remove());
- miniBadge(a, 1);
- });
- }
- if (driverCol) {
- const driver = tr.$(`td:nth-child(${driverCol}) span > p[mdn-text][title]`);
- if (driver?.classList) {
- driver.parentNode?.append(_('a', { href: `${globalOrigin}/amconsole/transporter/${driver.title}`, target: '_blank' })._(driver));
- }
- }
- });
- })).observe(root, { characterData: true, attributes: false, childList: true, subtree: true });
- });
- }
- function associate() {
- debuglog('associate()');
- document.documentElement.dataset.improveSccCssBadgesPage = '';
- if (hrefContains('receive')) {
- const tabs = $$("[role=tablist] label");
- if (!tabs.length) { setTimeout(associate, 500); return; }
- debuglog(tabs);
- tabs.at(-1)?.do('click');
- page.region = window.location.href.split('ivs')[1].split('.')[0];
- document.documentElement.dataset.improveSccCssReceivePage = '';
- wait$('#root').then(root => new MutationObserver(() => setTimeout(() => {
- $$('#root table tbody > tr > [scope=row]:first-child:not(.fmcload)').forEach(td => {
- debuglog(td);
- td.classList.add('fmcload');
- const vrId = td.textContent;
- XHR('GET', `https://trans-logistics${page.region == 'na' ? '' : `-${page.region}`}.amazon.com/fmc/api/v2/execution/load/${vrId}/mapFeature/stops`).then(json).then(responseJSON => {
- td.title = responseJSON.reduce((prev, next) => `${prev}${next.timelineEvent.title}:\n${next.timelineEvent.stopActions.reduce((prev, next) => `${prev}${next.actualCompletedTime?.utcMillis ? `\u2003${next.yardActionType} - ${toWeekdayDateTimeString(next.actualCompletedTime?.utcMillis)}\n` : ''}`, '')}\n`, '');
- td.classList.add('fmcdone');
- });
- });
- })).observe(root, { characterData: true, attributes: false, childList: true, subtree: true }));
- return;
- }
- // if (hrefContains('induct')) return;
- if (hrefContains('packageList')) { packageList(); return; }// WIP does not work yet.
- wait$('#root').then(root => {
- setInterval(() => root.append(mutationComment), 6000);
- new MutationObserver(() => {
- setTimeout(() => {
- const badgeCol = $$('thead th').reduce((/**@type {false | number}*/bool, th, i) => bool || S(th?.innerText).dictContains('associate') && i + 1, false);
- if (!badgeCol) return;
- $$(`tbody tr :is(th, td):nth-child(${badgeCol}) span`).forEach(a => {
- if (a?.$('input')) return;
- if (a?.$('img')) { a?.classList.add('badge'); return; }
- miniBadge(a, 0);
- });
- });
- }).observe(root, { characterData: true, attributes: false, childList: true, subtree: true });
- });
- }
- function packageList() {
- debuglog('packageList()');
- wait$('tbody').then(tbody => {
- $('thead tr')?._(_('th', { classList: ['css-1j7l84d'] })._(_('span')._('PDD')));
- packageListXHR();
- new MutationObserver(packageListXHR).observe(tbody, { characterData: true, attributes: false, childList: true, subtree: true });
- });
- }
- function psTab() {
- debuglog('psTab()');
- document.documentElement.dataset.improveSccCssBadgesPage = '';
- wait$('body').then(body => {
- new MutationObserver(() => setTimeout(() => {
- const badgeCol = $('thead')?.$$('th').reduce((/**@type {false | number}*/badgeCol, th, i) => badgeCol || S(th?.innerText).dictContains('Reportedby') && (i + 1), false);
- badgeCol && $('tbody')?.$$('tr').forEach(tr => {
- debuglog(tr);
- const a = tr.$(`td:nth-child(${badgeCol}) span`);
- if (a?.$('img')) { a.classList.add('badge'); return; }
- a && miniBadge(a, 0);
- });
- })).observe(body, { characterData: true, attributes: false, childList: true, subtree: true });
- });
- debuglog('psTab - MO - Start');
- }
- //#endregion
- //#region: XHR Functions
- /** @type {() => Promise<PackageData>} */
- function getPackageData() {
- debuglog('getPackageData()');
- return XHR('POST', `${globalOrigin}/station/proxyapigateway/data`, { "resourcePath": "/os/getPackageDetailData", "httpMethod": "get", "processName": "oculus", "requestParams": { "trackingId": [page.trackingId] } }).then(response => {
- debuglog('getPackageDataXHR()');
- const packageData = response.json().packageDetail.packageData;
- packageData.amxl = S(packageData.shipInfo.shipMethod).contains('_SH');
- packageData.pddDate = packageData.shipInfo.promisedDeliveryTime ? D(packageData.shipInfo.promisedDeliveryTime) : undefined;
- packageData.eadDate = packageData.shipInfo.estimatedArrivalTime ? D(packageData.shipInfo.estimatedArrivalTime) : undefined;
- packageData.pddYMDKey = packageData.pddDate?.toYMDKey();
- packageData.eadYMDKey = packageData.eadDate?.toYMDKey();
- packageData.oversize = ((m, l, w, h) => {
- packageData.volume = l * w * h;
- packageData.letterbox = (h <= 3.8 && w <= 25.4);
- return (m > 5
- || packageData.volume > 50000
- || l > 73 || w > 73 || h > 73
- || (l > 53 && (w > 40 || h > 40))
- || (w > 53 && (l > 40 || h > 40))
- || (h > 53 && (w > 40 || l > 40))
- );
- })(
- packageData.packageDimensions.packageWeight.unit == 'ounces' ? 0.02834952 * packageData.packageDimensions.packageWeight.value : packageData.packageDimensions.packageWeight.value,
- packageData.packageDimensions.packageLength.value,
- packageData.packageDimensions.packageWidth.value,
- packageData.packageDimensions.packageHeight.value
- );
- packageData.pcd = packageData.customerInfo.customerAddress?.split(',')?.slice(-1)[0];
- superlog('package', packageData);
- return packageData;
- });
- }
- /** @type {([improveRoot, packageData]:[ImproveRoot, PackageData]) => ImproveBoxes} */
- function usePackageData([improveRoot, packageData]) {
- debuglog('usePackageData()', improveRoot, packageData);
- const improveBoxes = /** @type {ImproveBoxes} */(improveRoot);
- document.documentElement.dataset.improveSccXhr = '';
- if (packageData.shipInfo.itemDescription) { improveBoxes.items.__(packageData.shipInfo.itemDescription); };
- addButton(`https://sim.amazon.com/issues/search?q=(${packageData.orderInfo.orderId}+OR+${packageData.trackingId})&sort=lastUpdatedConversationDate`, s('SIM'), -1, { id: 'SIM' });
- if (packageData.amxl && page.region == 'na') { addButton(`http://amxl-ba.corp.amazon.com/Passage/#${packageData.trackingId}`, s('Passage'), 2); }
- colourResult(packageData.shipInfo.shipMethod, improveBoxes.head);
- improveBoxes.head.__(
- _('div')._(
- improveBoxes.trackingId = _('h1')._(page.trackingId).on('click', () => copyText(page.trackingId)),
- _('div')._(_('strong')._(s('shipMethod')), packageData.shipInfo.shipMethod),
- _('div')._(_('strong')._(s('shipOption')), packageData.shipInfo.shipOption),
- // packageData.serviceType?.length && _('div')._(_('strong')._(s('serviceType')), packageData.serviceType) : undefined,
- packageData.orderInfo.orderId && (improveBoxes.orderId = _('div', { id: 'oid', classList: [S(packageData.orderInfo.orderId).containsAny('VRET', 'S02-') ? 'vret' : undefined] })._(_('strong')._(s('oId')), packageData.orderInfo.orderId).on('click', () => copyText(packageData.orderInfo.orderId))),
- // improveBoxes.customerId = _('div')._(_('strong')._(s('customerId')), improveBoxes.customerIdText = _('span')._('…')).on('click', () => copyText(improveBoxes.customerIdText.innerText)),
- packageData.linkedTrackingIds.map((linktid) => _('div', { classList: ['linktid'] })._(_('strong')._(s('lTId')), _('a', { href: `${globalOrigin}/station/dashboard/search?shareableLink=detailPage%2F${linktid}`, target: '_blank' })._(linktid))),
- improveBoxes.multiPart = _('div'),
- ),
- _('div', { id: 'flags' })._(
- improveBoxes.OTP = packageData.hasOtp ? _('strong', { id: 'OTP', style: { color: 'red' } })._(s('OTP')) : undefined,
- (S(packageData.shipInfo.shipMethod).contains('AGEVER') || packageData.isAvdPackage) && _('strong', { style: { color: 'red' } })._(s('AVD')),
- packageData.isHazmat && _('strong', { style: { color: 'darkorange' } })._(s('HAZMAT')),
- packageData.orderInfo.orderAmount >= ((cur) => cur == 'INR' ? 10000 : cur == 'JPY' ? 20000 : cur == 'BRL' ? 500 : 100)(packageData.orderInfo.orderCurrency) && _('strong', { style: { color: 'forestgreen' } })._(s('HV').replace(/ /g, '\u00a0')),
- (packageData.amxl ? [_('strong', { style: { color: 'royalblue' } })._('AMXL')] : [
- packageData.letterbox && _('strong', { style: { color: 'royalblue' } })._(s('LB')),
- (packageData.oversize || packageData.isOv) && _('strong', { style: { color: 'royalblue' } })._(s('OVER')),
- packageData.packageDimensions.packageWeight.value > 20 ? _('strong', { style: { color: 'royalblue' } })._(s('VH').replace(/ /g, '\u00a0')) : packageData.packageDimensions.packageWeight.value > 10 ? _('strong', { style: { color: 'royalblue' } })._(s('H')) : undefined
- ])
- ),
- _('div')._(
- _('div')._(`${formatUnit(packageData.packageDimensions.packageLength)} x ${formatUnit(packageData.packageDimensions.packageWidth)} x ${formatUnit(packageData.packageDimensions.packageHeight)}`),
- _('div', { classList: ['spaced'] })._(
- _('span')._(`${packageData.volume.toFixed(0)}\u00a0cm³`),
- _('span')._(`${formatUnit(packageData.packageDimensions.packageWeight)}`),
- _('span')._(formatCurrency({ currency: packageData.orderInfo.orderCurrency, value: packageData.orderInfo.orderAmount }))
- ),
- improveBoxes.fc = _('div', { id: 'fcBox' }),
- packageData.eadDate && _('div')._(_('strong')._('EAD:'), `\u2002${toWeekdayDateTimeString(packageData.eadDate)}`),
- packageData.pddDate && _('div')._(_('strong')._('PDD:'), `\u2002${(['AMZN_DE_SAME_SD', ' AMZN_ES_SAME_SD', 'AMZN_FR_SAME_SD', 'AMZN_IT_SAME_SD', 'AMZN_UK_SAME_SD'].includes(packageData.shipInfo.shipMethod) && packageData.shipInfo.shipOption == 'rush' ? toWeekdayDateString : toWeekdayDateTimeString)(packageData.pddDate)}`),
- !!(packageData.shipInfo.scheduledDeliveryTime && packageData.shipInfo.scheduledDeliveryTimeEnd) && _('div', { classList: ['simple-flex'] })._(_('strong')._('Scheduled:'), _('span')._(_('div')._(toWeekdayDateTimeString(packageData.shipInfo.scheduledDeliveryTime, packageData.stationTimeZone)), _('div')._(toWeekdayDateTimeString(packageData.shipInfo.scheduledDeliveryTimeEnd, packageData.stationTimeZone))))
- ),
- improveBoxes.customerCol = _('div', { id: 'customerColumn' })._(
- _('div')._(packageData.customerInfo.customerName),
- _('div')._(packageData.customerInfo.customerAddress.replace(/,/g, ', ').replace(/\s+/g, ' ')),
- _('strong')._(packageData.customerInfo.customerAddressType),
- improveBoxes.nak = _('div', { id: 'NAK' }),
- improveBoxes.phr = _('div', { id: 'PHR' }),
- _('strong')._('Customer Notes:'),
- improveBoxes.notes = _('div', { id: 'custNotes' })._(...packageData.customerNotes.map((note) => custNoteDiv(note.customerNoteContent, note.dateAdded)))
- )
- );
- if (packageData.amxl) {
- XHR('POST', `${globalOrigin}/station/proxyapigateway/data`, {
- "resourcePath": "/os/batchGetPackageSummary",
- "httpMethod": "post",
- "processName": "oculus",
- "requestBody": { "idType": "TRACKING_ID", "identifiers": [packageData.orderInfo.orderId], "nodeId": packageData.routeInfo.stationCode, "includeFields": [] }
- }).then(json).then(searchResult => {
- const items = searchResult.packageSummaryList.filter((resultRow) => (page.trackingId != resultRow.trackingId)).map((resultRow) => _('a', { href: `${globalOrigin}/station/dashboard/search?shareableLink=detailPage%2F${resultRow.trackingId}`, target: '_blank' })._(resultRow.trackingId));
- if (items.length) improveBoxes.multiPart.__(s('sameOrderID'), items);
- });
- }
- return improveBoxes;
- }
- /** @type {() => Promise<SiteMap>} */
- function siteMap() {
- let sitemap;
- if ((sitemap = localStorage.getItem('sitemap')) && (sitemap = JSON.parse(sitemap)) && (sitemap.timestamp > now - 7 * 24 * 60 * 60 * 1000) && sitemap.hasOwnProperty('data')) { return Promise.resolve(sitemap); }
- return XHR('GET', `${globalOrigin}/flex/api/getOperationalRegions`).then(response => {
- debuglog('sitemap', response);
- const sitemap = { timestamp: now, data: {} };
- response.json().forEach((region) => region.basicServiceAreas.forEach((site) => (sitemap.data[site.defaultStationCode] = site.serviceAreaID)));
- localStorage.setItem('sitemap', JSON.stringify(sitemap));
- return sitemap;
- }, error => {
- if ('text' in error) delete error.text;
- throw error;
- });
- }
- /** @type {() => Promise<GeoData>} */
- function getGeoData() {
- debuglog('getGeoData()');
- return XHR('POST', `https://api-gam.${page.region}.prod.geostudio.last-mile.amazon.dev/api/getAddressInfo`, { "id": page.trackingId, "idType": "Auto", "gdeView": "" }).then(json, json).then(geoData => {
- debuglog('geoData', geoData);
- const message = (geoData.message ?? geoData.Message); if (message == 'Unauthenticated' || S(message)?.contains('not authorized')) throw message;
- /**@type {GeoData} */
- const returnGeoData = Object.assign({
- deliveryHint: geoData.deliveryHint,
- nak: (geoData?.geocodingServiceResult ?? geoData?.geospatialData)?.scope10NAK ?? geoData?.geocodingServiceResult?.scope10NAK,
- phr: geoData?.preferredDeliveryLocations?.length && geoData?.preferredDeliveryLocations?.reduce((a, b) => `${a}, ${b}`),
- }, ((geoData?.geocodingServiceResult ?? geoData?.geospatialData)?.bestDeliveryPoint ?? geoData?.addressServiceGeocode)?.coordinates);
- returnGeoData.validLatLon = !(returnGeoData.latitude === undefined || returnGeoData.latitude === null || returnGeoData.longitude === undefined || returnGeoData.longitude === null);
- if (returnGeoData.validLatLon) { return returnGeoData; }
- throw `Geo data has invalid lat/lon: ${JSON.stringify(geoData)}`;
- }).catch(e => { throw e; });
- }
- /** @type {([improveBoxes, geoData]:[ImproveBoxes, GeoData]) => void} */
- function useGeoData([improveBoxes, geoData]) {
- superlog('useGeoData()', geoData);
- if (geoData.nak) { improveBoxes.nak._(_('strong')._('NAK:\u2002'), geoData.nak.replace(/(\!+)/g, ' $1 ')); }
- if (geoData.phr) { improveBoxes.phr._(_('strong')._('Safe Place(s):\u2002'), geoData.phr); }
- if (!geoData.validLatLon) return;
- improveBoxes.buttons._(($('#latlonbuts') || _('div', { id: 'latlonbuts', style: { order: `${4}` } })).__(
- s('LatLon'),
- miniButton(`https://bing.com/maps?style=a&where1=${geoData.latitude} ${geoData.longitude}`),
- ));
- }
- /** @type {(packageData:PackageData) => Promise<GAMData>} */
- function getGAMData(packageData) {
- debuglog('getGAMData()');
- return Promise.reject('GAM requests disabled');
- const countryCode = packageData.shipInfo.shipMethod.split('_')[1];
- return XHR('GET', `https://gamtools-${page.region}.aka.amazon.com/searchResults?searchId=${page.trackingId}&idType=TRACKING_ID&countryCode=${countryCode == 'UK' ? 'GB' : countryCode}`).then(response => { try { return response.json(); } catch (e) { throw response.text; } }).then(json => {
- debuglog('gam', json);
- if (!('step_up_methods' in json)) { throw 'Unknown JSON'; }
- if (midwayWindow == null || midwayWindow == undefined || midwayWindow.closed) {
- midwayWindow = window.open(json.step_up_methods[0].cap_url, 'midwayAuth', 'width=1200, height=800');
- if (midwayWindow == null || midwayWindow == undefined || midwayWindow.closed) { throw 'Midway Popup Blocked'; }
- }
- midwayWindow.focus(); throw (json.step_up_methods[0].cap_display_string || 'Please login with Midway');
- }, text => {
- debuglog('gam', text);
- if (text.contains("Oops, something has gone wrong") || text.contains("not authorized")) { return { hourText: undefined }; }
- if (text.contains('is not yet in GAM. Addresses may take a few days to reflect.')) { return { hourText: s('GAM404') }; }
- const gam = _('html', { innerHTML: text.replace(/\<script.*\<\/script\>/gim, '') });
- let hoursList = []; hoursList.push(...gam.$$("#canonicalAttributes div.canonical-attribute-values > b"), ...gam.$$("#Business-Hours-canonical-values > b"));
- return {
- unitImg: gam.$("img.unit-icon")?.src,
- hourText: hoursList.filter(b => S(b.innerText.replace(/ /gim, '').slice(0, 3)).inDict('GAMdays') && Number.isNaN(Number(b.innerText.slice(0, 4)))).map(b => b.innerText).join('\u2003') || s('GAMnoHours'),
- hintText: gam.$$('#canonicalAttributes li').reduce((hintText, li) => `${hintText}${S(li.innerText).contains('Delivery Hint') && li.$('b') ? li.$('b')?.innerHTML : ''}`, '')
- };
- });
- }
- /** @type {([improveBoxes, gamData, historyData]:[ImproveRoot, GAMData, HistDataRow[]]) => void} */
- function useGAMData([improveBoxes, gamData, historyData]) {
- superlog('useGAMData()', gamData);
- addButton(`https://gamtools-${page.region}.aka.amazon.com/search?searchId=${page.trackingId}&idType=TRACKING_ID`, s('GAM'), 2);
- const bizClosed = historyData.filter((row) => row.reasonCode == 'BUSINESS_CLOSED');
- gamData.hourText !== null && improveBoxes.gam.__(`${s('Hours')} ${gamData.hourText}`, !!bizClosed.length && _('div', { id: 'gamfail' })._(`${s('FailedAttempt')}\u2003`, bizClosed.map(row => toWeekdayDateString(row.stateTime)).join(' | ')));
- gamData.hintText && newCustNote(gamData.hintText, null, s('GAMhint'));
- }
- // function getTaxonomy([improveBoxes, eeData]) {
- // XHR('GET', `https://transportation-taxonomy-${page.regionCode}.aka.amazon.com/loadContainer?containerId=${eeData.tcdaId}&versionNumber=`).then(response => response.text.replace(/\s+/gim, ' ')).then(responseText => {
- // debuglog(responseText);
- // if (responseText.contains('Content is hidden because of Access control on Transportation Taxonomy')) { throw 'No Access to Transportation Taxonomy'; }
- // try {
- // let tempText = responseText.split('"transactionType":')[1].split(',')[0].replaceAll('\\', '').replaceAll('"', '').trim();
- // if (tempText == 'null') { throw ''; }
- // improveBoxes.transactionType.__(tempText);
- // } catch (e) { improveBoxes.transactionType.remove(); }
- // try {
- // improveBoxes.replacementType.__(responseText.split('"replacementType":')[1].split(',')[0].replaceAll('\\', '').replaceAll('"', '').trim());
- // } catch (e) { improveBoxes.replacementType.remove(); }
- // const fragments = responseText.split('java.util.HashMap');
- // new Promise((resolve, reject) => { fragments.filter((fragment) => fragment.contains('OTPRequired')).forEach((fragment) => fragment.split(',').filter((HashMap) => HashMap.contains('OTPRequired') && HashMap.contains('true')).forEach(resolve)); reject(); }).then(
- // () => { improveBoxes.OTP.__(s('OTP')); improveBoxes.SIG.remove(); },
- // () => new Promise((resolve, reject) => { fragments.filter((fragment) => fragment.contains('SignatureRequired')).forEach((fragment) => fragment.split(',').filter((HashMap) => HashMap.contains('SignatureRequired') && HashMap.contains('true')).forEach(resolve)); reject(); }).then(
- // () => { improveBoxes.SIG.__(s('SIG')); improveBoxes.OTP.remove(); },
- // () => new Promise((resolve, reject) => { responseText.split('"name":"ServiceOfferings"').filter((fragment) => fragment.split('"targetEntityName":')[1]?.contains('"OTP"')).forEach(resolve); reject(); }).then(
- // () => { improveBoxes.OTP.__(s('OTP')); improveBoxes.SIG.remove(); },
- // () => { improveBoxes.OTP.remove(); improveBoxes.SIG.remove(); }
- // )
- // )
- // );
- // }).catch(e => {
- // improveBoxes.OTP.remove();
- // improveBoxes.SIG.remove();
- // improveBoxes.taxonomyError._('No OTP or Sig Data: ', e);
- // });
- // }
- // function getOBLT() {
- // debuglog('getOBLT()');
- // return XHR('GET', `https://trans-app-prod-${page.region}.amazon.com/outboundLookup/packageLookup.cgi?submitForm=Submit;data_type=TRACKING_ID;id=${page.trackingId}`).then(response => response.text).then(html => {
- // const oblt_row = _('html', { innerHTML: html.replace(/\<script.*\<\/script\>/gim, '') }).$$('table#resultsTable tr[rownum="0"] td');
- // return {
- // fulfillmentShipmentId: oblt_row[3]?.textContent,
- // orderingShipmentId: oblt_row[5]?.textContent,
- // customerId: oblt_row[9]?.textContent,
- // FC: oblt_row[10]?.textContent
- // };
- // });
- // }
- // function useOBLTData([improveBoxes, obltData]) {
- // debuglog('useOBLTData()', obltData);
- // improveBoxes.customerIdText.__(obltData.customerId);
- // response.json().EventList.filter((event) => event.eventType == 'COMPLETE_PACKAGE').forEach((event) => {
- // if (!response.text.contains('boxRecommendation=')) return;
- // improveBoxes.fc.__(_('strong')._('FC Box Recommendation: '), response.text.split('boxRecommendation=')[1].split(',')[0]);
- // });
- // });
- // });
- // addButton(`https://slamops-dub.amazon.com/packageHistory/?warehouseId=${obltData.FC}&shipmentId=${obltData.fulfillmentShipmentId}`, s('SlamOps'), 1);
- // }
- /** @type {() => Promise<HistDataRow[]>} */
- function getHistoryData() {
- debuglog('getHistoryData()');
- return XHR('POST', `${globalOrigin}/station/proxyapigateway/data`, { "resourcePath": "/os/getPackageHistoryData", "httpMethod": "post", "processName": "oculus", "requestBody": { "packageId": page.trackingId, "pageSize": 100, "pageToken": null, "startTime": null, "endTime": null } }).then(json).then(({ packageHistory }) => packageHistory);
- }
- /** @type {(routeId: string, node: Extended<HTMLElement>, timestamp: ExtendedDate) => void} */
- function routeVisButton(routeId, node, timestamp) {
- debuglog('routeVisButton()', routeId, node, timestamp);
- node._(
- _('button')._(s('RouteVis')).on('click', () => buttonclick(`https://routingtools-viz-${page.regionCode}.${page.regionCode}.proxy.amazon.com/route/routevisualize.jsp#/search?routeId=${routeId}`)),
- (timestamp.toMidnightLocal() < D().toMidnightLocal()) && _('button')._(s('RouteDiver')).on('click', () => buttonclick(`https://routediver-${page.regionCode}.${page.regionCode}.proxy.amazon.com/#?routeId=${routeId}`)),
- _('button')._(s('RouteEagle')).on('click', () => buttonclick(`https://global.eagle.routeiq.last-mile.amazon.dev/?routes=${routeId}®ion=${page.region?.toUpperCase()}`))
- );
- }
- function packageListXHR() {
- const searchXHRpayload = {
- "resourcePath": "/os/batchGetPackageSummary",
- "httpMethod": "post",
- "processName": "oculus",
- "requestBody": {
- "idType": "TRACKING_ID",
- /** @type {(string | undefined)[]} */
- "identifiers": [],
- "nodeId": (/.*stationCode=([A-Z0-9]+).*/.exec(page.url[3]) || '')[1],
- "includeFields": []
- }
- }, trMap = {};
- $$('tbody tr').forEach(tr => {
- const tId = tr.$('td span')?.innerText;
- if (tr.tId == tId) return;
- tr.tId = tId;
- trMap[tId] = tr;
- searchXHRpayload.requestBody.identifiers.push(tId);
- tr.$('.pdd')?.remove?.();
- tr.classList.remove('AVD', 'SWA', 'LOCK', 'SAME');
- });
- debuglog(searchXHRpayload);
- if (searchXHRpayload.requestBody.identifiers.length) {
- XHR('POST', `${globalOrigin}/station/proxyapigateway/data`, searchXHRpayload).then(json).then(searchResult => {
- searchResult.packageSummaryList.forEach((resultRow) => {
- const td = $(`row_${resultRow.trackingId} .pdd`) || _('td', { classList: ['pdd'] });
- if (resultRow.promisedDeliveryDate) { td.__(_('div', { style: { display: 'inline-block', width: '140px' } })._(toWeekdayDateString(resultRow.promisedDeliveryDate))); }
- trMap[resultRow.trackingId]._(td);
- colourResult(resultRow.shipMethod, trMap[resultRow.trackingId]);
- });
- });
- }
- }
- const /** @type {Record<string, string>} */ AWS_POD_REGION_MAPPING = { eu: "eu-west-1", na: "us-east-1", fe: "us-west-2" };
- function getPODData() {
- promises.topBar.then(improveBoxes => {
- improveBoxes.podContainer.__('POD: Please wait…');
- XHR('GET', `https://honeypot.amazon.dev/api/searchImageByIndex?input=${encodeURIComponent(JSON.stringify({ "imageIndex": page.trackingId, "imageType": "PHOTO_ON_DELIVERY", "searchBy": "TRACKING_ID", "region": AWS_POD_REGION_MAPPING[page.region ?? ''] }))}`).then(r => r.json(), r => r.json()).then((/** @type {PODResponse} */ data) => {
- improveBoxes.podContainer.__(
- _('div', { classList: ['button-align'] })._(
- _('button', { classList: ['close'] })._('X').on('click', () => improveBoxes.podContainer.__()),
- ),
- _('section')._(
- ('error' in data) ? data.error : data.result.data.imageList.length ? data.result.data.imageList.map(
- ({ imageInfo, imagePresignedUrl }) => _('div', { classList: ['pod-item'] })._(
- _('img', { src: imagePresignedUrl, classList: ['pod-img'] }),
- _('span')._(imageInfo.imageAttributeData.imageType),
- _('span')._(D(imageInfo.photographedDate * 1e3).toISODateTimeString()),
- _('span')._(imageInfo.metadataMap.REASON_CODE),
- _('div')._(
- _('span')._(`${formatUnit({ value: imageInfo.geocode.latitude, unit: 'degree' })}, ${formatUnit({ value: imageInfo.geocode.longitude, unit: 'degree' })}`),
- distanceNode(imageInfo.geocode.latitude, imageInfo.geocode.longitude))
- )
- ) : 'No Results Found'
- )
- );
- }).catch(e => improveBoxes.podContainer.__(JSON.stringify(e)));
- });
- }
- //#endregion
- //#region: Mini Functions
- /** Add svg css */
- _css(`svg[data-improve-scc-svg] {
- path { stroke-linecap: round; stroke-linejoin: round; }
- path.bag { stroke: black; fill-opacity: 0.75; }
- path.bag.out { fill-opacity: 1; }
- path.box { fill: #FF7F00; }
- path.tape { fill: #000000; }
- path.label { fill: #FFFFFF; }
- &.cart {
- path.cage { stroke: yellow; fill: none; }
- path.cage.floor { fill: #000000; }
- circle.wheel { fill: #7F7F7F; }
- }
- &.van {
- .van { fill: #232F3E; stroke: #0096D6; }
- .window { fill: white; stroke: #0096D6; }
- .smile { fill: #0096D6; stroke: #0096D6; }
- .wheel { fill: white; stroke: white; }
- path.wheelnut { fill: #0096D6; stroke: #0096D6; }
- }
- &:is(.trailer, .in_trailer) {
- path.cab { fill: #232f3e; stroke: black; }
- path.trailer { fill: #0096d6; stroke: black; }
- path.window { fill: #afafFF; stroke: black; }
- path.tsmile { fill: #ffffff; stroke: #ffffff; }
- circle.wheel { fill: #404040; stroke: black; }
- }
- &:is(.avery){
- path.print { fill: black; }
- path.deco { fill: #bb0000; }
- path.clip { fill: #bbbb00; }
- }
- }`);
- /** @type {(type: string, title?: string?, colour?: string) => Extended<SVGSVGElement>} */
- function svg(type, title, colour) {
- const svg = _svg('svg', { dataset: { improveSccSvg: '' }, attributeList: { viewBox: '0 0 60 60' }, classList: [type, 'bag', colour] })._(title && _svg('title')._(title));
- switch (type) {
- case 'bag':
- svg.setAttribute('viewBox', '0 10 60 40');
- svg._(
- _svg('path', { classList: ['bag', 'colour'], attributeList: { d: 'M 20,15 h 40 v 20 h -40 z' } }),
- _svg('path', { classList: ['bag', 'colour'], attributeList: { d: 'M 0,45 L 20,35 h 40 L 40,45 z' } }),
- _svg('path', { classList: ['bag', 'colour'], attributeList: { d: 'M 0,25 L 20,15 v 20 L 0,45 z' } }),
- _svg('path', { classList: ['bag', 'out', 'colour'], attributeList: { d: 'M 0,25 L 20,15 h 40 L 40,25 z' } }),
- _svg('path', { classList: ['bag', 'out', 'colour'], attributeList: { d: 'M 40,25 L 60,15 v 20 L 40,45 z' } }),
- _svg('path', { classList: ['box'], attributeList: { d: 'M 15,34 h 15 v 10 h -15 z' } }),
- _svg('path', { classList: ['box'], attributeList: { d: 'M 15,34 l 5,-5 h 15 l -5,5 z' } }),
- _svg('path', { classList: ['box'], attributeList: { d: 'M 30,34 l 5,-5 v 10 l -5,5 z' } }),
- _svg('path', { classList: ['tape'], attributeList: { d: 'M 21,34 h 3 v 10 h -3 z' } }),
- _svg('path', { classList: ['tape'], attributeList: { d: 'M 21,34 l 5,-5 h 3 l -5,5 z' } }),
- _svg('path', { classList: ['label'], attributeList: { d: 'M 19,33 l 3,-3 h 5 l -3,3 z' } }),
- _svg('path', { classList: ['label'], attributeList: { d: 'M 0,25 h 40 v 20 h -40 z' }, style: { stroke: '#000000', fillOpacity: '0.25' } }),
- );
- break;
- case 'cart':
- svg._(
- _svg('title')._(title),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '3', cy: '56' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '37', cy: '56' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '57', cy: '47' } }),
- _svg('path', { classList: ['cage'], attributeList: { d: 'M 20,45 v-40 h 40 v 40 z h 4 v -40 v 40 h 4 v -40 v 40 h 4 v -40 v 40 h 4 v -40 v 40 h 4 v -40 v 40 h 4 v -40 v 40 h 4 v -40 v 40 h 4 v -40 v 40 h 4 v -40 v 40z' } }),
- _svg('path', { classList: ['cage', 'floor'], attributeList: { d: 'M 0,55 l 20,-10 h 40 l -20,10 z' } }),
- _svg('path', { classList: ['cage'], attributeList: { d: 'M 0,15 l 20,-10 v 40 l -20,10 z l 4,-2 v 40 v -40 l 4,-2 v 40 v -40 l 4,-2 v 40 v -40 l 4,-2 v 40 v -40 z' } }),
- _svg('path', { classList: ['box'], attributeList: { d: 'M 25,44 h 15 v 10 h -15 z' } }),
- _svg('path', { classList: ['box'], attributeList: { d: 'M 25,44 l 5,-5 h 15 l -5,5 z' } }),
- _svg('path', { classList: ['box'], attributeList: { d: 'M 40,44 l 5,-5 v 10 l -5,5 z' } }),
- _svg('path', { classList: ['tape'], attributeList: { d: 'M 31,44 h 3 v 10 h -3 z' } }),
- _svg('path', { classList: ['tape'], attributeList: { d: 'M 31,44 l 5,-5 h 3 l -5,5 z' } }),
- _svg('path', { classList: ['label'], attributeList: { d: 'M 29,43 l 3,-3 h 5 l -3,3 z' } }),
- _svg('path', { classList: ['cage'], attributeList: { d: 'M 40,15 l 20,-10 v 40 l -20,10 z l 4,-2 v 40 v -40 l 4,-2 v 40 v -40 l 4,-2 v 40 v -40 l 4,-2 v 40 v -40 z' } }),
- );
- break;
- case 'van':
- svg.setAttribute('viewBox', '-30 -30 60 60');
- svg._(
- _svg('circle', { classList: ['van'], attributeList: { r: '6', cx: '-17.5', cy: '15' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '3', cx: '-17.5', cy: '15' } }),
- _svg('path', { classList: ['wheelnut'], attributeList: { d: 'M -17.5,15 l-0.5,-0.5 l 0.5,0.5 l 0.5,-0.5 l -0.5,0.5 l 0.5,0.5 l -0.5,-0.5 l -0.5,0.5 l 0.5,-0.5 z' } }),
- _svg('circle', { classList: ['van'], attributeList: { r: '6', cx: '17.5', cy: '15' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '3', cx: '17.5', cy: '15' } }),
- _svg('path', { classList: ['wheelnut'], attributeList: { d: 'M 17.5,15 l-0.5,-0.5 l 0.5,0.5 l 0.5,-0.5 l -0.5,0.5 l 0.5,0.5 l -0.5,-0.5 l -0.5,0.5 l 0.5,-0.5 z' } }),
- _svg('path', { classList: ['van'], attributeList: { d: 'M -27.5,15 v -15 l 15,-15 h 40 v 30 h -4 q 0,-6 -6,-6 q -6,0 -6,6 h -23 q 0,-6 -6,-6 q -6,0 -6,6 z' } }),
- _svg('path', { classList: ['window'], attributeList: { d: 'M -25,0 l 12.5,-12.5 v 12.5 z' } }),
- _svg('path', { classList: ['smile'], attributeList: { d: 'M -10,-7 q 15,10 30,2 q -15,12 -30,-2 m 28,0 q 7,-3 4,4 q 2,-6 -4,-4' } }),
- );
- break;
- case 'in_trailer':
- svg._(
- _svg('path', { classList: ['cab'], attributeList: { d: 'M 60,45 v -10 l -15,-15 h -3 v 18 h -10 v 7 h 1 q 0,-3 3,-3 q 3,0 3,3 h 1 q 0,-3 3,-3 q 3,0 3,3 h 7 q 0,-3 3,-3 q 3,0 3,3 z' } }),
- _svg('path', { classList: ['trailer'], attributeList: { d: 'M 30.5,45 v -8.5 h 10 v -20.5 h -40 v 29 h 1 q 0,-3 3,-3 q 3,0 3,3 h 1 q 0,-3 3,-3 q 3,0 3,3 h 7 q 0,-3 3,-3 q 3,0 3,3 z' } }),
- _svg('path', { classList: ['window'], attributeList: { d: 'M 57.5,35 l -12.5,-12.5 v 12.5 z' } }),
- _svg('path', { classList: ['tsmile'], attributeList: { d: 'M 3,25 q 15,10 30,2 q -15,12 -30,-2 m 28,0 q 7,-3 4,4 q 2,-6 -4,-4' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '56', cy: '45.5' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '43', cy: '45.5' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '36', cy: '45.5' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '24.5', cy: '45.5' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '11.5', cy: '45.5' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '4.5', cy: '45.5' } }),
- );
- break;
- case 'trailer':
- svg._(
- _svg('path', { classList: ['cab'], attributeList: { d: 'M 0,45 v -10 l 15,-15 h 3 v 18 h 10 v 7 h -1 q 0,-3 -3,-3 q -3,0 -3,3 h -1 q 0,-3 -3,-3 q -3,0 -3,3 h -7 q 0,-3 -3,-3 q -3,0 -3,3 z' } }),
- _svg('path', { classList: ['trailer'], attributeList: { d: 'M 29.5,45 v -8.5 h -10 v -20.5 h 40 v 29 h -1 q 0,-3 -3,-3 q -3,0 -3,3 h -1 q 0,-3 -3,-3 q -3,0 -3,3 h -7 q 0,-3 -3,-3 q -3,0 -3,3 z' } }),
- _svg('path', { classList: ['window'], attributeList: { d: 'M 2.5,35 l 12.5,-12.5 v 12.5 z' } }),
- _svg('path', { classList: ['tsmile'], attributeList: { d: 'M 23,25 q 15,10 30,2 q -15,12 -30,-2 m 28,0 q 7,-3 4,4 q 2,-6 -4,-4' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '4', cy: '45.5' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '17', cy: '45.5' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '24', cy: '45.5' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '35.5', cy: '45.5' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '48.5', cy: '45.5' } }),
- _svg('circle', { classList: ['wheel'], attributeList: { r: '2', cx: '55.5', cy: '45.5' } }),
- );
- break;
- case 'avery':
- svg._(
- _svg('g', { attributeList: { transform: 'rotate(-30 30 30)' } })._(
- _svg('path', { classList: ['print'], attributeList: { d: 'M 20,12 l 24,-6 q 10,25 0,25 v 20 h 5 v 10 h -20 v -10 h 10 v -20 l -16,-4 q -4,-6 -4,-10 z' } }),
- _svg('path', { classList: ['deco'], attributeList: { d: 'M 28,15 l 12,-3 q 0,6 -6,6 h -6 z' } }),
- _svg('path', { classList: ['clip'], attributeList: { d: 'M 21,17 l 6,-2 v 3 h -6 z' } }),
- ),
- _svg('path', { classList: ['box'], attributeList: { d: 'M 5,44 h 15 v 10 h -15 z' } }),
- _svg('path', { classList: ['box'], attributeList: { d: 'M 5,44 l 5,-5 h 15 l -5,5 z' } }),
- _svg('path', { classList: ['box'], attributeList: { d: 'M 20,44 l 5,-5 v 10 l -5,5 z' } }),
- _svg('path', { classList: ['tape'], attributeList: { d: 'M 11,44 h 3 v 10 h -3 z' } }),
- _svg('path', { classList: ['tape'], attributeList: { d: 'M 11,44 l 5,-5 h 3 l -5,5 z' } }),
- _svg('path', { classList: ['label'], attributeList: { d: 'M 9,43 l 3,-3 h 5 l -3,3 z' } }),
- );
- break;
- default:
- break;
- }
- return svg;
- }
- /** @type {(method: string | undefined | null, node: HTMLElement) => void} */
- function colourResult(method, node) {
- if (!method) return;
- const m = S(method);
- m.contains('AGEVER') && node.classList.add('AVD');
- m.contains('OUT') && node.classList.add('SWA');
- m.contains('LOCKER') && node.classList.add('LOCK');
- m.contains('SAME') && node.classList.add('SAME');
- }
- /** @type {(node: HTMLElement | ParentNode | null, count?: number) => ParentNode?} */
- const parentNode = (node, count = 1) => node && count ? (--count ? parentNode(node.parentNode, count) : node.parentNode) : node;
- /** @type {(node: HTMLElement, parents?: number) => void} */
- function miniBadge(node, parents = 1) {
- if (['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'Total', '...', '-'].includes(node?.innerText) || node?.classList.contains('badge') || !node?.innerText) return;
- node?.classList.add('badge');
- const oldInnerText = node.innerText.split('@')[0];
- parentNode(node, parents)?.append(_('a', { href: `https://fclm-portal.amazon.com/employee/ppaTimeDetails?employeeId=${oldInnerText}`, target: '_blank', classList: ['minibadge'] })._(_('img', { src: `https://internal-cdn.amazon.com/badgephotos.amazon.com/?login=${oldInnerText}`, loading: 'lazy', classList: ['minibadge'] })));
- }
- /** @type {(url: ExtendedString) => Extended<HTMLImageElement> | undefined} */
- const _buttonImg = (url) => {
- if (url.contains('royalmail')) return _('img', { src: 'https://www.royalmail.com/themes/custom/rmlcwr/favicon.ico' });
- if (url.contains('maps.google.com')) return _('img', { src: 'https://www.google.com/images/branding/product/ico/maps15_bnuw3a_32dp.ico' });
- if (url.contains('bing.com')) return _('img', { src: 'https://www.bing.com/sa/simg/favicon-2x.ico' });
- if (url.contains('openstreetmap')) return _('img', { src: 'https://www.openstreetmap.org/assets/favicon-194x194-79d3fb0152c735866e64b1d7535d504483cd13c2fad0131a6142bd9629d30de2.png' });
- if (url.contains('duckduckgo')) return _('img', { src: 'https://duckduckgo.com/favicon.ico' });
- if (url.contains('gamtools')) return _('img', { src: 'https://m.media-amazon.com/images/G/01/ate/gam/tools/favicon.png' });
- if (url.contains('eagleeye.amazon.dev')) return _('img', { src: 'https://eagleeye.amazon.dev/favicon.ico' });
- if (url.contains('eagleeye')) return _('img', { src: 'data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAAsSAAALEgHS3X78AAADRElEQVQ4jYXTT2gcVRwH8O9v/tiNO5NkdhqNDVm3Zktg4qZqiKK4hcJGkBpYXBExIRjIRS8lnoRqIYcYySGXeiiIR9lK6CU5mIQcTIuwQQSFENvaCEm2lWRhszvzZgMh+35edpekTtffaXiP3+d9md97hIBi5ogQ4iMAKWa+CMAmIh/AAwB3ANwyTfPPoF56AtJ8378qpbwOoDWooVZVIroF4HPTNPcDQWY2hBC3mfmdJtDpNESPiOiKYRh/nAKZWRNC/MTMqZMNBwcHWF9fx+7uLjzPQ0dHB3p7ezE4OAgiqqMFXdffDIVCWw1QCPGFlHKmDm1ubmJ2dhaLi4uQUsJxHDiOA8uyUC6Xsb+/j+HhYYyPj4OIQER3DcO4TERVxfO856SU12pJcePbG0gmk1hYWMDIyAhyuRyWl5eRTqdx6Puw83kMDAzAdV2Mjo4im82iVColhRAfoJbuquu67LouT09Ps33W5mg0yisrK1wqldh1Xd7Y2OC1tTX+4eZNXotG+axtc39/P4+NjbFlWRyPx3lpaWkVAEgIsSilfO/erz9j8quvIZkwNzeHvr6+wEHk83nout74x0dHR2hpacHMzMzh/Px8hyalTMjjI7y6/hl+fKOIh5e/g+M4gVihUEAmk0E+n0cikUB3dzd830elUkFra2uL7/txDUD7/b+28Is/DKf9H7z+9ruNCZ4sZsbU1BT29vagqipSqRQmJiZgmiYKhQKy2SxUVW3TiKhcLpfbnnmhD1tKAm9p2lPv3dDASyjci+DDT68hk8k01js7OzE5OQlVVV2NmTfOhM5Eu7q6YNv2UzEASF+M4OXHOmLp9H/2iOhQ1/WHiqIoqxfiF9DT04Nnw+Gm4N/tl7Aafh+qqgZt54hIKACy4XC4EovF0HXuXFMwdv482jpfBDMHJfweqL0Uz/OuM/NUM4yZQUTwPA+hUKhxdWpYzjCMJBEdKwCwvb39DYC7zcD65A3DgHZ6cEVd1z8houNGQgAoFottmqYtALjUDH7ikD1FUa6Ew+Hf6mtK/SMSiZR3dnaGVFX9kpkr/2NJIrqtKMprJ7FTCU+WEOJ5AB8DGGLmV4jIYuZDAPeZ+U61Ws1alvV7UO+/+k9aMjlySqQAAAAASUVORK5CYII=' });
- if (url.contains('hero')) return _('img', { src: 'https://hero.eu.picking.aft.a2z.com/favicon.ico' });
- if (url.contains('sim.amazon.com')) return _('img', { src: 'https://sim.amazon.com/images/sim-favicon-new.ico' });
- if (url.contains('ordnancesurvey.co.uk')) return _('img', { src: 'https://osmaps.ordnancesurvey.co.uk/bundles/app/css/favicon.ico' });
- if (url.contains('explore.osmaps.com')) return _('img', { src: 'https://explore.osmaps.com/images/logo/osmaps-logo-triangle.svg' });
- };
- /** @type {(url: string, buttonText: string, order: number, windowProps?: {id?: string} & WindowProps) => void} */
- function addButton(url, buttonText, order, { id, name, ...windowProps } = {}) {
- id ??= `${name ?? buttonText}_button`.replace(/[^a-zA-Z0-9\-_]/gm, '');
- promises.topBar.then((improveBoxes) => improveBoxes.buttons._(($(`button#${id}`, { style: { order: `${order}` } }) ?? _('button', { id, style: { order: `${order}` } })).on('click', () => buttonclick(url, { name, ...windowProps })).__(_buttonImg(S(url)), buttonText)));
- }
- /** @type {() => void} */
- function specialButtons() {
- const
- qrButton = ($(`button#QR`) ?? _('button', { id: 'QR', style: { order: '-1' } })).__(s('qrCode')),
- podButton = ($(`button#POD`) ?? _('button', { id: 'POD', style: { order: '-1' } })).__(s('viewPOD'));
- qrButton.onclick = showQR; podButton.onclick = getPODData;
- promises.topBar.then((improveBoxes) => improveBoxes.buttons._(qrButton, podButton));
- }
- function showQR() {
- const contentSection = _('section'),
- dialog = _('dialog', { classList: ['QR'] })._(_('button', { classList: ['close'] })._('X').on('click', () => { dialog.close(); contentSection.remove(); dialog.remove(); }), contentSection);
- document.body.append(dialog);
- queueMicrotask(() => {
- dialog.showModal();
- new QRCode(contentSection, page.trackingId);
- });
- }
- /** @type {(url: string, windowProps?: WindowProps) => Extended<HTMLImageElement>} */
- function miniButton(url, windowProps) {
- const img = _buttonImg(S(url));
- if (!img) { throw 'Unable to generate minibut img for url'; }
- img.classList.add('minibut');
- return img.on('click', () => buttonclick(url, windowProps));
- }
- function addrbuts(packageData) {
- debuglog('addrbuts()');
- if (packageData.customerInfo.customerAddress) {
- if (/^[A-Z]{1,2}[0-9]{1,2}[A-Z]{0,1} ?[0-9][A-Z]{2}$/i.test(packageData.pcd.trim().toUpperCase()) || S(packageData.customerInfo.customerAddress).contains('United Kingdom')) { addButton(`https://www.royalmail.com/find-a-postcode#${packageData.customerInfo.customerAddress}`, s('RoyalMail'), 3, { name: 'RMpostcode' }); }
- addAddrButs(s('Address'), packageData.customerInfo.customerAddress.replace(/\//g, '-').replace(/&/gi, 'and').replace('#', ''), 3);
- }
- if (/Amazon.*Locker/i.test(packageData.customerInfo.customerName)) {
- addButton(`https://locker${page.region == 'na' ? '' : `-${page.region}`}.amazon.com/search?searchType=kioskPostalCode¶m=${packageData.pcd}`, s('LockerStatus'), 2);
- addButton(`https://locker${page.region == 'na' ? '' : `-${page.region}`}.amazon.com/search?searchType=externalReferenceID¶m=${page.trackingId}`, s('LockerReserve'), 2);
- addAddrButs(s('Locker'), `${packageData.customerInfo.customerName} ${packageData.pcd}`, 5);
- }
- if (/Amazon.*Counter/i.test(packageData.customerInfo.customerName)) {
- addAddrButs(s('Counter'), `${packageData.customerInfo.customerName.replace(/.* - /i, '')} ${packageData.customerInfo.customerAddress.replace(/\//g, '-')}`, 5);
- }
- }
- /** @type {(buttonText: string, mapSearchString: string, order: number) => void} */
- function addAddrButs(buttonText, mapSearchString, order) {
- const id = `${buttonText}_button`.replace(/[^a-zA-Z0-9\-_]/gm, '');
- promises.topBar?.then((improveBoxes) => {
- improveBoxes.buttons._(($(`div.button_group#${id}`) ?? _('div', { id, style: { order: `${order}` }, classList: ['button_group'] })).__(
- buttonText,
- miniButton(`https://bing.com/maps?style=a&where1=${mapSearchString}`),
- miniButton(`https://duckduckgo.com/?iaxm=maps&q=${mapSearchString}`),
- ));
- });
- }
- /** @type {(url: string, windowProps?: WindowProps) => void} */
- function buttonclick(url, { w = 1200, h = 800, name = '' } = {}) { window.open(encodeURI(url).replace(/'/g, '%27'), name, `width=${w}, height=${h}, noopener, noreferrer`); }
- /** @type {(lat: string|number, lon: string|number) => Extended<HTMLSpanElement>} */
- function distanceNode(lat, lon) {
- debuglog('distanceNode()');
- const distSpan = _('span', { classList: ['dist'] })._('…');
- promises.geo?.then((geoData) => {
- if (!geoData.validLatLon) { return distSpan.remove(); }
- debuglog(`${lat} - ${lon} - ${geoData.latitude} - ${geoData.longitude}`);
- const clat_1 = (90.0 - Number(lat)) * Math.PI / 180.0,
- clon_1 = (Number(lon)) * Math.PI / 180.0,
- clat_2 = (90.0 - Number(geoData.latitude)) * Math.PI / 180.0,
- clon_2 = Number(geoData.longitude) * Math.PI / 180.0,
- d = Math.acos(Math.sin(clat_1) * Math.sin(clat_2) * Math.cos(clon_1 - clon_2) + Math.cos(clat_1) * Math.cos(clat_2));
- if (d >= 0.5 / 6370) { distSpan.classList.add('longDistance'); }
- distSpan._(
- `${s('calcText').replace('{{ft#}}', formatUnit({ value: (d * 3960 * 5280), unit: 'foot' })).replace('{{m#}}', formatUnit({ value: (d * 6370 * 1000), unit: 'meter' }))})\u2002`,
- );
- }, () => distSpan.remove());
- return distSpan;
- }
- /** @type {(text?: string) => void} */
- function copyText(text) {
- text && navigator.clipboard.writeText(text).then(() => notify("Copied to clipboard", text)).catch(e => { notify('Copy Failed', e); console.warn(e); });
- }
- function closeNotification() { notification?.close(); }
- /** @type {(title: string, content: string, closeDelay?:number) => void} */
- function notify(title, content, closeDelay = 3) {
- if (Notification.permission !== "denied" && Notification.permission !== "granted") { Notification.requestPermission(); }
- if (Notification.permission !== "granted") { alert(`${title}\n\n${content}`); return; }
- closeNotification();
- notification = new Notification(title, { body: content, silent: true });
- delay(closeDelay).then(closeNotification);
- }
- function historyFormatMenu() {
- const
- localOption = { colours: 'OnRoad', ...JSON.parse(localStorage.getItem('SCC_Search_CONFIG') ?? '{}') },
- onChange = (newValue) => {
- const tabs = $$("[role=tablist] label");
- localOption.colours = newValue;
- localStorage.setItem('SCC_Search_CONFIG', JSON.stringify(localOption));
- tabs[0].do('click'); tabs[3].do('click');
- };
- return {
- colourValue: localOption.colours,
- menuElement: _('div', { id: 'SCC_Search_CONFIG' })._(
- _('strong')._(s('formatTable')),
- [{ label: s('onRoadOption'), value: 'OnRoad' }, { label: s('inStationOption'), value: 'InStation' }].map(({ label, value }) => _('label')._(label, _('input', { type: 'radio', name: 'colours', value, checked: value == localOption.colours }).on('change', () => onChange(value))))
- )
- };
- }
- //#endregion
- //#region: CSS
- function addCSS() {
- wait$('head').then(head => head._(_('meta', { name: 'theme-color', content: '#ffffff' })));
- _css(`
- /* All Pages */
- :root {
- color-scheme: light;
- --redBG: #FFAAAA;
- --yellowBG: #FFFFAA;
- --greenBG: #AAFFAA;
- --blueBG: #AAFFFF;
- --matchBG: white;
- --greenTableBG: #96FF96;
- --yellowTableBG: #FFFF96;
- --redTableBG: #FF9696;
- --blueTableBG: #9696FF;
- --cyanTableBG: #96FFFF;
- --greenText: forestgreen;
- --orangeText: darkorange;
- --redText: firebrick;
- --smile: #FF9900;
- --squidInk: #232F3E;
- --primeBlue: #0096D6;
- }
- :root[data-improve-scc-css-dark-mode="dark"] {
- color-scheme: dark;
- --redBG: #640000;
- --yellowBG: #646400;
- --greenBG: #006400;
- --blueBG: #00004B;
- --matchBG: #232F3E;
- --greenTableBG: #003200;
- --yellowTableBG: #323200;
- --redTableBG: #320000;
- --blueTableBG: #000032;
- --cyanTableBG: #006464;
- --greenText: #00FF00;
- --orangeText: #FFFF00;
- --redText: #FF0000;
- & :is(.fp-navigation-container, .fp-navigation-container .fp-nav-menu, .fp-page-template, .css-avryxx, .css-m7c1h1, .css-1ekky2x, #verdiv, #changelog ul, #changelog li, .css-sdn4iy:hover) {
- background-color: var(--squidInk)!important;
- }
- }
- *, *:before, *:after {
- box-sizing: border-box;
- font-family: "Amazon Ember", Sans-serif;
- margin: 0;
- padding: 0;
- border-collapse: collapse;
- vertical-align: middle;
- }
- ::-webkit-scrollbar, ::-webkit-scrollbar-track, ::-webkit-scrollbar-corner, ::-webkit-scrollbar-thumb {
- width: 1rem;
- height: 1rem;
- border: 0.25rem solid transparent;
- }
- ::-webkit-scrollbar, ::-webkit-scrollbar-corner {
- background: inherit;
- }
- ::-webkit-scrollbar-track {
- box-shadow: inset 0 0 0 0.0625rem var(--primeBlue);
- border-radius: 1rem;
- }
- ::-webkit-scrollbar-thumb {
- box-shadow: inset 0 0 0 1rem var(--primeBlue);
- border-radius: 1rem;
- }
- @supports not selector(::-webkit-scrollbar) {
- * {
- scrollbar-color: var(--primeBlue) transparent;
- }
- }
- dialog {
- max-height: 60vh;
- max-height: 60svh;
- padding-block-start: 3rem;
- & #debugModalButtons {
- position: absolute;
- inset-block-start: 1rem;
- inset-inline-end: 1rem;
- font-size: 200%;
- & > button {
- padding: 0.25rem;
- margin-inline: 0.25rem;
- }
- }
- }
- :root[data-improve-scc-css-noframe] {
- zoom: 0.9;
- &:not([data-improve-scc-show-top-menu]) {
- display: flex;
- flex-flow: column nowrap;
- height: 100%;
- overflow: auto;
- & :is(header.fp-header, div.fp-navigation-container) {
- display: none;
- }
- & .is-it-down-stripe {
- flex: 0 0 0;
- z-index: unset;
- position: unset;
- overflow: unset;
- }
- & body {
- flex: 1 1 100%;
- overflow: auto;
- margin: 0;
- padding: 0;
- height: unset;
- min-height: unset;
- & > div {
- display: flex;
- flex-flow: column nowrap;
- height: 100%;
- overflow: auto;
- }
- & .boson-meridian-frame-dimension {
- position: unset;
- top: unset;
- bottom: unset;
- flex: 1 1 100%;
- }
- }
- }
- & #scc_alert {
- padding: 0;
- :root[data-improve-scc-css-hide-alerts] &, & .boson-display-none {
- display: none!important;
- }
- }
- & #dkingamzNav {
- color: canvastext;
- text-align: center;
- border-top: 1px solid #BBC0C1;
- & li {
- list-style: none;
- & button {
- background: transparent;
- border: none;
- }
- }
- }
- & #main_row {
- position: relative;
- }
- & #taskContainer {
- background: var(--matchBG);
- border-block-end: 1px solid #C0C0C0;
- }
- & #verdiv {
- position: absolute;
- top: -1px;
- right: -0.125rem;
- color: canvastext;
- background: var(--matchBG);
- padding: 0.5rem;
- border-radius: 0 0 0 1em;
- border: 1px solid #C0C0C0;
- font-size: 1.2rem;
- &.hidden {
- transform: translate(100%) translate(-2rem);
- &::before {
- content: '<\u2003';
- }
- }
- }
- & :is(#dkingamzNav, #verdiv) a {
- color: inherit;
- text-decoration: underline;
- & strong {
- padding: 0.25em;
- }
- }
- }
- :root[data-improve-scc-css-iframe] {
- margin-block-start: 0.5rem;
- & img.minibadge {
- border: 0.125rem ridge silver;
- border-radius: 0.5rem;
- &:not(.pkmn) {
- max-height: 80px;
- max-width: 60px;
- }
- }
- & :has( > a.minibadge) {
- display: inline-flex;
- flex-flow: column-reverse nowrap;
- align-items: center;
- align-content: center;
- padding: 0.375rem;
- & a {
- padding: 0!important;
- margin: 0!important;
- }
- }
- & #exportLogs {
- position: fixed;
- inset-block-start: 3rem;
- inset-inline-end: 2rem;
- background: canvas;
- padding: 0.5rem;
- font-size: 200%;
- }
- }
- :root:is([data-improve-scc-css-search-page],[data-improve-scc-css-details-page]) {
- & #root#root {
- & .AVD {
- &, & th, & td {
- background: var(--redBG);
- }
- }
- & .LOCK {
- &, & th, & td {
- background: var(--yellowBG);
- }
- }
- & .SAME {
- &, & th, & td {
- background: var(--greenBG);
- }
- }
- & .SWA {
- &, & th, & td {
- background: var(--blueBG);
- }
- }
- }
- }
- :root[data-improve-scc-css-search-page] {
- & :is(tr, th, td) {
- background-color: inherit;
- border-block-end: 1px outset;
- }
- & tr[data-row-number]::before {
- content: attr(data-row-number);
- display: table-cell;
- color: canvastext;
- padding: 8px;
- border-block-end: 1px outset;
- }
- & tr[data-vrid]::after {
- content: attr(data-vrid);
- display: table-cell;
- color: canvastext;
- padding: 8px;
- border-block-end: 1px outset;
- }
- & tr[data-exchange-id] td:last-child::after {
- content: attr(data-exchange-id);
- display: table-cell;
- color: canvastext;
- padding: 8px;
- border-block-end: 1px outset;
- }
- & .css-vps56m {
- margin-block-end: 0!important;
- padding: 0;
- }
- }
- :root[data-improve-scc-css-details-page] {
- /*main box below root*/
- & .css-xx5nu9 {
- padding: 2px!important;
- /*main rows below main box*/
- & > :is(div,ul) {
- margin: 2px!important;
- padding: 0 2px!important;
- }
- }
- &[data-improve-scc-xhr] :is(.css-rx4572, .css-rx4572 + .css-14fuupd) {
- display: none!important;
- }
- & #SCC_Search_CONFIG {
- display: flex;
- gap: 0.5rem;
- & label {
- display: inline-flex;
- gap: 0.5rem;
- }
- }
- & #improveRoot {
- margin-block-start: -1px;
- & > div {
- border-block-end: 2px groove;
- border-radius: 0;
- }
- & #improveHead {
- font-family: "Amazon Ember", "Amazon Ember Arabic", Arial, sans-serif;
- color: canvastext;
- display: grid;
- grid-template-columns: max-content min-content max-content 1fr;
- column-rule: 2px solid currentcolor;
- column-rule-outset: 0;
- gap: 4px;
- align-items: center;
- border-radius: 1em 1em 0 0;
- & h1 {
- font-weight: 600;
- font-size: 36px;
- line-height: 48px;
- margin: 0;
- }
- & > div {
- display: flex;
- flex-flow: column nowrap;
- &:not(#customerColumn) * {
- text-align: center;
- }
- &:first-of-type > * {
- padding-inline-start: 0;
- }
- &:last-of-type > * {
- padding-inline-end: 0;
- }
- }
- & div {
- & > * {
- padding: 0 0.25em;
- }
- &.spaced {
- display:flex;
- flex-flow: row nowrap;
- justify-content: space-around;
- & > * {
- margin: 0 0.5em;
- &:first-of-type {
- margin-left: 0;
- }
- &:last-of-type {
- margin-right: 0;
- }
- }
- }
- &.simple-flex {
- display:flex
- }
- }
- & #oid {
- &.vret {
- background: var(--yellowTableBG);
- }
- &.covid {
- background: var(--redTableBG);
- }
- }
- & #flags {
- justify-content: space-evenly;
- align-self: stretch;
- padding-inline: 0.25rem;
- & > strong {
- margin: 0;
- font-size: 1.2rem;
- }
- }
- & #customerColumn {
- flex-grow: 1;
- flex-shrink: 1;
- & > div > strong {
- padding: 0;
- }
- & #custNotes {
- padding-left: 3em!important;
- & > div {
- text-indent: -1.5em;
- }
- }
- }
- }
- & #podContainer {
- padding:0.125rem;
- &:not(:has(>*)) {
- display:none;
- }
- & section {
- min-height: 2rem;
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
- grid-auto-rows: max-content;
- & .pod-item {
- display:grid;
- grid-template-columns: 1fr;
- text-align: center;
- & .pod-img {
- max-width: 100%;
- margin-inline: auto;
- }
- & :has(> .minibut) {
- padding-block: 0.6rem;
- }
- }
- }
- }
- & #transport {
- &, & > div {
- display: flex;
- flex-flow: row wrap;
- justify-content: space-around;
- }
- & > div {
- flex: 1 1 auto;
- border-radius: 0;
- &:not(:first-child) {
- border-inline-start: 1px groove currentcolor;
- }
- }
- }
- & #gamrow {
- text-align: center;
- }
- & #buttons {
- display: flex;
- flex-flow: row wrap;
- align-content: space-around;
- justify-content: space-around;
- padding-block: 0.375rem;
- & > :is(button, div) {
- appearance: none;
- display: flex;
- flex-flow: row nowrap;
- align-items: center;
- justify-content: center;
- font-family: "Amazon Ember";
- font-size: 1.1rem;
- line-height: 1.1rem;
- background: #077398;
- color: white;
- margin: 0.375rem;
- padding: 0.125rem 0.5rem;
- border: none;
- border-radius: 0.25rem;
- &, & img {
- box-shadow: 0 0 0.25rem 0 #077398;
- }
- }
- & button {
- margin-inline-start: 0.5rem;
- cursor: pointer;
- &:hover {
- &, & img {
- box-shadow: inset 0 0 0.25rem 0 canvas, 0 0 0.5rem 0 canvastext;
- }
- }
- & img {
- margin-inline-start: -1rem;
- margin-inline-end: 0.25rem;
- }
- }
- }
- & .errMsg {
- color: var(--redText);
- font-size: small;
- }
- & :is(.AVD, .LOCK, .SAME, .SWA) {
- padding-left: 12px;
- border-radius: 1em 1em 0 0;
- }
- }
- & :is(#buttons button img, .minibut) {
- height: 2.2rem;
- padding: 0.25rem;
- background: white;
- border-radius: 100%;
- overflow: hidden;
- cursor: pointer;
- margin-block: -1.5rem;
- }
- & .minibut{
- margin-inline: 0.125rem;
- margin-block: -0.6rem;
- vertical-align: middle;
- &:hover {
- box-shadow: inset 0 0 0.25rem 0 canvas, 0 0 0.5rem 0 canvastext;
- }
- &:first-of-type {
- margin-inline-start: 0.75rem;
- }
- &:last-of-type {
- margin-inline-end: -0.25rem;
- }
- }
- & table[data-improve-scc=true] {
- & button {
- border-radius: 0.375rem;
- margin-inline: 0.125rem;
- padding-inline: 0.25rem;
- padding-block: 0.125rem;
- &.copyButton {
- display: inline-block;
- }
- }
- & :is(thead, tfoot) th {
- text-align: start;
- padding: 0;
- &:not(:has( > *)) {
- border: none;
- }
- & > * {
- margin: 0.5rem;
- }
- }
- & td:first-child {
- white-space: nowrap;
- }
- & :is(.newRow, .newRow td, .newRow th) {
- border: 2px inset;
- border-block-end: none;
- }
- & tr.newRow {
- & td > * {
- margin-inline-end: 0.75rem;
- }
- & td > .photoImg {
- display: block;
- width: 100%;
- max-width: calc(120vw - 1rem);
- max-height: calc(120vh - 1rem);
- object-fit: contain;
- margin-block-start: 0.75rem;
- &.hide {
- display: none;
- }
- }
- }
- & tr.newRow + tr {
- border: 2px inset;
- border-top: none;
- &, & td, & th {
- border-block-end: 2px outset;
- }
- & :is(td:first-of-type, th:first-of-type) {
- border-left: 2px inset;
- }
- & :is(td:last-of-type, th:last-of-type) {
- border-right: 2px inset;
- }
- }
- & .newDay.newRow:not(.newRow + tr) {
- &, & td, & th {
- border-top: 3px solid currentcolor;
- }
- }
- & :is(.delSuc, .delSuc td, .delSuc th) {
- background: var(--greenTableBG)!important;
- }
- & :is(.delFail, .delFail td, .delFail th) {
- background: var(--yellowTableBG)!important;
- }
- & :is(.endFail, .endFail td, .endFail th) {
- background: var(--redTableBG)!important;
- }
- & :is(.rts, .rts td, .rts th) {
- background: var(--blueTableBG)!important;
- }
- & :is(.oor, .oor td, .oor th) {
- background: var(--cyanTableBG)!important;
- }
- & .goodTime {
- color: var(--greenText)!important;
- }
- & .poorTime {
- color: var(--orangeText)!important;
- }
- & :is(.badTime, .longDistance) {
- color: var(--redText)!important;
- }
- & svg.bag {
- background: silver;
- border-radius: 0.75rem;
- max-height: 100%;
- position: absolute;
- inset-block: 0;
- inset-inline-end: 0;
- margin-block: auto;
- max-width: 3rem;
- &.BLK .colour{
- fill: black;
- }
- &.GRN .colour{
- fill: green;
- }
- &.NVY .colour{
- fill: blue;
- }
- &.YLO .colour{
- fill: yellow;
- }
- &.ORG .colour{
- fill: orange;
- }
- }
- & .die {
- display: none;
- }
- }
- & [role=tablist] label {
- line-height: 1rem;
- flex: 1 1 auto;
- & > div:last-child {
- margin-block: 0;
- }
- & > span > div {
- padding-block: 0.125rem;
- padding-inline: 1rem;
- }
- }
- & :is(#flags > strong, .goodTime, .poorTime, .badTime, .longDistance) {
- background: canvas;
- border-radius: 0.5rem;
- padding: 0.0625em 0.25rem;
- margin-block: 0.125rem;
- }
- & div > a.minibadge {
- position: absolute;
- display: none;
- right: 8px;
- top: -32px;
- z-index: 10;
- }
- & div:hover > .minibadge {
- display: initial;
- }
- & :is(b,strong) > .minibadge {
- display: none;
- position: relative;
- background: white;
- border: 3px ridge silver;
- border-radius: 8px;
- margin: -3em 0;
- height: 7em;
- z-index: 10;
- }
- & :is(b,strong):hover > .minibadge {
- display: block;
- }
- }
- :root[data-improve-scc-css-receive-page] {
- & .fmcdone {
- text-decoration: underline;
- }
- }
- :root[data-improve-scc-css-outbound-page] {
- font-size: 0.8rem;
- & * {
- font-size: inherit!important;
- line-height: inherit!important;
- }
- & div:has( table) {
- overflow-x: unset!important;
- }
- & th {
- padding-inline-end: 0.25rem;
- }
- & :is(th, td) {
- padding-inline-start: 0.25rem;
- padding-block: 0.25rem;
- }
- & #root div.highlighted-warning {
- color: black;
- text-align: center;
- }
- }
- :root[data-improve-scc-css-badges-page] {
- & :is(tr, th, td) {
- border-block-end: 2px solid silver;
- }
- & :is(span, a).badge {
- display: flex;
- align-content: center;
- justify-content: center;
- align-items: center;
- justify-items: center;
- flex-flow: column-reverse nowrap;
- }
- }
- dialog {
- inset: 50vh 50vw;
- inset: 50dvh 50dvw;
- transform: translate(-50%, -50%);
- background: canvas;
- color: canvastext;
- border: 2px ridge #0096D6;
- border-radius: 1em;
- padding: 3rem;
- width: max-content;
- &.QR {
- color-scheme: light;
- }
- & button.close {
- position: absolute;
- inset: 0.5rem 0.5rem auto auto;
- margin: 0;
- }
- }
- div.button-align:has(> button.close) {
- width: 100%;
- height: 0;
- overflow: visible;
- display: flex;
- flex-flow: row-reverse nowrap;
- margin: 0.125rem;
- }
- button.close {
- cursor: pointer;
- background: firebrick;
- color: white;
- border: 0.125rem ridge red;
- border-radius: 1rem;
- padding: 0;
- width: 2em;
- height: 2em;
- z-index: 3;
- &:is(:hover, :focus, :active) {
- box-shadow: inset 0 0 0.125rem 0.125rem red;
- background: firebrick;
- color: white;
- }
- }
- ::backdrop {
- backdrop-filter: blur(5px) brightness(50%);
- }
- @-moz-document url-prefix() {
- ::backdrop {
- background: #00000088;
- }
- }
- `);
- }
- //#endregion
- //#region: non-SCC pages | start SCC
- (() => {
- debuglog(`multiple check - ${window.ImproveSCC}`);
- if (window.ImproveSCC) return;
- window.ImproveSCC = true;
- if (hrefContains('midway-auth')) {
- if (window.name == 'midwayAuth') {
- debuglog('midwayAuthPage');
- wait$('#auth-success-view').then(success => {
- new MutationObserver(() => {
- if (success?.style?.display == 'block') { window.close(); }
- }).observe(success, { characterData: false, attributes: true, childList: false, subtree: false });
- });
- }
- return;
- }
- if (hrefContains('siw-eu-dub.dub.') || hrefContains('siw-na-iad.iad')) {
- debuglog('GCRSsearchPage');
- const tId = window.location.hash.slice(1);
- debuglog(tId);
- return tId && wait$('[ng-model="vm.queryItems"]', { customProps: { input: tId } }).then(input => {
- debuglog(input);
- input.do('input');
- wait$('[ng-click="vm.query()"]:not([disabled])').then(button => button.do('click'));
- });
- }
- if (hrefContains('royalmail')) {
- debuglog('RMpostcodePage');
- const addr = decodeURI(window.location.hash.slice(1));
- debuglog(addr);
- return addr && wait$('#edit-rml-postcode-finder-postal-code').then(input => {
- debuglog(input);
- input.focus();
- input.value = addr;
- input.do('input');
- });
- }
- if (GM.info.scriptHandler == 'Greasemonkey') {
- alert('Improve SCC Search\n\nThis script will not run in Greasemonkey due to a limitation with how the extension handles iframes.\nPlease install with Tampermonkey.');
- window.open('https://www.tampermonkey.net');
- return;
- }
- addCSS();
- startup();
- })();
- //#endregion
RAW Paste Data
Copied
