fix(ci): typed card points, the managed take route, and the failing card tests and ratchets

This commit is contained in:
Maurice
2026-10-22 16:21:20 +02:00
parent db023f4c4d
commit 162f2996d2
77 changed files with 293 additions and 244 deletions
+1
View File
@@ -87,6 +87,7 @@ function checkPluralForms(locale, keys, groups) {
*/
export const NOT_PLURAL = [
{ key: 'assistant.place.addToShort', because: 'the number of the day a found place would go on ("+ Day 3")' },
{ key: 'assistant.card.tour.days', because: 'the numbers of the days a tour lies on ("Days 2, 4")' },
{ key: 'collab.polls.optionPlaceholder', because: 'the position of a poll option ("Option 3")' },
{ key: 'collections.importOnDay', because: 'the number of the day a place is planned on' },
{ key: 'dashboard.atlas.aroundEquator', because: 'a decimal multiplier ("≈ 1.37×"), not a count of things' },
+3 -2
View File
@@ -16,7 +16,9 @@ export const cardLatSchema = z.number().min(-90).max(90);
export const cardLngSchema = z.number().min(-180).max(180);
/** A point of a line to draw, `[lat, lng]` at five decimals; single points are `{ lat, lng }` objects. */
export const cardPointSchema = z.tuple([cardLatSchema, cardLngSchema]);
export type CardPoint = [number, number];
// Typed by hand: server and client compile without strictNullChecks, where an inferred tuple makes every item optional.
export const cardPointSchema: z.ZodType<CardPoint> = z.tuple([cardLatSchema, cardLngSchema]);
export const cardDateSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}$/);
export const cardClockSchema = z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/);
@@ -52,7 +54,6 @@ export const cardDaySchema = z.object({
/** The most one card may weigh, as JSON text; a heavier one is not sent at all. */
export const MAX_CARD_CHARS = 24_000;
export type CardPoint = z.infer<typeof cardPointSchema>;
export type CardMoney = z.infer<typeof cardMoneySchema>;
export type CardPerson = z.infer<typeof cardPersonSchema>;
export type CardDay = z.infer<typeof cardDaySchema>;
@@ -47,10 +47,7 @@ function hike(extra: Partial<TourRouteCard> = {}): TourRouteCard {
[47.61, 11.31, 1670],
],
stretches: [{ facet: 'sac', fromM: 0, toM: 4000, step: 3 }],
stops: [
stop(0, { role: 'start', clock: '08:00' }),
stop(4100, { role: 'end', kind: 'peak', name: 'Hochfelln' }),
],
stops: [stop(0, { role: 'start', clock: '08:00' }), stop(4100, { role: 'end', kind: 'peak', name: 'Hochfelln' })],
stages: null,
skiScheme: null,
schedule: {
@@ -4,7 +4,7 @@ import { HIKE_UNROUTED_REASONS } from '../../tours/hike-plan.schema';
import { HIKE_WARNING_KINDS } from '../../tours/hike-schedule';
import { tourPoiCategorySchema } from '../../tours/tour-poi-category';
import { tourMaxHikingDifficultySchema, tourTypeKeySchema } from '../../tours/tours.schema';
import { cardClockSchema, cardDateSchema, cardLatSchema, cardLngSchema, cardText } from './card-parts';
import { cardClockSchema, cardDateSchema, cardLatSchema, cardLngSchema, cardPointSchema, cardText } from './card-parts';
import { z } from 'zod';
@@ -37,7 +37,13 @@ const minutes = z.number().int().min(0).max(86_400);
const sacStep = z.number().int().min(1).max(6);
/** A point of the line, `[lat, lng, height]` at five decimals; every height is null when one is missing. */
export const tourRoutePointSchema = z.tuple([cardLatSchema, cardLngSchema, height.nullable()]);
export type TourRoutePoint = [number, number, number | null];
// Typed by hand like cardPointSchema: an inferred tuple reads every item as optional where strictNullChecks is off.
export const tourRoutePointSchema: z.ZodType<TourRoutePoint> = z.tuple([
cardLatSchema,
cardLngSchema,
height.nullable(),
]);
/** What a stop is beyond its role: a kind of place along a hike, its highest point, a city walk's station. */
export const TOUR_ROUTE_STOP_KINDS = ['highest', 'station'] as const;
@@ -164,7 +170,7 @@ export const tourRouteCardSchema = z.object({
/** A held change of a saved tour's way: the way it has now, to draw faintly beside the new one. */
previous: z
.object({
line: z.array(z.tuple([cardLatSchema, cardLngSchema])).min(2).max(L.previous),
line: z.array(cardPointSchema).min(2).max(L.previous),
distanceM: metres,
ascentM: climb.nullable(),
minutes: minutes.nullable(),
+5 -6
View File
@@ -224,11 +224,7 @@ describe('pickBookPhotos', () => {
it('PHOTOPICK-010: without signals a caption wins, then a photo the book does not have yet, best first', () => {
const result = pickBookPhotos(
[
at(1, '09:00:00', { inBook: true }),
at(2, '10:00:00'),
at(3, '11:00:00', { caption: 'Tram 28', inBook: true }),
],
[at(1, '09:00:00', { inBook: true }), at(2, '10:00:00'), at(3, '11:00:00', { caption: 'Tram 28', inBook: true })],
[],
{ limit: 2 },
);
@@ -342,7 +338,10 @@ describe('pickBookPhotos', () => {
expect(ids(one)).toEqual([[101]]);
expect(one.groups[0]?.dropped).toHaveLength(30);
expect(one.groups[0]?.dropped_more).toBe(5);
const five = pickBookPhotos([1, 2, 3, 4, 5].flatMap((day) => burst(day, 31)), []);
const five = pickBookPhotos(
[1, 2, 3, 4, 5].flatMap((day) => burst(day, 31)),
[],
);
expect(bookPhotoSuggestionsSchema.parse(five)).toEqual(five);
expect(five.groups.map((g) => [g.dropped.length, g.dropped_more])).toEqual([
[30, 0],
+5 -2
View File
@@ -258,7 +258,10 @@ export function pickBookPhotos(
const chosen = filterFor(placed, options, byEntry);
const groups = groupByDayAndPlace(chosen);
const judged = groups.map((g) => judge(g, purpose, median));
const shown = takeRoundRobin(judged.map((j) => j.picks), limit);
const shown = takeRoundRobin(
judged.map((j) => j.picks),
limit,
);
const out: BookPhotoSuggestions['groups'] = [];
let groupsMore = 0;
let droppedRoom: number = PHOTO_PICK.droppedTotal;
@@ -417,7 +420,7 @@ function similarSets(members: readonly Placed[]): Placed[][] {
let r = i;
while (parent[r] !== r) r = parent[r] ?? r;
// Every index on the way now points straight at the root.
for (let k = i; parent[k] !== r; ) {
for (let k = i; parent[k] !== r;) {
const next = parent[k] ?? r;
parent[k] = r;
k = next;
+1 -1
View File
@@ -54,7 +54,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays.few': 'أيام إجازة أخرى هذا العام: {count}',
'assistant.card.vacay.otherDays.many': 'أيام إجازة أخرى هذا العام: {count}',
'assistant.card.vacay.allowance': 'الاستحقاق',
'assistant.card.vacay.meter': '{used} مستخدم، {planned} مخطط، {left} متبقٍ من {total}',
'assistant.card.vacay.meter': '{used} مستخدم، {planned} مخطط، {remaining} متبقٍ من {total}',
'assistant.card.vacay.weekendBlocked': 'عطلة نهاية الأسبوع، محجوبة في خطتك',
'assistant.card.vacay.weekend': 'يوم عطلة نهاية الأسبوع، يُحسب إجازة',
'assistant.card.vacay.publicHoliday': 'عطلة رسمية، لا حاجة لإجازة',
+1 -1
View File
@@ -26,7 +26,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays': 'Bu il daha {count} istirahət günü',
'assistant.card.vacay.otherDays.one': 'Bu il daha {count} istirahət günü',
'assistant.card.vacay.allowance': 'Məzuniyyət limiti',
'assistant.card.vacay.meter': '{used} istifadə olunub, {planned} planlaşdırılıb, {total} gündən {left} qalıb',
'assistant.card.vacay.meter': '{used} istifadə olunub, {planned} planlaşdırılıb, {total} gündən {remaining} qalıb',
'assistant.card.vacay.weekendBlocked': 'Həftəsonu, planınızda bağlıdır',
'assistant.card.vacay.weekend': 'Həftəsonu günü, məzuniyyət sayılır',
'assistant.card.vacay.publicHoliday': 'Rəsmi bayram, məzuniyyət lazım deyil',
+1 -1
View File
@@ -26,7 +26,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays': 'Mais {count} dias de folga este ano',
'assistant.card.vacay.otherDays.one': 'Mais {count} dia de folga este ano',
'assistant.card.vacay.allowance': 'Direito',
'assistant.card.vacay.meter': '{used} usados, {planned} planejados, restam {left} de {total}',
'assistant.card.vacay.meter': '{used} usados, {planned} planejados, restam {remaining} de {total}',
'assistant.card.vacay.weekendBlocked': 'Fim de semana, bloqueado no seu plano',
'assistant.card.vacay.weekend': 'Dia de fim de semana, conta como férias',
'assistant.card.vacay.publicHoliday': 'Feriado, não precisa de folga',
+1 -1
View File
@@ -26,7 +26,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays': '{count} dies lliures més aquest any',
'assistant.card.vacay.otherDays.one': '{count} dia lliure més aquest any',
'assistant.card.vacay.allowance': 'Dret',
'assistant.card.vacay.meter': '{used} gastats, {planned} previstos, queden {left} de {total}',
'assistant.card.vacay.meter': '{used} gastats, {planned} previstos, queden {remaining} de {total}',
'assistant.card.vacay.weekendBlocked': 'Cap de setmana, bloquejat al teu pla',
'assistant.card.vacay.weekend': 'Dia de cap de setmana, compta com a vacances',
'assistant.card.vacay.publicHoliday': 'Festiu, no cal demanar el dia',
+1 -1
View File
@@ -33,7 +33,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays.one': 'Letos ještě {count} den volna',
'assistant.card.vacay.otherDays.few': 'Letos ještě {count} dny volna',
'assistant.card.vacay.allowance': 'Nárok',
'assistant.card.vacay.meter': 'Vyčerpáno {used}, naplánováno {planned}, zbývá {left} z {total}',
'assistant.card.vacay.meter': 'Vyčerpáno {used}, naplánováno {planned}, zbývá {remaining} z {total}',
'assistant.card.vacay.weekendBlocked': 'Víkend, ve tvém plánu zablokovaný',
'assistant.card.vacay.weekend': 'Víkendový den, počítá se jako dovolená',
'assistant.card.vacay.publicHoliday': 'Státní svátek, dovolená není potřeba',
+1 -1
View File
@@ -26,7 +26,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays': '{count} weitere freie Tage in diesem Jahr',
'assistant.card.vacay.otherDays.one': '{count} weiterer freier Tag in diesem Jahr',
'assistant.card.vacay.allowance': 'Urlaubsanspruch',
'assistant.card.vacay.meter': '{used} genommen, {planned} geplant, {left} übrig von {total}',
'assistant.card.vacay.meter': '{used} genommen, {planned} geplant, {remaining} übrig von {total}',
'assistant.card.vacay.weekendBlocked': 'Wochenende, in deinem Plan gesperrt',
'assistant.card.vacay.weekend': 'Wochenendtag, zählt als Urlaub',
'assistant.card.vacay.publicHoliday': 'Feiertag, kein Urlaub nötig',
+1 -1
View File
@@ -26,7 +26,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays': '{count} more days off this year',
'assistant.card.vacay.otherDays.one': '{count} more day off this year',
'assistant.card.vacay.allowance': 'Allowance',
'assistant.card.vacay.meter': '{used} used, {planned} planned, {left} left of {total}',
'assistant.card.vacay.meter': '{used} used, {planned} planned, {remaining} left of {total}',
'assistant.card.vacay.weekendBlocked': 'Weekend, blocked in your plan',
'assistant.card.vacay.weekend': 'Weekend day, counts as leave',
'assistant.card.vacay.publicHoliday': 'Public holiday, no leave needed',
+1 -1
View File
@@ -26,7 +26,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays': '{count} días libres más este año',
'assistant.card.vacay.otherDays.one': '{count} día libre más este año',
'assistant.card.vacay.allowance': 'Derecho',
'assistant.card.vacay.meter': '{used} usados, {planned} previstos, quedan {left} de {total}',
'assistant.card.vacay.meter': '{used} usados, {planned} previstos, quedan {remaining} de {total}',
'assistant.card.vacay.weekendBlocked': 'Fin de semana, bloqueado en tu plan',
'assistant.card.vacay.weekend': 'Día de fin de semana, cuenta como vacaciones',
'assistant.card.vacay.publicHoliday': 'Festivo, no hace falta pedir el día',
+1 -1
View File
@@ -26,7 +26,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays': 'Sel aastal veel {count} vaba päeva',
'assistant.card.vacay.otherDays.one': 'Sel aastal veel {count} vaba päev',
'assistant.card.vacay.allowance': 'Puhkusepäevade õigus',
'assistant.card.vacay.meter': '{used} kasutatud, {planned} plaanis, {total} päevast {left} jäänud',
'assistant.card.vacay.meter': '{used} kasutatud, {planned} plaanis, {total} päevast {remaining} jäänud',
'assistant.card.vacay.weekendBlocked': 'Nädalavahetus, sinu plaanis blokeeritud',
'assistant.card.vacay.weekend': 'Nädalavahetuse päev, loetakse puhkuseks',
'assistant.card.vacay.publicHoliday': 'Riigipüha, puhkust pole vaja',
+1 -1
View File
@@ -26,7 +26,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays': '{count} autres jours de congé cette année',
'assistant.card.vacay.otherDays.one': '{count} autre jour de congé cette année',
'assistant.card.vacay.allowance': 'Droits',
'assistant.card.vacay.meter': '{used} pris, {planned} prévus, {left} restants sur {total}',
'assistant.card.vacay.meter': '{used} pris, {planned} prévus, {remaining} restants sur {total}',
'assistant.card.vacay.weekendBlocked': 'Week-end, bloqué dans votre plan',
'assistant.card.vacay.weekend': 'Jour de week-end, compté comme congé',
'assistant.card.vacay.publicHoliday': 'Jour férié, pas besoin de congé',
+1 -1
View File
@@ -26,7 +26,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays': 'Άλλες {count} μέρες άδειας φέτος',
'assistant.card.vacay.otherDays.one': 'Άλλη {count} μέρα άδειας φέτος',
'assistant.card.vacay.allowance': 'Δικαίωμα',
'assistant.card.vacay.meter': '{used} χρησιμοποιήθηκαν, {planned} σχεδιάζονται, απομένουν {left} από {total}',
'assistant.card.vacay.meter': '{used} χρησιμοποιήθηκαν, {planned} σχεδιάζονται, απομένουν {remaining} από {total}',
'assistant.card.vacay.weekendBlocked': 'Σαββατοκύριακο, μπλοκαρισμένο στο πλάνο σου',
'assistant.card.vacay.weekend': 'Μέρα Σαββατοκύριακου, μετράει ως άδεια',
'assistant.card.vacay.publicHoliday': 'Δημόσια αργία, δεν χρειάζεται άδεια',
+1 -1
View File
@@ -26,7 +26,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays': 'Idén még {count} szabadnap',
'assistant.card.vacay.otherDays.one': 'Idén még {count} szabadnap',
'assistant.card.vacay.allowance': 'Szabadságkeret',
'assistant.card.vacay.meter': '{used} felhasználva, {planned} tervezve, {total} napból {left} maradt',
'assistant.card.vacay.meter': '{used} felhasználva, {planned} tervezve, {total} napból {remaining} maradt',
'assistant.card.vacay.weekendBlocked': 'Hétvége, a tervedben letiltva',
'assistant.card.vacay.weekend': 'Hétvégi nap, szabadságnak számít',
'assistant.card.vacay.publicHoliday': 'Ünnepnap, nem kell szabadság',
+1 -1
View File
@@ -19,7 +19,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.compDays': '{count} hari pengganti',
'assistant.card.vacay.otherDays': '{count} hari libur lagi tahun ini',
'assistant.card.vacay.allowance': 'Jatah cuti',
'assistant.card.vacay.meter': '{used} terpakai, {planned} direncanakan, sisa {left} dari {total}',
'assistant.card.vacay.meter': '{used} terpakai, {planned} direncanakan, sisa {remaining} dari {total}',
'assistant.card.vacay.weekendBlocked': 'Akhir pekan, diblokir di rencanamu',
'assistant.card.vacay.weekend': 'Hari akhir pekan, dihitung sebagai cuti',
'assistant.card.vacay.publicHoliday': 'Hari libur nasional, tidak perlu cuti',
+1 -1
View File
@@ -26,7 +26,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays': "Altri {count} giorni liberi quest'anno",
'assistant.card.vacay.otherDays.one': "{count} altro giorno libero quest'anno",
'assistant.card.vacay.allowance': 'Disponibilità',
'assistant.card.vacay.meter': '{used} usati, {planned} previsti, {left} rimasti su {total}',
'assistant.card.vacay.meter': '{used} usati, {planned} previsti, {remaining} rimasti su {total}',
'assistant.card.vacay.weekendBlocked': 'Fine settimana, bloccato nel tuo piano',
'assistant.card.vacay.weekend': 'Giorno del fine settimana, conta come ferie',
'assistant.card.vacay.publicHoliday': 'Festività, non servono ferie',
+4 -2
View File
@@ -62,8 +62,10 @@ const assistantTour: TranslationStrings = {
'assistant.card.tour.warn.dark_start': '日の出前に出発します({time})',
'assistant.card.tour.warn.dusk': '日没の1時間以内に戻ります',
'assistant.card.tour.warn.legs_failed': '{count}区間を計画できませんでした',
'assistant.card.tour.problem.no_valhalla': 'このサーバーのルート検索は登山道を知らないため、ハイキングを計画できませんでした',
'assistant.card.tour.problem.router_unavailable': 'ルート検索が応答しませんでした。少ししてからもう一度お試しください',
'assistant.card.tour.problem.no_valhalla':
'このサーバーのルート検索は登山道を知らないため、ハイキングを計画できませんでした',
'assistant.card.tour.problem.router_unavailable':
'ルート検索が応答しませんでした。少ししてからもう一度お試しください',
'assistant.card.tour.problem.no_way': 'T{grade}までの道ではこれらの地点を結べません',
'assistant.card.tour.problem.no_way_any': 'これらの地点を結ぶ道がありません',
'assistant.card.tour.problem.point_off_the_way': '地点{point}はどの道からも離れすぎています',
+1 -1
View File
@@ -19,7 +19,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.compDays': '代休{count}日',
'assistant.card.vacay.otherDays': '今年はほかに{count}日休み',
'assistant.card.vacay.allowance': '付与日数',
'assistant.card.vacay.meter': '使用{used}、予定{planned}、{total}日中残り{left}',
'assistant.card.vacay.meter': '使用{used}、予定{planned}、{total}日中残り{remaining}',
'assistant.card.vacay.weekendBlocked': '週末、プランでブロック中',
'assistant.card.vacay.weekend': '週末、休暇として数える',
'assistant.card.vacay.publicHoliday': '祝日、休暇は不要',
+1 -1
View File
@@ -19,7 +19,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.compDays': '대체휴무 {count}일',
'assistant.card.vacay.otherDays': '올해 {count}일 더 쉼',
'assistant.card.vacay.allowance': '휴가 일수',
'assistant.card.vacay.meter': '{used} 사용, {planned} 예정, {total} 중 {left} 남음',
'assistant.card.vacay.meter': '{used} 사용, {planned} 예정, {total} 중 {remaining} 남음',
'assistant.card.vacay.weekendBlocked': '주말, 플랜에서 차단됨',
'assistant.card.vacay.weekend': '주말, 휴가로 계산됨',
'assistant.card.vacay.publicHoliday': '공휴일, 휴가 불필요',
+1 -1
View File
@@ -26,7 +26,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays': 'Nog {count} vrije dagen dit jaar',
'assistant.card.vacay.otherDays.one': 'Nog {count} vrije dag dit jaar',
'assistant.card.vacay.allowance': 'Vakantierecht',
'assistant.card.vacay.meter': '{used} opgenomen, {planned} gepland, {left} over van {total}',
'assistant.card.vacay.meter': '{used} opgenomen, {planned} gepland, {remaining} over van {total}',
'assistant.card.vacay.weekendBlocked': 'Weekend, geblokkeerd in je plan',
'assistant.card.vacay.weekend': 'Weekenddag, telt als vakantie',
'assistant.card.vacay.publicHoliday': 'Feestdag, geen vakantie nodig',
+1 -1
View File
@@ -40,7 +40,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays.few': 'Jeszcze {count} dni wolne w tym roku',
'assistant.card.vacay.otherDays.many': 'Jeszcze {count} dni wolnych w tym roku',
'assistant.card.vacay.allowance': 'Wymiar',
'assistant.card.vacay.meter': 'Wykorzystano {used}, zaplanowano {planned}, zostało {left} z {total}',
'assistant.card.vacay.meter': 'Wykorzystano {used}, zaplanowano {planned}, zostało {remaining} z {total}',
'assistant.card.vacay.weekendBlocked': 'Weekend, zablokowany w Twoim planie',
'assistant.card.vacay.weekend': 'Dzień weekendu, liczy się jako urlop',
'assistant.card.vacay.publicHoliday': 'Święto, urlop niepotrzebny',
+1 -1
View File
@@ -40,7 +40,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays.few': 'Ещё {count} дня отдыха в этом году',
'assistant.card.vacay.otherDays.many': 'Ещё {count} дней отдыха в этом году',
'assistant.card.vacay.allowance': 'Право на отпуск',
'assistant.card.vacay.meter': 'Использовано {used}, запланировано {planned}, осталось {left} из {total}',
'assistant.card.vacay.meter': 'Использовано {used}, запланировано {planned}, осталось {remaining} из {total}',
'assistant.card.vacay.weekendBlocked': 'Выходные, заблокированы в вашем плане',
'assistant.card.vacay.weekend': 'Выходной день, считается отпуском',
'assistant.card.vacay.publicHoliday': 'Праздник, отпуск не нужен',
+1 -1
View File
@@ -33,7 +33,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays.one': 'Tento rok ešte {count} deň voľna',
'assistant.card.vacay.otherDays.few': 'Tento rok ešte {count} dni voľna',
'assistant.card.vacay.allowance': 'Nárok',
'assistant.card.vacay.meter': 'Vyčerpané {used}, naplánované {planned}, zostáva {left} z {total}',
'assistant.card.vacay.meter': 'Vyčerpané {used}, naplánované {planned}, zostáva {remaining} z {total}',
'assistant.card.vacay.weekendBlocked': 'Víkend, vo tvojom pláne zablokovaný',
'assistant.card.vacay.weekend': 'Víkendový deň, počíta sa ako dovolenka',
'assistant.card.vacay.publicHoliday': 'Štátny sviatok, dovolenka nie je potrebná',
+1 -1
View File
@@ -26,7 +26,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays': '{count} lediga dagar till i år',
'assistant.card.vacay.otherDays.one': '{count} ledig dag till i år',
'assistant.card.vacay.allowance': 'Semesterrätt',
'assistant.card.vacay.meter': '{used} uttagna, {planned} planerade, {left} kvar av {total}',
'assistant.card.vacay.meter': '{used} uttagna, {planned} planerade, {remaining} kvar av {total}',
'assistant.card.vacay.weekendBlocked': 'Veckoslut, spärrat i din plan',
'assistant.card.vacay.weekend': 'Veckoslut, räknas som semester',
'assistant.card.vacay.publicHoliday': 'Helgdag, ingen semester behövs',
+1 -1
View File
@@ -19,7 +19,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.compDays': 'วันหยุดชดเชย {count} วัน',
'assistant.card.vacay.otherDays': 'ปีนี้หยุดอีก {count} วัน',
'assistant.card.vacay.allowance': 'สิทธิวันลา',
'assistant.card.vacay.meter': 'ใช้ไป {used} วางแผน {planned} เหลือ {left} จาก {total}',
'assistant.card.vacay.meter': 'ใช้ไป {used} วางแผน {planned} เหลือ {remaining} จาก {total}',
'assistant.card.vacay.weekendBlocked': 'วันหยุดสุดสัปดาห์ ถูกบล็อกในแผนของคุณ',
'assistant.card.vacay.weekend': 'วันหยุดสุดสัปดาห์ นับเป็นวันลา',
'assistant.card.vacay.publicHoliday': 'วันหยุดนักขัตฤกษ์ ไม่ต้องลา',
+1 -1
View File
@@ -26,7 +26,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays': 'Bu yıl {count} izin günü daha',
'assistant.card.vacay.otherDays.one': 'Bu yıl {count} izin günü daha',
'assistant.card.vacay.allowance': 'Hakediş',
'assistant.card.vacay.meter': '{used} kullanıldı, {planned} planlandı, {total} günden {left} kaldı',
'assistant.card.vacay.meter': '{used} kullanıldı, {planned} planlandı, {total} günden {remaining} kaldı',
'assistant.card.vacay.weekendBlocked': 'Hafta sonu, planında engelli',
'assistant.card.vacay.weekend': 'Hafta sonu günü, izin sayılır',
'assistant.card.vacay.publicHoliday': 'Resmi tatil, izin gerekmez',
+1 -1
View File
@@ -40,7 +40,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.otherDays.few': 'Ще {count} дні відпочинку цього року',
'assistant.card.vacay.otherDays.many': 'Ще {count} днів відпочинку цього року',
'assistant.card.vacay.allowance': 'Право на відпустку',
'assistant.card.vacay.meter': 'Використано {used}, заплановано {planned}, залишилося {left} з {total}',
'assistant.card.vacay.meter': 'Використано {used}, заплановано {planned}, залишилося {remaining} з {total}',
'assistant.card.vacay.weekendBlocked': 'Вихідні, заблоковані у вашому плані',
'assistant.card.vacay.weekend': 'Вихідний день, рахується як відпустка',
'assistant.card.vacay.publicHoliday': 'Свято, відпустка не потрібна',
+1 -1
View File
@@ -19,7 +19,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.compDays': '{count} ngày nghỉ bù',
'assistant.card.vacay.otherDays': 'Năm nay còn nghỉ thêm {count} ngày',
'assistant.card.vacay.allowance': 'Số ngày phép',
'assistant.card.vacay.meter': 'Đã dùng {used}, dự kiến {planned}, còn {left} trên {total}',
'assistant.card.vacay.meter': 'Đã dùng {used}, dự kiến {planned}, còn {remaining} trên {total}',
'assistant.card.vacay.weekendBlocked': 'Cuối tuần, bị chặn trong kế hoạch của bạn',
'assistant.card.vacay.weekend': 'Ngày cuối tuần, tính là ngày phép',
'assistant.card.vacay.publicHoliday': 'Ngày lễ, không cần nghỉ phép',
+1 -1
View File
@@ -19,7 +19,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.compDays': '補休 {count} 天',
'assistant.card.vacay.otherDays': '今年還有 {count} 天休假',
'assistant.card.vacay.allowance': '年假額度',
'assistant.card.vacay.meter': '已用 {used},計畫 {planned},共 {total},剩餘 {left}',
'assistant.card.vacay.meter': '已用 {used},計畫 {planned},共 {total},剩餘 {remaining}',
'assistant.card.vacay.weekendBlocked': '週末,在你的計畫中已封鎖',
'assistant.card.vacay.weekend': '週末,計入假期',
'assistant.card.vacay.publicHoliday': '公共假日,無需請假',
+1 -1
View File
@@ -19,7 +19,7 @@ const assistantVacay: TranslationStrings = {
'assistant.card.vacay.compDays': '调休 {count} 天',
'assistant.card.vacay.otherDays': '今年还有 {count} 天休假',
'assistant.card.vacay.allowance': '年假额度',
'assistant.card.vacay.meter': '已用 {used},计划 {planned},共 {total},剩余 {left}',
'assistant.card.vacay.meter': '已用 {used},计划 {planned},共 {total},剩余 {remaining}',
'assistant.card.vacay.weekendBlocked': '周末,在你的计划中已屏蔽',
'assistant.card.vacay.weekend': '周末,计入假期',
'assistant.card.vacay.publicHoliday': '公共假日,无需请假',
+4 -1
View File
@@ -50,7 +50,10 @@ export function cheapestEnergy(tariffs: ChargingInfo['tariffs']): ChargingEnergy
.map((component) => ({ price: component.price, currency: tariff.currency })),
);
if (new Set(energy.map((component) => component.currency)).size !== 1) return null;
return energy.reduce<ChargingEnergyPrice | null>((best, item) => (!best || item.price < best.price ? item : best), null);
return energy.reduce<ChargingEnergyPrice | null>(
(best, item) => (!best || item.price < best.price ? item : best),
null,
);
}
/**