cry-search 2.1.1 → 2.2.0

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.
@@ -40,6 +40,12 @@ var __export = (target, all) => {
40
40
  var exports_vet = {};
41
41
  __export(exports_vet, {
42
42
  ENOTE_SINONIMI: () => ENOTE_SINONIMI,
43
+ PREVODI: () => PREVODI,
44
+ PREVODI_VIR: () => PREVODI_VIR,
45
+ STAROSTI: () => STAROSTI,
46
+ STOP_BESEDE: () => STOP_BESEDE,
47
+ VELIKOSTI_EN: () => VELIKOSTI_EN,
48
+ VELIKOSTI_OKRAJSAVE: () => VELIKOSTI_OKRAJSAVE,
43
49
  VET_NORMALIZATORJI: () => VET_NORMALIZATORJI,
44
50
  VET_TABELA: () => VET_TABELA,
45
51
  VRSTE_SINONIMI: () => VRSTE_SINONIMI,
@@ -50,10 +56,14 @@ __export(exports_vet, {
50
56
  normalizeQueryWithOpts: () => normalizeQueryWithOpts,
51
57
  oceniPar: () => oceniPar,
52
58
  oznakeNormalizator: () => oznakeNormalizator,
59
+ prevodiNormalizator: () => prevodiNormalizator,
53
60
  pripraviVetIndeks: () => pripraviVetIndeks,
61
+ razdeljevalciNormalizator: () => razdeljevalciNormalizator,
62
+ starostNormalizator: () => starostNormalizator,
54
63
  upariArtikle: () => upariArtikle,
55
64
  upariVse: () => upariVse,
56
65
  upariVseSync: () => upariVseSync,
66
+ velikostNormalizator: () => velikostNormalizator,
57
67
  vetArtikelSpec: () => vetArtikelSpec,
58
68
  vetQueryOpts: () => vetQueryOpts,
59
69
  vrstaNormalizator: () => vrstaNormalizator,
@@ -240,6 +250,369 @@ dodajVrsto("jelen", ["jelena", "jeleni", "jelenov", "jelenjad"]);
240
250
  dodajVrsto("srna", ["srne", "srni", "srn", "srnjak", "srnjaka", "srnjaki"]);
241
251
  dodajVrsto("divjad", ["divjadi", "divjadjo"]);
242
252
 
253
+ // src/vet/data/prevodi.ts
254
+ var PREVODI = {
255
+ dog: "pes",
256
+ dogs: "pes",
257
+ pse: "pes",
258
+ puppy: "mladič",
259
+ puppies: "mladič",
260
+ cat: "mačka",
261
+ cats: "mačka",
262
+ kitten: "mladič",
263
+ kittens: "mladič",
264
+ rabbit: "zajec",
265
+ bunny: "zajec",
266
+ chicken: "piščanec",
267
+ chick: "piščanec",
268
+ hen: "kokoš",
269
+ turkey: "puran",
270
+ duck: "raca",
271
+ goose: "gos",
272
+ quail: "prepelica",
273
+ pheasant: "fazan",
274
+ beef: "govedina",
275
+ veal: "teletina",
276
+ pork: "svinjina",
277
+ lamb: "jagnjetina",
278
+ mutton: "jagnjetina",
279
+ sheep: "ovca",
280
+ goat: "koza",
281
+ horse: "konj",
282
+ buffalo: "bivol",
283
+ bison: "bizon",
284
+ venison: "divjačina",
285
+ boar: "divji prašič",
286
+ salmon: "losos",
287
+ trout: "postrv",
288
+ cod: "polenovka",
289
+ codfish: "polenovka",
290
+ hake: "oslič",
291
+ herring: "sled",
292
+ sardine: "sardela",
293
+ anchovy: "inčun",
294
+ mackerel: "skuša",
295
+ shrimp: "rakci",
296
+ prawn: "rakci",
297
+ krill: "kril",
298
+ crab: "rakovice",
299
+ lobster: "jastog",
300
+ squid: "lignji",
301
+ octopus: "hobotnica",
302
+ clam: "skoljke",
303
+ mussel: "skoljke",
304
+ egg: "jajce",
305
+ eggs: "jajce",
306
+ milk: "mleko",
307
+ cheese: "sir",
308
+ yogurt: "jogurt",
309
+ insect: "žuželke",
310
+ fish: "riba",
311
+ salmonoil: "ribje olje",
312
+ rice: "riž",
313
+ potato: "krompir",
314
+ potatoes: "krompir",
315
+ potatoe: "krompir",
316
+ grain: "žita",
317
+ grains: "žita",
318
+ wheat: "pšenica",
319
+ corn: "koruza",
320
+ maize: "koruza",
321
+ oat: "oves",
322
+ oats: "oves",
323
+ barley: "ječmen",
324
+ rye: "rž",
325
+ spelt: "pira",
326
+ spelled: "pira",
327
+ millet: "proso",
328
+ sorghum: "sirek",
329
+ quinoa: "kvinoja",
330
+ buckwheat: "ajda",
331
+ pea: "grah",
332
+ peas: "grah",
333
+ chickpea: "čiček",
334
+ lentil: "leča",
335
+ bean: "fižol",
336
+ beans: "fižol",
337
+ carrot: "korenje",
338
+ carrots: "korenje",
339
+ spinach: "špinača",
340
+ broccoli: "brokoli",
341
+ tomato: "paradižnik",
342
+ tomatoes: "paradižnik",
343
+ beet: "pesa",
344
+ beetroot: "pesa",
345
+ pumpkin: "buča",
346
+ courgette: "bučke",
347
+ zucchini: "bučke",
348
+ kale: "ohrovt",
349
+ cabbage: "zelje",
350
+ apple: "jabolko",
351
+ apples: "jabolko",
352
+ pomegranate: "granatno jabolko",
353
+ pomeg: "granatno jabolko",
354
+ orange: "pomaranča",
355
+ lemon: "limona",
356
+ pear: "hruška",
357
+ blueberry: "borovnica",
358
+ blueberries: "borovnica",
359
+ cranberry: "brusnica",
360
+ cranberries: "brusnica",
361
+ raspberry: "malina",
362
+ strawberry: "jagoda",
363
+ blackberry: "robida",
364
+ cherry: "češnja",
365
+ apricot: "marelica",
366
+ peach: "breskev",
367
+ pineapple: "ananas",
368
+ papaya: "papaja",
369
+ kiwi: "kivi",
370
+ melon: "melona",
371
+ melons: "melona",
372
+ watermelon: "lubenica",
373
+ cantaloupe: "melona",
374
+ coconut: "kokoš",
375
+ almond: "mandelj",
376
+ walnuts: "oreski",
377
+ peanut: "arašid",
378
+ seaweed: "alge",
379
+ kelp: "alge",
380
+ yucca: "juka",
381
+ alfalfa: "lucerna",
382
+ mint: "meta",
383
+ chamomile: "kamilica",
384
+ fennel: "komarček",
385
+ parsley: "peteršilj",
386
+ garlic: "česen",
387
+ flaxseed: "laneno seme",
388
+ flax: "lan",
389
+ sesame: "sezam",
390
+ sunflower: "sončnice",
391
+ herbal: "zeleni",
392
+ tablet: "tbl",
393
+ tablets: "tbl",
394
+ capsule: "kps",
395
+ capsules: "kps",
396
+ injection: "inj",
397
+ injections: "inj",
398
+ suspension: "suspenzija",
399
+ solution: "raztopina",
400
+ powder: "prašek",
401
+ granulate: "granulat",
402
+ granules: "granulat",
403
+ drops: "kapljice",
404
+ shampoo: "šampon",
405
+ conditioner: "balzam",
406
+ paste: "pasta",
407
+ pate: "pašteta",
408
+ syrup: "sirup",
409
+ spray: "sprej",
410
+ pipette: "pipeta",
411
+ ampoule: "ampula",
412
+ vial: "viala",
413
+ sachet: "vrecka",
414
+ pouch: "vrecka",
415
+ can: "konzerva",
416
+ cans: "konzerva",
417
+ tin: "konzerva",
418
+ bag: "vrecka",
419
+ tube: "tuba",
420
+ bottle: "steklenička",
421
+ jar: "kozarec",
422
+ collar: "ovratnica",
423
+ harness: "ovratnica",
424
+ leash: "povodec",
425
+ lead: "povodec",
426
+ muzzle: "nagobcnik",
427
+ toy: "igraca",
428
+ toys: "igraca",
429
+ brush: "krtača",
430
+ comb: "glavnik",
431
+ clipper: "škarje",
432
+ scissors: "škarje",
433
+ wipes: "brisače",
434
+ pads: "blazinice",
435
+ biscuit: "piškot",
436
+ biscuits: "piškot",
437
+ stick: "palčka",
438
+ sticks: "palčka",
439
+ bone: "kost",
440
+ jerky: "suseno",
441
+ chew: "žvečenje",
442
+ chewable: "žvečljiv",
443
+ jelly: "žele",
444
+ gravy: "omaka",
445
+ sauce: "omaka",
446
+ mousse: "pena",
447
+ loaf: "hlod",
448
+ cream: "krema",
449
+ oil: "olje",
450
+ balm: "balzam",
451
+ tonic: "tonik",
452
+ lotion: "losjon",
453
+ urinary: "urinarne",
454
+ renal: "ledvično",
455
+ kidney: "ledvica",
456
+ dental: "zobno",
457
+ hairball: "dlake",
458
+ joint: "sklepi",
459
+ joints: "sklepi",
460
+ skin: "koza",
461
+ coat: "dlaka",
462
+ stomach: "želodec",
463
+ gastric: "prebavno",
464
+ digestive: "prebavni",
465
+ digestion: "prebava",
466
+ intestinal: "črevesni",
467
+ hepatic: "jetrni",
468
+ liver: "jetra",
469
+ cardiac: "srčni",
470
+ heart: "srce",
471
+ respiratory: "dihala",
472
+ breath: "dihala",
473
+ ear: "ušesa",
474
+ eye: "oci",
475
+ eyes: "oci",
476
+ oral: "oralno",
477
+ hypoallergenic: "hipoalergen",
478
+ hypoall: "hipoalergen",
479
+ allergenic: "alergen",
480
+ allergy: "alergija",
481
+ sensitive: "občutljiv",
482
+ sterilised: "steriliziran",
483
+ sterilized: "steriliziran",
484
+ steril: "steriliziran",
485
+ neutered: "steriliziran",
486
+ neutred: "steriliziran",
487
+ neuter: "steriliziran",
488
+ castrated: "kastriran",
489
+ obesity: "debelost",
490
+ obese: "debel",
491
+ overweight: "predebel",
492
+ diabetic: "diabetik",
493
+ mobility: "mobilnost",
494
+ weight: "teža",
495
+ growth: "rast",
496
+ recovery: "okrevanje",
497
+ convalescence: "okrevanje",
498
+ calm: "pomiritev",
499
+ relaxing: "pomiritev",
500
+ vitality: "vitalnost",
501
+ immune: "imunski",
502
+ immunity: "imunost",
503
+ supplement: "dodatek",
504
+ supplements: "dodatek",
505
+ probiotic: "probiotik",
506
+ probiotics: "probiotik",
507
+ antioxidant: "antioksidant",
508
+ fibre: "vlaknine",
509
+ fiber: "vlaknine",
510
+ protein: "beljakovine",
511
+ fat: "maščobe",
512
+ ash: "pepel",
513
+ moisture: "vlaga",
514
+ veterinary: "veterinarski",
515
+ diet: "dieta",
516
+ dietary: "dietna",
517
+ adult: "odrasel",
518
+ wet: "mokra",
519
+ dry: "suha",
520
+ food: "hrana",
521
+ snack: "priboljsek",
522
+ snacks: "priboljsek",
523
+ treat: "priboljsek",
524
+ treats: "priboljsek",
525
+ complete: "popolna",
526
+ balanced: "uravnotežena",
527
+ daily: "dnevni",
528
+ special: "specialni",
529
+ intensive: "intenzivni",
530
+ support: "podpora",
531
+ protection: "zaščita",
532
+ control: "nadzor",
533
+ hygiene: "higiena",
534
+ fresh: "sveze",
535
+ grainfree: "brez zita",
536
+ bite: "grizljaj",
537
+ flavour: "okus",
538
+ flavor: "okus",
539
+ taste: "okus",
540
+ chickpomeg: "piscanec granatno jabolko",
541
+ chpom: "piscanec granatno jabolko",
542
+ cant: "melona",
543
+ cantmelon: "melona",
544
+ neut: "steriliziran",
545
+ vacc: "cepivo",
546
+ vaccin: "cepivo",
547
+ vaccine: "cepivo",
548
+ haem: "hem",
549
+ canine: "pasji",
550
+ feline: "mačji",
551
+ satiety: "sitost",
552
+ gastrointestinal: "prebavni",
553
+ pisc: "piščanec",
554
+ piscji: "piščanec",
555
+ krom: "krompir",
556
+ kromp: "krompir",
557
+ granat: "granatno",
558
+ ovck: "ovčka",
559
+ priboljski: "priboljšek"
560
+ };
561
+ var STOP_BESEDE = [
562
+ "and",
563
+ "with",
564
+ "for",
565
+ "the",
566
+ "of",
567
+ "in",
568
+ "on",
569
+ "to",
570
+ "from",
571
+ "per",
572
+ "care",
573
+ "health",
574
+ "healthy",
575
+ "premium",
576
+ "quality",
577
+ "test"
578
+ ];
579
+ var STAROSTI = {
580
+ mladic: "mladič",
581
+ mladicek: "mladič",
582
+ puppy: "mladič",
583
+ puppies: "mladič",
584
+ kitten: "mladič",
585
+ kittens: "mladič",
586
+ junior: "mladič",
587
+ juniors: "mladič",
588
+ baby: "mladič",
589
+ weaning: "mladič",
590
+ odrasel: "odrasel",
591
+ odrasli: "odrasel",
592
+ adult: "odrasel",
593
+ adults: "odrasel",
594
+ mature: "odrasel",
595
+ senior: "senior",
596
+ seniors: "senior",
597
+ seniorji: "senior",
598
+ geriatric: "senior",
599
+ aged: "senior"
600
+ };
601
+ var VELIKOSTI_EN = {
602
+ small: "s",
603
+ medium: "m",
604
+ large: "l",
605
+ giant: "xl",
606
+ xlarge: "xl",
607
+ extralarge: "xl"
608
+ };
609
+ var VELIKOSTI_OKRAJSAVE = {
610
+ med: "medium",
611
+ max: "maxi",
612
+ min: "mini"
613
+ };
614
+ var PREVODI_VIR = "ročno kurirano 2026-10-04 (besedišče izmerjeno v tackakp + SI_TACKA)";
615
+
243
616
  // src/vet/data/znamke.gen.ts
244
617
  var ZNAMKE_GEN = {
245
618
  vir: "/Users/primozk/devmt/panthenImport",
@@ -987,6 +1360,14 @@ function kljucBesede(beseda) {
987
1360
  return beseda.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]+$/, "");
988
1361
  }
989
1362
  var BESEDA = /(?<![\p{L}\p{N}])([\p{L}\p{N}]+)(?![\p{L}\p{N}])/gu;
1363
+ var BESEDA_Z_VEZNIKOM = /(?<![\p{L}\p{N}])([\p{L}]+)\s*[&+]\s*([\p{L}]+)(?![\p{L}\p{N}])/gu;
1364
+ var VELIKOSTNE_BESEDE = new Set([
1365
+ ...Object.keys(VELIKOSTI_OKRAJSAVE),
1366
+ ...Object.keys(VELIKOSTI_EN),
1367
+ "mini",
1368
+ "maxi",
1369
+ ...Object.keys(VELIKOSTI_SINONIMI)
1370
+ ]);
990
1371
  function kanonicaVelika(enota) {
991
1372
  return enota.toUpperCase();
992
1373
  }
@@ -1072,19 +1453,90 @@ var vrstaNormalizator = {
1072
1453
  return najdene.length ? { text: ocisceno, classes: { vrsta: najdene } } : ocisceno;
1073
1454
  }
1074
1455
  };
1075
- var TIPSKE_OZNAKE = new Set(ZNAMKE_GEN.tipskeOznake.map(kljucBesede).filter((t) => t.length >= 2));
1456
+ var TIPSKE_OZNAKE = new Set(ZNAMKE_GEN.tipskeOznake.map(kljucBesede).filter((t) => t.length >= 2 && !PREVODI[t]));
1457
+ var razdeljevalciNormalizator = {
1458
+ fn: (v) => {
1459
+ let spremenjeno = false;
1460
+ let besedilo = v.replace(BESEDA_Z_VEZNIKOM, (ujemanje, a, b) => {
1461
+ const ka = kljucBesede(a);
1462
+ const kb = kljucBesede(b);
1463
+ if (!VELIKOSTNE_BESEDE.has(ka) || !VELIKOSTNE_BESEDE.has(kb))
1464
+ return ujemanje;
1465
+ const razsiri = (k) => VELIKOSTI_OKRAJSAVE[k] ?? VELIKOSTI_EN[k] ?? k;
1466
+ spremenjeno = true;
1467
+ return `${razsiri(ka)} ${razsiri(kb)}`;
1468
+ });
1469
+ const zLocili = besedilo.replace(/\s*[&+,;|]\s*/g, " ").replace(/(?<=[\p{L}\p{N}]{2})\s*\/\s*(?=[\p{L}\p{N}]{2})/gu, " ").replace(/(?<![\d])([\p{L}]{2,})\.(?=\s|$)/gu, "$1").replace(/(?<=\p{L})\.(?=\p{L})/gu, " ");
1470
+ if (zLocili !== besedilo)
1471
+ spremenjeno = true;
1472
+ besedilo = zLocili;
1473
+ return spremenjeno ? besedilo.replace(/\s+/g, " ").trim() : undefined;
1474
+ }
1475
+ };
1476
+ var PREVODI_MAP = new Map(Object.entries(PREVODI));
1477
+ var STOP_MAP = new Set(STOP_BESEDE);
1478
+ var prevodiNormalizator = {
1479
+ fn: (v) => {
1480
+ let spremenjeno = false;
1481
+ const izhod = v.replace(BESEDA, (ujemanje) => {
1482
+ const kljuc = kljucBesede(ujemanje);
1483
+ if (STOP_MAP.has(kljuc)) {
1484
+ spremenjeno = true;
1485
+ return " ";
1486
+ }
1487
+ const prevod = PREVODI_MAP.get(kljuc);
1488
+ if (!prevod)
1489
+ return ujemanje;
1490
+ spremenjeno = true;
1491
+ return prevod.toUpperCase();
1492
+ });
1493
+ return spremenjeno ? izhod.replace(/\s+/g, " ").trim() : undefined;
1494
+ }
1495
+ };
1496
+ var starostNormalizator = {
1497
+ fn: (v) => {
1498
+ const najdene = [];
1499
+ const izhod = v.replace(BESEDA, (ujemanje) => {
1500
+ const starost = STAROSTI[kljucBesede(ujemanje)];
1501
+ if (!starost)
1502
+ return ujemanje;
1503
+ if (!najdene.includes(starost))
1504
+ najdene.push(starost);
1505
+ return " ";
1506
+ });
1507
+ if (!najdene.length)
1508
+ return;
1509
+ return { text: izhod.replace(/\s+/g, " ").trim(), classes: { starost: najdene } };
1510
+ }
1511
+ };
1076
1512
  var VRSTE_ZA_RAZRED = new Set(["pes", "macka"]);
1077
1513
  var OKRAJSAVE_ZNAMK = new Map;
1078
1514
  var LINIJE_ZNAMK = new Map;
1515
+ var ZNANE_ZNAMKE = new Map([["n&d", "NATURAL DELICIOUS"]]);
1516
+ var OBIČAJNE_BESEDE = new Set([
1517
+ ...Object.keys(PREVODI),
1518
+ ...STOP_BESEDE,
1519
+ ...Object.keys(STAROSTI),
1520
+ ...Object.keys(VELIKOSTI_EN),
1521
+ ...Object.keys(VELIKOSTI_SINONIMI),
1522
+ ...Object.keys(VRSTE_SINONIMI)
1523
+ ]);
1524
+ var BESEDE_ZNAMK = new Set(ZNAMKE_GEN.okrajsave.flatMap((o) => o.znamka.toLowerCase().split(/[^\p{L}\p{N}]+/u)).filter(Boolean));
1079
1525
  for (const zapis of ZNAMKE_GEN.okrajsave) {
1080
1526
  const kljuc = zapis.okrajsava.toLowerCase();
1081
1527
  if (zapis.zaupanje === "splet")
1082
1528
  continue;
1529
+ if (kljuc.length <= 4 && OBIČAJNE_BESEDE.has(kljuc))
1530
+ continue;
1531
+ if (BESEDE_ZNAMK.has(kljuc))
1532
+ continue;
1083
1533
  if (!OKRAJSAVE_ZNAMK.has(kljuc))
1084
1534
  OKRAJSAVE_ZNAMK.set(kljuc, zapis.znamka);
1085
1535
  }
1086
1536
  for (const linija of ZNAMKE_GEN.linije) {
1087
1537
  const kljuc = linija.linija.toLowerCase();
1538
+ if (OBIČAJNE_BESEDE.has(kljuc))
1539
+ continue;
1088
1540
  if (!LINIJE_ZNAMK.has(kljuc))
1089
1541
  LINIJE_ZNAMK.set(kljuc, linija.znamka);
1090
1542
  }
@@ -1093,7 +1545,7 @@ var znamkaNormalizator = {
1093
1545
  let spremenjeno = false;
1094
1546
  const izhod = v.replace(/(?<![\p{L}\p{N}])([\p{L}\p{N}&]+)(?![\p{L}\p{N}])/gu, (ujemanje) => {
1095
1547
  const kljuc = kljucBesede(ujemanje);
1096
- const znamka = OKRAJSAVE_ZNAMK.get(kljuc);
1548
+ const znamka = ZNANE_ZNAMKE.get(kljuc) ?? OKRAJSAVE_ZNAMK.get(kljuc);
1097
1549
  if (znamka) {
1098
1550
  const besedeCilja = znamka.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter(Boolean);
1099
1551
  if (besedeCilja.includes(kljuc))
@@ -1104,7 +1556,8 @@ var znamkaNormalizator = {
1104
1556
  const linija = LINIJE_ZNAMK.get(kljuc);
1105
1557
  if (linija) {
1106
1558
  spremenjeno = true;
1107
- return `${linija.toUpperCase()} ${ujemanje.toUpperCase()}`;
1559
+ const ze = v.toLowerCase().includes(linija.toLowerCase());
1560
+ return ze ? ujemanje.toUpperCase() : `${linija.toUpperCase()} ${ujemanje.toUpperCase()}`;
1108
1561
  }
1109
1562
  return ujemanje;
1110
1563
  });
@@ -1138,7 +1591,7 @@ var velikostNormalizator = {
1138
1591
  const najdene = [];
1139
1592
  const izhod = v.replace(BESEDA, (ujemanje, ...args) => {
1140
1593
  const kljuc = kljucBesede(ujemanje);
1141
- const velikost = VELIKOSTI_SINONIMI[kljuc];
1594
+ const velikost = VELIKOSTI_SINONIMI[kljuc] ?? VELIKOSTI_EN[kljuc];
1142
1595
  if (!velikost)
1143
1596
  return ujemanje;
1144
1597
  const mesto = args[args.length - 2];
@@ -1192,11 +1645,14 @@ var VET_NORMALIZATORJI = [
1192
1645
  kodiranjeNormalizator,
1193
1646
  decimalkeNormalizator,
1194
1647
  pantheonOznakaNormalizator,
1195
- tipskeOznakeNormalizator,
1196
1648
  enoteNormalizator,
1197
1649
  znamkaNormalizator,
1650
+ razdeljevalciNormalizator,
1651
+ prevodiNormalizator,
1652
+ tipskeOznakeNormalizator,
1198
1653
  kolicinaNormalizator,
1199
1654
  velikostNormalizator,
1655
+ starostNormalizator,
1200
1656
  vrstaNormalizator,
1201
1657
  oznakeNormalizator
1202
1658
  ];
@@ -1205,6 +1661,10 @@ var VET_TABELA = {
1205
1661
  linije: LINIJE_ZNAMK,
1206
1662
  dobavitelji: DOBAVITELJI,
1207
1663
  oznake: OZNAKE,
1664
+ prevodi: PREVODI_MAP,
1665
+ stopBesede: STOP_MAP,
1666
+ starosti: STAROSTI,
1667
+ velikostiEn: VELIKOSTI_EN,
1208
1668
  vir: ZNAMKE_GEN.vir
1209
1669
  };
1210
1670
  // src/vet/spec.ts
@@ -2006,14 +2466,17 @@ var KAZEN = {
2006
2466
  kolicina: 150,
2007
2467
  pakiranje: 150,
2008
2468
  velikost: 300,
2009
- pantheon: 100
2469
+ pantheon: 100,
2470
+ starost: 400
2010
2471
  };
2472
+ var VETO_RAZREDI = new Set(["vrsta"]);
2011
2473
  var BONUS = {
2012
2474
  razpon: 150,
2013
2475
  vrsta: 200,
2014
2476
  kolicina: 100,
2015
2477
  pakiranje: 100,
2016
- velikost: 150
2478
+ velikost: 150,
2479
+ starost: 200
2017
2480
  };
2018
2481
  function kotSeznam(v) {
2019
2482
  if (v === undefined)
@@ -2025,6 +2488,32 @@ function staVNasprotju(a, b) {
2025
2488
  return false;
2026
2489
  return !a.some((x) => b.includes(x));
2027
2490
  }
2491
+ var NORMALIZIRANO = new Map;
2492
+ function normalizirajNaziv(naziv) {
2493
+ const shranjeno = NORMALIZIRANO.get(naziv);
2494
+ if (shranjeno)
2495
+ return shranjeno;
2496
+ let text = naziv;
2497
+ const classes = {};
2498
+ for (const n of VET_NORMALIZATORJI) {
2499
+ const r = n.fn(text, "naziv");
2500
+ if (r === undefined)
2501
+ continue;
2502
+ if (typeof r === "string") {
2503
+ text = r;
2504
+ continue;
2505
+ }
2506
+ text = r.text;
2507
+ for (const [kljuc, vrednost] of Object.entries(r.classes ?? {})) {
2508
+ classes[kljuc] = Array.isArray(vrednost) ? vrednost.map(String) : [String(vrednost)];
2509
+ }
2510
+ }
2511
+ const rezultat = { text: text.replace(/\s+/g, " ").trim(), classes };
2512
+ if (NORMALIZIRANO.size > 60000)
2513
+ NORMALIZIRANO.clear();
2514
+ NORMALIZIRANO.set(naziv, rezultat);
2515
+ return rezultat;
2516
+ }
2028
2517
  function kljuc(beseda) {
2029
2518
  return beseda.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9]/g, "");
2030
2519
  }
@@ -2054,8 +2543,16 @@ function prestaneVratar(besedePoizvedbe, besedeKandidata) {
2054
2543
  }
2055
2544
  function oceniPar(poizvedba, kandidat, nastavitve = {}, razredi) {
2056
2545
  const n = { ...PRIVZETO, ...nastavitve };
2057
- const q = import_cry_vetzdravila.razcleniNaziv(poizvedba);
2058
- const c = import_cry_vetzdravila.razcleniNaziv(kandidat);
2546
+ const qNorm = normalizirajNaziv(poizvedba);
2547
+ const cNorm = normalizirajNaziv(kandidat);
2548
+ const q = import_cry_vetzdravila.razcleniNaziv(qNorm.text);
2549
+ const c = import_cry_vetzdravila.razcleniNaziv(cNorm.text);
2550
+ const qSurov = import_cry_vetzdravila.razcleniNaziv(poizvedba);
2551
+ const cSurov = import_cry_vetzdravila.razcleniNaziv(kandidat);
2552
+ const razrediSkupni = {
2553
+ poizvedba: { ...qNorm.classes, ...razredi?.poizvedba ?? {} },
2554
+ kandidat: { ...cNorm.classes, ...razredi?.kandidat ?? {} }
2555
+ };
2059
2556
  const prazna = {
2060
2557
  ocena: 0,
2061
2558
  sprejeto: false,
@@ -2067,52 +2564,85 @@ function oceniPar(poizvedba, kandidat, nastavitve = {}, razredi) {
2067
2564
  };
2068
2565
  if (!prestaneVratar(q.besede, c.besede))
2069
2566
  return prazna;
2070
- const qTok = [...new Set([...q.besede, ...q.zivalskeVrste, ...q.dozirneOblike].map((t) => t.toLowerCase()))];
2071
- const cTok = [...new Set([...c.besede, ...c.zivalskeVrste, ...c.dozirneOblike].map((t) => t.toLowerCase()))];
2072
- const qStevci = new Map;
2073
- for (const t of qTok)
2074
- qStevci.set(t, (qStevci.get(t) ?? 0) + 1);
2075
- const cStevci = new Map;
2076
- for (const t of cTok)
2077
- cStevci.set(t, (cStevci.get(t) ?? 0) + 1);
2078
- const porabljeno = new Map;
2079
- let ujemajoce = 0;
2080
- let ujemajoceCele = 0;
2081
- const skupne = [];
2082
- for (const [qZeton, kolikoQ] of qStevci) {
2083
- let potrebnih = kolikoQ;
2084
- for (const [cZeton, kolikoC] of cStevci) {
2085
- if (potrebnih === 0)
2086
- break;
2087
- const prostih = kolikoC - (porabljeno.get(cZeton) ?? 0);
2088
- if (prostih <= 0)
2089
- continue;
2090
- const cela = qZeton === cZeton;
2091
- const predpona = !cela && (cZeton.startsWith(qZeton) || qZeton.startsWith(cZeton));
2092
- const razmerje = Math.min(qZeton.length, cZeton.length) / Math.max(qZeton.length, cZeton.length);
2093
- if (!cela && !(predpona && razmerje >= n.predponaDelez))
2094
- continue;
2095
- const vzem = Math.min(potrebnih, prostih);
2096
- porabljeno.set(cZeton, (porabljeno.get(cZeton) ?? 0) + vzem);
2097
- ujemajoce += vzem;
2098
- if (cela)
2099
- ujemajoceCele += vzem;
2100
- if (!skupne.includes(qZeton))
2101
- skupne.push(qZeton);
2102
- potrebnih -= vzem;
2567
+ const vrednostiRazredov = (m) => Object.values(m).flat().map((v) => String(v).toLowerCase()).filter((v) => v.length > 0);
2568
+ const qSurovTok = [
2569
+ ...new Set([
2570
+ ...[...qSurov.besede, ...qSurov.zivalskeVrste, ...qSurov.dozirneOblike].map((t) => t.toLowerCase()),
2571
+ ...vrednostiRazredov(razrediSkupni["poizvedba"] ?? {})
2572
+ ])
2573
+ ];
2574
+ const cSurovTok = [
2575
+ ...new Set([
2576
+ ...[...cSurov.besede, ...cSurov.zivalskeVrste, ...cSurov.dozirneOblike].map((t) => t.toLowerCase()),
2577
+ ...vrednostiRazredov(razrediSkupni["kandidat"] ?? {})
2578
+ ])
2579
+ ];
2580
+ const qTok = [
2581
+ ...new Set([
2582
+ ...[...q.besede, ...q.zivalskeVrste, ...q.dozirneOblike].map((t) => t.toLowerCase()),
2583
+ ...vrednostiRazredov(razrediSkupni["poizvedba"] ?? {})
2584
+ ])
2585
+ ];
2586
+ const cTok = [
2587
+ ...new Set([
2588
+ ...[...c.besede, ...c.zivalskeVrste, ...c.dozirneOblike].map((t) => t.toLowerCase()),
2589
+ ...vrednostiRazredov(razrediSkupni["kandidat"] ?? {})
2590
+ ])
2591
+ ];
2592
+ const izracunajPokritost = (qZetoni, cZetoni) => {
2593
+ const qStevci = new Map;
2594
+ for (const t of qZetoni)
2595
+ qStevci.set(t, (qStevci.get(t) ?? 0) + 1);
2596
+ const cStevci = new Map;
2597
+ for (const t of cZetoni)
2598
+ cStevci.set(t, (cStevci.get(t) ?? 0) + 1);
2599
+ const porabljeno = new Map;
2600
+ let ujemajoce = 0;
2601
+ let ujemajoceCele = 0;
2602
+ const skupne2 = [];
2603
+ for (const [qZeton, kolikoQ] of qStevci) {
2604
+ let potrebnih = kolikoQ;
2605
+ for (const [cZeton, kolikoC] of cStevci) {
2606
+ if (potrebnih === 0)
2607
+ break;
2608
+ const prostih = kolikoC - (porabljeno.get(cZeton) ?? 0);
2609
+ if (prostih <= 0)
2610
+ continue;
2611
+ const qKljuc = kljuc(qZeton);
2612
+ const cKljuc = kljuc(cZeton);
2613
+ const cela = qKljuc === cKljuc;
2614
+ const predpona = !cela && (cKljuc.startsWith(qKljuc) || qKljuc.startsWith(cKljuc));
2615
+ const razmerje = Math.min(qKljuc.length, cKljuc.length) / Math.max(qKljuc.length, cKljuc.length);
2616
+ if (!cela && !(predpona && razmerje >= n.predponaDelez))
2617
+ continue;
2618
+ const vzem = Math.min(potrebnih, prostih);
2619
+ porabljeno.set(cZeton, (porabljeno.get(cZeton) ?? 0) + vzem);
2620
+ ujemajoce += vzem;
2621
+ if (cela)
2622
+ ujemajoceCele += vzem;
2623
+ if (!skupne2.includes(qZeton))
2624
+ skupne2.push(qZeton);
2625
+ potrebnih -= vzem;
2626
+ }
2103
2627
  }
2104
- }
2105
- const pokritostKandidata = cTok.length ? ujemajoce / cTok.length : 0;
2106
- const pokritostPoizvedbe = qTok.length ? ujemajoce / qTok.length : 0;
2107
- const dovoljDolg = [...porabljeno.keys()].some((t) => t.length >= 5);
2108
- const popolno = pokritostKandidata === 1 && pokritostPoizvedbe === 1;
2109
- const pokritostOk = ujemajoce >= 1 && pokritostKandidata >= n.pokritostKandidata && pokritostPoizvedbe >= n.pokritostPoizvedbe && (popolno || ujemajoceCele >= 2 || dovoljDolg);
2110
- let ocena = import_cry_vetzdravila.oceniPodobnost(q, c).ocena;
2628
+ const pokritostKandidata2 = cZetoni.length ? ujemajoce / cZetoni.length : 0;
2629
+ const pokritostPoizvedbe2 = qZetoni.length ? ujemajoce / qZetoni.length : 0;
2630
+ const dovoljDolg = [...porabljeno.keys()].some((t) => kljuc(t).length >= 5);
2631
+ const popolno = pokritostKandidata2 === 1 && pokritostPoizvedbe2 === 1;
2632
+ const ok = ujemajoce >= 1 && pokritostKandidata2 >= n.pokritostKandidata && pokritostPoizvedbe2 >= n.pokritostPoizvedbe && (popolno || ujemajoceCele >= 2 || dovoljDolg);
2633
+ return { ok, pokritostKandidata: pokritostKandidata2, pokritostPoizvedbe: pokritostPoizvedbe2, skupne: skupne2, nasprotja: [] };
2634
+ };
2635
+ const kanonicno = izracunajPokritost(qTok, cTok);
2636
+ const surovo = izracunajPokritost(qSurovTok, cSurovTok);
2637
+ const izbrano = kanonicno.ok || kanonicno.pokritostKandidata >= surovo.pokritostKandidata ? kanonicno : surovo;
2638
+ const { pokritostKandidata, pokritostPoizvedbe, skupne } = izbrano;
2639
+ const pokritostOk = kanonicno.ok || surovo.ok;
2640
+ let ocena = Math.max(import_cry_vetzdravila.oceniPodobnost(q, c).ocena, import_cry_vetzdravila.oceniPodobnost(qSurov, cSurov).ocena);
2111
2641
  const nasprotja = [];
2112
- const kljuci = ["razpon", "vrsta", "kolicina", "pakiranje", "velikost", "pantheon"];
2642
+ const kljuci = ["razpon", "vrsta", "kolicina", "pakiranje", "velikost", "starost", "pantheon"];
2113
2643
  for (const kljuc2 of kljuci) {
2114
- const a = kotSeznam(razredi?.poizvedba?.[kljuc2]);
2115
- const b = kotSeznam(razredi?.kandidat?.[kljuc2]);
2644
+ const a = kotSeznam(razrediSkupni["poizvedba"]?.[kljuc2]);
2645
+ const b = kotSeznam(razrediSkupni["kandidat"]?.[kljuc2]);
2116
2646
  if (staVNasprotju(a, b)) {
2117
2647
  ocena -= KAZEN[kljuc2] ?? 0;
2118
2648
  nasprotja.push(`${kljuc2}: ${a.join("/")} ≠ ${b.join("/")}`);
@@ -2120,8 +2650,9 @@ function oceniPar(poizvedba, kandidat, nastavitve = {}, razredi) {
2120
2650
  ocena += BONUS[kljuc2] ?? 0;
2121
2651
  }
2122
2652
  }
2123
- const sprejeto = pokritostOk && ocena >= n.minOcena;
2124
- const razlog = sprejeto ? `pokritost kandidata ${Math.round(pokritostKandidata * 100)} %, poizvedbe ${Math.round(pokritostPoizvedbe * 100)} %` + (skupne.length ? `; skupne besede: ${skupne.slice(0, 5).join(", ")}` : "") + (nasprotja.length ? `; nasprotja: ${nasprotja.join("; ")}` : "") : `pokritost prenizka (kandidat ${Math.round(pokritostKandidata * 100)} %, poizvedba ${Math.round(pokritostPoizvedbe * 100)} %)`;
2653
+ const veto = nasprotja.some((n2) => VETO_RAZREDI.has(n2.split(":")[0] ?? ""));
2654
+ const sprejeto = pokritostOk && !veto && ocena >= n.minOcena;
2655
+ const razlog = sprejeto ? `pokritost kandidata ${Math.round(pokritostKandidata * 100)} %, poizvedbe ${Math.round(pokritostPoizvedbe * 100)} %` + (skupne.length ? `; skupne besede: ${skupne.slice(0, 5).join(", ")}` : "") + (nasprotja.length ? `; nasprotja: ${nasprotja.join("; ")}` : "") : veto ? `nasprotje v razredu (${nasprotja.join("; ")})` : `pokritost prenizka (kandidat ${Math.round(pokritostKandidata * 100)} %, poizvedba ${Math.round(pokritostPoizvedbe * 100)} %)`;
2125
2656
  return { ocena, sprejeto, razlog, pokritostKandidata, pokritostPoizvedbe, skupneBesede: skupne.slice(0, 5), nasprotja };
2126
2657
  }
2127
2658
  // src/common/numeric/scoring.ts