@opentripplanner/core-utils 15.0.0 → 16.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/index.js +3 -0
- package/esm/index.js.map +1 -1
- package/esm/itinerary.js +104 -78
- package/esm/itinerary.js.map +1 -1
- package/esm/map.js +2 -2
- package/esm/map.js.map +1 -1
- package/esm/query-gen.js +9 -5
- package/esm/query-gen.js.map +1 -1
- package/esm/route.js +26 -20
- package/esm/route.js.map +1 -1
- package/esm/storage.js +4 -1
- package/esm/storage.js.map +1 -1
- package/esm/time.js +6 -5
- package/esm/time.js.map +1 -1
- package/esm/ui.js +4 -2
- package/esm/ui.js.map +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +6 -0
- package/lib/index.js.map +1 -1
- package/lib/itinerary.d.ts +20 -11
- package/lib/itinerary.d.ts.map +1 -1
- package/lib/itinerary.js +96 -85
- package/lib/itinerary.js.map +1 -1
- package/lib/map.d.ts +2 -2
- package/lib/map.d.ts.map +1 -1
- package/lib/map.js +1 -1
- package/lib/map.js.map +1 -1
- package/lib/query-gen.d.ts +1 -19
- package/lib/query-gen.d.ts.map +1 -1
- package/lib/query-gen.js +9 -5
- package/lib/query-gen.js.map +1 -1
- package/lib/route.d.ts +10 -8
- package/lib/route.d.ts.map +1 -1
- package/lib/route.js +22 -16
- package/lib/route.js.map +1 -1
- package/lib/storage.d.ts +1 -1
- package/lib/storage.d.ts.map +1 -1
- package/lib/storage.js +4 -1
- package/lib/storage.js.map +1 -1
- package/lib/time.d.ts +3 -1
- package/lib/time.d.ts.map +1 -1
- package/lib/time.js +5 -4
- package/lib/time.js.map +1 -1
- package/lib/ui.d.ts.map +1 -1
- package/lib/ui.js +4 -2
- package/lib/ui.js.map +1 -1
- package/package.json +9 -7
- package/src/__tests__/itinerary.ts +64 -6
- package/src/index.ts +3 -0
- package/src/itinerary.ts +145 -97
- package/src/map.ts +5 -3
- package/src/query-gen.ts +15 -9
- package/src/route.ts +65 -38
- package/src/storage.ts +8 -2
- package/src/time.ts +7 -6
- package/src/ui.ts +8 -6
- package/tsconfig.json +1 -0
- package/tsconfig.tsbuildinfo +1 -1
package/lib/storage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAK5D;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAK5D;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,CAAC,EACvB,GAAG,EAAE,MAAM,EACX,aAAa,GAAE,CAAC,GAAG,IAAW,GAC7B,CAAC,GAAG,IAAI,CAeV;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE5C;AAED;;;GAGG;AACH,wBAAgB,MAAM,IAAI,MAAM,CAI/B"}
|
package/lib/storage.js
CHANGED
|
@@ -23,9 +23,12 @@ function storeItem(key, object) {
|
|
|
23
23
|
* null or, the optionally provided notFoundValue.
|
|
24
24
|
*/
|
|
25
25
|
function getItem(key, notFoundValue = null) {
|
|
26
|
-
let itemAsString;
|
|
26
|
+
let itemAsString = null;
|
|
27
27
|
try {
|
|
28
28
|
itemAsString = window.localStorage.getItem(`${STORAGE_PREFIX}.${key}`);
|
|
29
|
+
if (!itemAsString) {
|
|
30
|
+
return notFoundValue;
|
|
31
|
+
}
|
|
29
32
|
const json = JSON.parse(itemAsString);
|
|
30
33
|
if (json) return json;
|
|
31
34
|
return notFoundValue;
|
package/lib/storage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","names":["STORAGE_PREFIX","storeItem","key","object","window","localStorage","setItem","JSON","stringify","getItem","notFoundValue","itemAsString","json","parse","e","console","warn","removeItem","randId","Math","random","toString","substr"],"sources":["../src/storage.ts"],"sourcesContent":["/* eslint-disable no-console */\n// Prefix to use with local storage keys.\nconst STORAGE_PREFIX = \"otp\";\n\n/**\n * Store a javascript object at the specified key.\n */\nexport function storeItem(key: string, object: unknown): void {\n window.localStorage.setItem(\n `${STORAGE_PREFIX}.${key}`,\n JSON.stringify(object)\n );\n}\n\n/**\n * Retrieve a javascript object at the specified key. If not found, defaults to\n * null or, the optionally provided notFoundValue.\n */\nexport function getItem(key: string
|
|
1
|
+
{"version":3,"file":"storage.js","names":["STORAGE_PREFIX","storeItem","key","object","window","localStorage","setItem","JSON","stringify","getItem","notFoundValue","itemAsString","json","parse","e","console","warn","removeItem","randId","Math","random","toString","substr"],"sources":["../src/storage.ts"],"sourcesContent":["/* eslint-disable no-console */\n// Prefix to use with local storage keys.\nconst STORAGE_PREFIX = \"otp\";\n\n/**\n * Store a javascript object at the specified key.\n */\nexport function storeItem(key: string, object: unknown): void {\n window.localStorage.setItem(\n `${STORAGE_PREFIX}.${key}`,\n JSON.stringify(object)\n );\n}\n\n/**\n * Retrieve a javascript object at the specified key. If not found, defaults to\n * null or, the optionally provided notFoundValue.\n */\nexport function getItem<T>(\n key: string,\n notFoundValue: T | null = null\n): T | null {\n let itemAsString: string | null = null;\n try {\n itemAsString = window.localStorage.getItem(`${STORAGE_PREFIX}.${key}`);\n if (!itemAsString) {\n return notFoundValue;\n }\n const json = JSON.parse(itemAsString);\n if (json) return json;\n return notFoundValue;\n } catch (e) {\n // Catch any errors associated with parsing bad JSON.\n console.warn(e, itemAsString);\n return notFoundValue;\n }\n}\n\n/**\n * Remove item at specified key.\n */\nexport function removeItem(key: string): void {\n window.localStorage.removeItem(`${STORAGE_PREFIX}.${key}`);\n}\n\n/**\n * Generate a random ID. This might not quite be a UUID, but it serves our\n * purposes for now.\n */\nexport function randId(): string {\n return Math.random()\n .toString(36)\n .substr(2, 9);\n}\n"],"mappings":";;;;;;;;;AAAA;AACA;AACA,MAAMA,cAAc,GAAG,KAAK;;AAE5B;AACA;AACA;AACO,SAASC,SAASA,CAACC,GAAW,EAAEC,MAAe,EAAQ;EAC5DC,MAAM,CAACC,YAAY,CAACC,OAAO,CACzB,GAAGN,cAAc,IAAIE,GAAG,EAAE,EAC1BK,IAAI,CAACC,SAAS,CAACL,MAAM,CACvB,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACO,SAASM,OAAOA,CACrBP,GAAW,EACXQ,aAAuB,GAAG,IAAI,EACpB;EACV,IAAIC,YAA2B,GAAG,IAAI;EACtC,IAAI;IACFA,YAAY,GAAGP,MAAM,CAACC,YAAY,CAACI,OAAO,CAAC,GAAGT,cAAc,IAAIE,GAAG,EAAE,CAAC;IACtE,IAAI,CAACS,YAAY,EAAE;MACjB,OAAOD,aAAa;IACtB;IACA,MAAME,IAAI,GAAGL,IAAI,CAACM,KAAK,CAACF,YAAY,CAAC;IACrC,IAAIC,IAAI,EAAE,OAAOA,IAAI;IACrB,OAAOF,aAAa;EACtB,CAAC,CAAC,OAAOI,CAAC,EAAE;IACV;IACAC,OAAO,CAACC,IAAI,CAACF,CAAC,EAAEH,YAAY,CAAC;IAC7B,OAAOD,aAAa;EACtB;AACF;;AAEA;AACA;AACA;AACO,SAASO,UAAUA,CAACf,GAAW,EAAQ;EAC5CE,MAAM,CAACC,YAAY,CAACY,UAAU,CAAC,GAAGjB,cAAc,IAAIE,GAAG,EAAE,CAAC;AAC5D;;AAEA;AACA;AACA;AACA;AACO,SAASgB,MAAMA,CAAA,EAAW;EAC/B,OAAOC,IAAI,CAACC,MAAM,CAAC,CAAC,CACjBC,QAAQ,CAAC,EAAE,CAAC,CACZC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC;AACjB","ignoreList":[]}
|
package/lib/time.d.ts
CHANGED
|
@@ -30,7 +30,9 @@ export declare function getLongDateFormat(config: Config): string;
|
|
|
30
30
|
* Offsets a time according to the provided time options
|
|
31
31
|
* and returns the result.
|
|
32
32
|
*/
|
|
33
|
-
export declare function offsetTime(ms:
|
|
33
|
+
export declare function offsetTime(ms: number, options?: {
|
|
34
|
+
offset: number;
|
|
35
|
+
}): number;
|
|
34
36
|
/**
|
|
35
37
|
* Formats a seconds after midnight value for display in narrative
|
|
36
38
|
* @param {number} seconds time since midnight in seconds
|
package/lib/time.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAMhD,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAChD,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAE3C;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,GACd;IACD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAMA;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,UAAU,MAAM,KAAG,MAC3B,CAAC;AAEhC;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,kBAAkB;AAClB,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAExD;AACD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAMhD,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAChD,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAE3C;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,GACd;IACD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAMA;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,UAAU,MAAM,KAAG,MAC3B,CAAC;AAEhC;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,kBAAkB;AAClB,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAExD;AACD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE3E;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,MAAM,CAGR;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,gBAAgB,SAAkB,GAAG,MAAM,CAI1E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,SAAoB,GAAG,MAAM,CAEnE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,SAAoB,GAAG,MAAM,CAEnE"}
|
package/lib/time.js
CHANGED
|
@@ -87,8 +87,9 @@ function formatSecondsAfterMidnight(seconds, timeFormat) {
|
|
|
87
87
|
* GMT+0 if the Intl API is unavailable.
|
|
88
88
|
*/
|
|
89
89
|
function getUserTimezone(fallbackTimezone = "Etc/Greenwich") {
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
var _process$env$TZ, _Intl$DateTimeFormat$;
|
|
91
|
+
if (process.env.NODE_ENV === "test") return (_process$env$TZ = process.env.TZ) !== null && _process$env$TZ !== void 0 ? _process$env$TZ : fallbackTimezone;
|
|
92
|
+
return (_Intl$DateTimeFormat$ = Intl === null || Intl === void 0 ? void 0 : Intl.DateTimeFormat().resolvedOptions().timeZone) !== null && _Intl$DateTimeFormat$ !== void 0 ? _Intl$DateTimeFormat$ : fallbackTimezone;
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
/**
|
|
@@ -96,7 +97,7 @@ function getUserTimezone(fallbackTimezone = "Etc/Greenwich") {
|
|
|
96
97
|
* The conversion to the user's timezone is needed for testing purposes.
|
|
97
98
|
*/
|
|
98
99
|
function getCurrentTime(timezone = getUserTimezone()) {
|
|
99
|
-
return (0, _dateFns.format)((0, _dateFnsTz.
|
|
100
|
+
return (0, _dateFns.format)((0, _dateFnsTz.toZonedTime)(Date.now(), timezone), OTP_API_TIME_FORMAT);
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
/**
|
|
@@ -104,6 +105,6 @@ function getCurrentTime(timezone = getUserTimezone()) {
|
|
|
104
105
|
* The conversion to the user's timezone is needed for testing purposes.
|
|
105
106
|
*/
|
|
106
107
|
function getCurrentDate(timezone = getUserTimezone()) {
|
|
107
|
-
return (0, _dateFns.format)((0, _dateFnsTz.
|
|
108
|
+
return (0, _dateFns.format)((0, _dateFnsTz.toZonedTime)(Date.now(), timezone), OTP_API_DATE_FORMAT);
|
|
108
109
|
}
|
|
109
110
|
//# sourceMappingURL=time.js.map
|
package/lib/time.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time.js","names":["_dateFns","require","_dateFnsTz","OTP_API_DATE_FORMAT","exports","OTP_API_TIME_FORMAT","toHoursMinutesSeconds","seconds","hours","Math","floor","minutes","ensureAtLeastOneMinute","duration","getTimeFormat","config","_config$dateTime","dateTime","timeFormat","getDateFormat","_config$dateTime2","dateFormat","getLongDateFormat","_config$dateTime3","longDateFormat","offsetTime","ms","options","offset","formatSecondsAfterMidnight","time","add","startOfDay","Date","format","getUserTimezone","fallbackTimezone","process","env","NODE_ENV","TZ","Intl","DateTimeFormat","resolvedOptions","timeZone","getCurrentTime","timezone","
|
|
1
|
+
{"version":3,"file":"time.js","names":["_dateFns","require","_dateFnsTz","OTP_API_DATE_FORMAT","exports","OTP_API_TIME_FORMAT","toHoursMinutesSeconds","seconds","hours","Math","floor","minutes","ensureAtLeastOneMinute","duration","getTimeFormat","config","_config$dateTime","dateTime","timeFormat","getDateFormat","_config$dateTime2","dateFormat","getLongDateFormat","_config$dateTime3","longDateFormat","offsetTime","ms","options","offset","formatSecondsAfterMidnight","time","add","startOfDay","Date","format","getUserTimezone","fallbackTimezone","_process$env$TZ","_Intl$DateTimeFormat$","process","env","NODE_ENV","TZ","Intl","DateTimeFormat","resolvedOptions","timeZone","getCurrentTime","timezone","toZonedTime","now","getCurrentDate"],"sources":["../src/time.ts"],"sourcesContent":["import { Config } from \"@opentripplanner/types\";\nimport { startOfDay, add, format } from \"date-fns\";\nimport { toZonedTime } from \"date-fns-tz\";\n\n// Date/time formats (per date-fns) when sending/receiving date from OTP\n// regardless of whatever the user has configured as the display format.\nexport const OTP_API_DATE_FORMAT = \"yyyy-MM-dd\";\nexport const OTP_API_TIME_FORMAT = \"HH:mm\";\n\n/**\n * Breaks up a duration in seconds into hours, minutes, and seconds.\n * @param {number} seconds The number of seconds to break up\n * @returns an object with fields with the corresponding, hours, minutes, seconds.\n */\nexport function toHoursMinutesSeconds(\n seconds: number\n): {\n hours: number;\n minutes: number;\n seconds: number;\n} {\n return {\n hours: Math.floor(seconds / 3600),\n minutes: Math.floor(seconds / 60) % 60,\n seconds: seconds % 60\n };\n}\n\n/**\n * If a duration is less than 60 seconds, round it to one minute, to avoid a duration\n * of 0 minutes on a leg.\n * @param {number} duration The leg or trip duration in seconds\n * @returns a duration in seconds of at least 60 seconds.\n */\nexport const ensureAtLeastOneMinute = (duration: number): number =>\n duration < 60 ? 60 : duration;\n\n/**\n * @param {[type]} config the OTP config object found in store\n * @return {string} the config-defined time formatter or HH:mm (24-hr time)\n */\nexport function getTimeFormat(config: Config): string {\n return config?.dateTime?.timeFormat || OTP_API_TIME_FORMAT;\n}\n\nexport function getDateFormat(config: Config): string {\n return config?.dateTime?.dateFormat || OTP_API_DATE_FORMAT;\n}\n\n/** @deprecated */\nexport function getLongDateFormat(config: Config): string {\n return config?.dateTime?.longDateFormat || \"D MMMM YYYY\";\n}\n/**\n * Offsets a time according to the provided time options\n * and returns the result.\n */\nexport function offsetTime(ms: number, options?: { offset: number }): number {\n return ms + (options?.offset || 0);\n}\n\n/**\n * Formats a seconds after midnight value for display in narrative\n * @param {number} seconds time since midnight in seconds\n * @param {string} timeFormat A valid date-fns time format\n * @return {string} formatted text representation\n */\nexport function formatSecondsAfterMidnight(\n seconds: number,\n timeFormat: string\n): string {\n const time = add(startOfDay(new Date()), { seconds });\n return format(time, timeFormat);\n}\n\n/**\n * Uses Intl.DateTimeFormat() api to get the user's time zone. In a test\n * environment, pulls timezone information from an env variable. Default to\n * GMT+0 if the Intl API is unavailable.\n */\nexport function getUserTimezone(fallbackTimezone = \"Etc/Greenwich\"): string {\n if (process.env.NODE_ENV === \"test\")\n return process.env.TZ ?? fallbackTimezone;\n return Intl?.DateTimeFormat().resolvedOptions().timeZone ?? fallbackTimezone;\n}\n\n/**\n * Formats current time for use in OTP query\n * The conversion to the user's timezone is needed for testing purposes.\n */\nexport function getCurrentTime(timezone = getUserTimezone()): string {\n return format(toZonedTime(Date.now(), timezone), OTP_API_TIME_FORMAT);\n}\n\n/**\n * Formats current date for use in OTP query\n * The conversion to the user's timezone is needed for testing purposes.\n */\nexport function getCurrentDate(timezone = getUserTimezone()): string {\n return format(toZonedTime(Date.now(), timezone), OTP_API_DATE_FORMAT);\n}\n"],"mappings":"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","ignoreList":[]}
|
package/lib/ui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,IAAI,OAAO,CAKlC;AACD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,IAAI,OAAO,CAKlC;AACD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CA8C9D"}
|
package/lib/ui.js
CHANGED
|
@@ -21,9 +21,11 @@ function enableScrollForSelector(selector) {
|
|
|
21
21
|
|
|
22
22
|
function isOverlayTotallyScrolled() {
|
|
23
23
|
// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions
|
|
24
|
+
if (!overlay) return false;
|
|
24
25
|
return overlay.scrollHeight - overlay.scrollTop <= overlay.clientHeight;
|
|
25
26
|
}
|
|
26
27
|
function disableRubberBand(event) {
|
|
28
|
+
if (!overlay || clientY === null) return;
|
|
27
29
|
const clientYDelta = event.targetTouches[0].clientY - clientY;
|
|
28
30
|
if (overlay.scrollTop === 0 && clientYDelta > 0) {
|
|
29
31
|
// element is at the top of its scroll
|
|
@@ -34,13 +36,13 @@ function enableScrollForSelector(selector) {
|
|
|
34
36
|
event.preventDefault();
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
|
-
overlay.addEventListener("touchstart",
|
|
39
|
+
overlay === null || overlay === void 0 || overlay.addEventListener("touchstart", event => {
|
|
38
40
|
if (event.targetTouches.length === 1) {
|
|
39
41
|
// detect single touch
|
|
40
42
|
clientY = event.targetTouches[0].clientY;
|
|
41
43
|
}
|
|
42
44
|
}, false);
|
|
43
|
-
overlay.addEventListener("touchmove",
|
|
45
|
+
overlay === null || overlay === void 0 || overlay.addEventListener("touchmove", event => {
|
|
44
46
|
if (event.targetTouches.length === 1) {
|
|
45
47
|
// detect single touch
|
|
46
48
|
disableRubberBand(event);
|
package/lib/ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.js","names":["isMobile","test","navigator","userAgent","enableScrollForSelector","selector","overlay","document","querySelector","clientY","isOverlayTotallyScrolled","scrollHeight","scrollTop","clientHeight","disableRubberBand","event","clientYDelta","targetTouches","preventDefault","addEventListener","length"],"sources":["../src/ui.ts"],"sourcesContent":["export function isMobile(): boolean {\n // TODO: consider using 3rd-party library?\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\n navigator.userAgent\n );\n}\n/**\n * Enables scrolling for a specified selector, while disabling scrolling for all\n * other targets. This is adapted from https://stackoverflow.com/a/41601290/915811\n * and intended to fix issues with iOS elastic scrolling, e.g.,\n * https://github.com/conveyal/trimet-mod-otp/issues/92.\n */\nexport function enableScrollForSelector(selector: string): void {\n const overlay = document.querySelector(selector);\n let clientY = null; // remember Y position on touch start\n\n function isOverlayTotallyScrolled(): boolean {\n // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions\n return overlay.scrollHeight - overlay.scrollTop <= overlay.clientHeight;\n }\n\n function disableRubberBand(event: TouchEvent) {\n const clientYDelta = event.targetTouches[0].clientY - clientY;\n\n if (overlay.scrollTop === 0 && clientYDelta > 0) {\n // element is at the top of its scroll\n event.preventDefault();\n }\n\n if (isOverlayTotallyScrolled() && clientYDelta < 0) {\n // element is at the top of its scroll\n event.preventDefault();\n }\n }\n\n overlay
|
|
1
|
+
{"version":3,"file":"ui.js","names":["isMobile","test","navigator","userAgent","enableScrollForSelector","selector","overlay","document","querySelector","clientY","isOverlayTotallyScrolled","scrollHeight","scrollTop","clientHeight","disableRubberBand","event","clientYDelta","targetTouches","preventDefault","addEventListener","length"],"sources":["../src/ui.ts"],"sourcesContent":["export function isMobile(): boolean {\n // TODO: consider using 3rd-party library?\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\n navigator.userAgent\n );\n}\n/**\n * Enables scrolling for a specified selector, while disabling scrolling for all\n * other targets. This is adapted from https://stackoverflow.com/a/41601290/915811\n * and intended to fix issues with iOS elastic scrolling, e.g.,\n * https://github.com/conveyal/trimet-mod-otp/issues/92.\n */\nexport function enableScrollForSelector(selector: string): void {\n const overlay = document.querySelector<HTMLElement>(selector);\n let clientY: number | null = null; // remember Y position on touch start\n\n function isOverlayTotallyScrolled(): boolean {\n // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions\n if (!overlay) return false;\n return overlay.scrollHeight - overlay.scrollTop <= overlay.clientHeight;\n }\n\n function disableRubberBand(event: TouchEvent) {\n if (!overlay || clientY === null) return;\n const clientYDelta = event.targetTouches[0].clientY - clientY;\n\n if (overlay.scrollTop === 0 && clientYDelta > 0) {\n // element is at the top of its scroll\n event.preventDefault();\n }\n\n if (isOverlayTotallyScrolled() && clientYDelta < 0) {\n // element is at the top of its scroll\n event.preventDefault();\n }\n }\n\n overlay?.addEventListener(\n \"touchstart\",\n (event: TouchEvent) => {\n if (event.targetTouches.length === 1) {\n // detect single touch\n clientY = event.targetTouches[0].clientY;\n }\n },\n false\n );\n\n overlay?.addEventListener(\n \"touchmove\",\n (event: TouchEvent) => {\n if (event.targetTouches.length === 1) {\n // detect single touch\n disableRubberBand(event);\n }\n },\n false\n );\n}\n"],"mappings":";;;;;;;AAAO,SAASA,QAAQA,CAAA,EAAY;EAClC;EACA,OAAO,gEAAgE,CAACC,IAAI,CAC1EC,SAAS,CAACC,SACZ,CAAC;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,uBAAuBA,CAACC,QAAgB,EAAQ;EAC9D,MAAMC,OAAO,GAAGC,QAAQ,CAACC,aAAa,CAAcH,QAAQ,CAAC;EAC7D,IAAII,OAAsB,GAAG,IAAI,CAAC,CAAC;;EAEnC,SAASC,wBAAwBA,CAAA,EAAY;IAC3C;IACA,IAAI,CAACJ,OAAO,EAAE,OAAO,KAAK;IAC1B,OAAOA,OAAO,CAACK,YAAY,GAAGL,OAAO,CAACM,SAAS,IAAIN,OAAO,CAACO,YAAY;EACzE;EAEA,SAASC,iBAAiBA,CAACC,KAAiB,EAAE;IAC5C,IAAI,CAACT,OAAO,IAAIG,OAAO,KAAK,IAAI,EAAE;IAClC,MAAMO,YAAY,GAAGD,KAAK,CAACE,aAAa,CAAC,CAAC,CAAC,CAACR,OAAO,GAAGA,OAAO;IAE7D,IAAIH,OAAO,CAACM,SAAS,KAAK,CAAC,IAAII,YAAY,GAAG,CAAC,EAAE;MAC/C;MACAD,KAAK,CAACG,cAAc,CAAC,CAAC;IACxB;IAEA,IAAIR,wBAAwB,CAAC,CAAC,IAAIM,YAAY,GAAG,CAAC,EAAE;MAClD;MACAD,KAAK,CAACG,cAAc,CAAC,CAAC;IACxB;EACF;EAEAZ,OAAO,aAAPA,OAAO,eAAPA,OAAO,CAAEa,gBAAgB,CACvB,YAAY,EACXJ,KAAiB,IAAK;IACrB,IAAIA,KAAK,CAACE,aAAa,CAACG,MAAM,KAAK,CAAC,EAAE;MACpC;MACAX,OAAO,GAAGM,KAAK,CAACE,aAAa,CAAC,CAAC,CAAC,CAACR,OAAO;IAC1C;EACF,CAAC,EACD,KACF,CAAC;EAEDH,OAAO,aAAPA,OAAO,eAAPA,OAAO,CAAEa,gBAAgB,CACvB,WAAW,EACVJ,KAAiB,IAAK;IACrB,IAAIA,KAAK,CAACE,aAAa,CAACG,MAAM,KAAK,CAAC,EAAE;MACpC;MACAN,iBAAiB,CAACC,KAAK,CAAC;IAC1B;EACF,CAAC,EACD,KACF,CAAC;AACH","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opentripplanner/core-utils",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "16.0.1",
|
|
4
4
|
"description": "Core functionality that is shared among numerous UI components",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=13"
|
|
@@ -15,18 +15,20 @@
|
|
|
15
15
|
"@conveyal/lonlat": "^1.4.1",
|
|
16
16
|
"@mapbox/polyline": "^1.1.1",
|
|
17
17
|
"@styled-icons/foundation": "^10.34.0",
|
|
18
|
-
"@turf/along": "^
|
|
19
|
-
"chroma-js": "^2.
|
|
20
|
-
"date-fns": "^
|
|
21
|
-
"date-fns-tz": "^
|
|
18
|
+
"@turf/along": "^7.3.1",
|
|
19
|
+
"chroma-js": "^3.2.0",
|
|
20
|
+
"date-fns": "^3.6.0",
|
|
21
|
+
"date-fns-tz": "^3.2.0",
|
|
22
22
|
"graphql": "^16.6.0",
|
|
23
23
|
"lodash.clonedeep": "^4.5.0",
|
|
24
24
|
"qs": "^6.9.1",
|
|
25
|
-
"@opentripplanner/geocoder": "3.0.
|
|
25
|
+
"@opentripplanner/geocoder": "3.0.8"
|
|
26
26
|
},
|
|
27
27
|
"gitHead": "0af1b7cda60bd4252b219dcf893e01c2acb2ed5d",
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@
|
|
29
|
+
"@types/chroma-js": "^3.1.2",
|
|
30
|
+
"@types/mapbox__polyline": "^1.0.5",
|
|
31
|
+
"@opentripplanner/types": "8.4.0"
|
|
30
32
|
},
|
|
31
33
|
"scripts": {
|
|
32
34
|
"tsc": "tsc"
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
getLegRouteShortName,
|
|
13
13
|
isFlex,
|
|
14
14
|
isTransit,
|
|
15
|
+
legElevationAtDistance,
|
|
15
16
|
mapOldElevationComponentToNew
|
|
16
17
|
} from "../itinerary";
|
|
17
18
|
|
|
@@ -22,6 +23,7 @@ import complexItinerary from "./__mocks__/complex-fares.json";
|
|
|
22
23
|
import tripleItinerary from "./__mocks__/three-transfer-itinerary.json";
|
|
23
24
|
import flexItinerary from "../../../itinerary-body/src/__mocks__/itineraries/flex-itinerary.json";
|
|
24
25
|
import faresv2Itinerary from "../../../itinerary-body/src/__mocks__/itineraries/fares-v2-fare-components.json";
|
|
26
|
+
import legFareProdcuts from "../../../itinerary-body/src/__mocks__/itineraries/leg-fare-products.json";
|
|
25
27
|
|
|
26
28
|
global.structuredClone = val => JSON.parse(JSON.stringify(val));
|
|
27
29
|
|
|
@@ -261,21 +263,21 @@ describe("util > itinerary", () => {
|
|
|
261
263
|
"cash",
|
|
262
264
|
"regular"
|
|
263
265
|
);
|
|
264
|
-
expect(result
|
|
265
|
-
expect(result
|
|
266
|
+
expect(result?.amount).toEqual(5.75);
|
|
267
|
+
expect(result?.currency).toEqual({
|
|
266
268
|
code: "USD",
|
|
267
269
|
digits: 2
|
|
268
270
|
});
|
|
269
271
|
});
|
|
270
272
|
it("should calculate the total cost of an itinerary using fares v2", () => {
|
|
271
273
|
const result = getItineraryCost(faresv2Itinerary.legs, "3", "ADULT");
|
|
272
|
-
expect(result
|
|
274
|
+
expect(result?.amount).toEqual(2.8);
|
|
273
275
|
const complexResult = getItineraryCost(
|
|
274
276
|
faresv2Itinerary.legs,
|
|
275
277
|
["0", "0"],
|
|
276
278
|
["ADULT", "ADULT"]
|
|
277
279
|
);
|
|
278
|
-
expect(complexResult
|
|
280
|
+
expect(complexResult?.amount).toEqual(2.8 * 2);
|
|
279
281
|
});
|
|
280
282
|
it("should calculate the total cost of an itinerary with multiple v2 fares & transfers", () => {
|
|
281
283
|
const result = getItineraryCost(complexItinerary.legs, "0", "ADULT");
|
|
@@ -287,7 +289,7 @@ describe("util > itinerary", () => {
|
|
|
287
289
|
["0", "0"],
|
|
288
290
|
["ADULT", null]
|
|
289
291
|
);
|
|
290
|
-
expect(result
|
|
292
|
+
expect(result?.amount).toEqual(11.55);
|
|
291
293
|
});
|
|
292
294
|
it("should calculate the individual leg cost of a fares v2 legs", () => {
|
|
293
295
|
const firstLegResult = getLegCost(faresv2Itinerary.legs[1], "3", "ADULT");
|
|
@@ -308,13 +310,20 @@ describe("util > itinerary", () => {
|
|
|
308
310
|
2.8
|
|
309
311
|
);
|
|
310
312
|
});
|
|
311
|
-
it("should calculate the total cost of an itinerary
|
|
313
|
+
it("should calculate the total cost of an itinerary with null ids", () => {
|
|
312
314
|
const result = getItineraryCost(fareProductItinerary.legs, null, null);
|
|
313
315
|
expect(result.amount).toEqual(2.75);
|
|
314
316
|
expect(result.currency).toEqual({
|
|
315
317
|
code: "USD",
|
|
316
318
|
digits: 2
|
|
317
319
|
});
|
|
320
|
+
const resultWithDashEnabled = getItineraryCost(
|
|
321
|
+
legFareProdcuts.legs,
|
|
322
|
+
"orca",
|
|
323
|
+
"youth",
|
|
324
|
+
true
|
|
325
|
+
);
|
|
326
|
+
expect(resultWithDashEnabled).toEqual(undefined);
|
|
318
327
|
});
|
|
319
328
|
it("should return undefined when the keys are invalid", () => {
|
|
320
329
|
const result = getItineraryCost(
|
|
@@ -404,4 +413,53 @@ describe("util > itinerary", () => {
|
|
|
404
413
|
).toBe("15");
|
|
405
414
|
});
|
|
406
415
|
});
|
|
416
|
+
|
|
417
|
+
describe("legElevationAtDistance", () => {
|
|
418
|
+
it("should interpolate elevation within a segment", () => {
|
|
419
|
+
const points: any = [
|
|
420
|
+
[0, 100],
|
|
421
|
+
[10, 110],
|
|
422
|
+
[20, 120]
|
|
423
|
+
];
|
|
424
|
+
// halfway between 100 and 110
|
|
425
|
+
expect(legElevationAtDistance(points, 5)).toBe(105);
|
|
426
|
+
expect(legElevationAtDistance(points, 15)).toBe(115);
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
it("should return start elevation at distance 0", () => {
|
|
430
|
+
const points: any = [
|
|
431
|
+
[0, 42],
|
|
432
|
+
[10, 52]
|
|
433
|
+
];
|
|
434
|
+
expect(legElevationAtDistance(points, 0)).toBe(42);
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
it("should return end elevation at the segment boundary", () => {
|
|
438
|
+
const points: any = [
|
|
439
|
+
[0, 100],
|
|
440
|
+
[10, 110],
|
|
441
|
+
[20, 120]
|
|
442
|
+
];
|
|
443
|
+
expect(legElevationAtDistance(points, 10)).toBe(110);
|
|
444
|
+
expect(legElevationAtDistance(points, 20)).toBe(120);
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
it("should return undefined when distance is before the profile", () => {
|
|
448
|
+
const points: any = [
|
|
449
|
+
[0, 100],
|
|
450
|
+
[10, 110],
|
|
451
|
+
[20, 120]
|
|
452
|
+
];
|
|
453
|
+
expect(legElevationAtDistance(points, -1)).toBeUndefined();
|
|
454
|
+
expect(legElevationAtDistance(points, 21)).toBeUndefined();
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
it("should return undefined when first point is not at zero", () => {
|
|
458
|
+
const points: any = [
|
|
459
|
+
[5, 100],
|
|
460
|
+
[15, 110]
|
|
461
|
+
];
|
|
462
|
+
expect(legElevationAtDistance(points, 4)).toBeUndefined();
|
|
463
|
+
});
|
|
464
|
+
});
|
|
407
465
|
});
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import * as itinerary from "./itinerary";
|
|
2
2
|
import * as map from "./map";
|
|
3
|
+
// @ts-expect-error not typed
|
|
3
4
|
import * as profile from "./profile";
|
|
5
|
+
// @ts-expect-error not typed
|
|
4
6
|
import * as query from "./query";
|
|
7
|
+
// @ts-expect-error not typed
|
|
5
8
|
import * as queryParams from "./query-params";
|
|
6
9
|
import * as route from "./route";
|
|
7
10
|
import * as storage from "./storage";
|