@whiteslove/parsing-lexicon 0.2.0 → 0.2.2
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/LICENSE +21 -21
- package/README.md +137 -137
- package/index.d.ts +374 -374
- package/package.json +77 -75
- package/src/central-asia-locations.js +211 -211
- package/src/central-asia.js +233 -233
- package/src/contact.d.ts +44 -44
- package/src/contact.js +159 -159
- package/src/countries.js +175 -175
- package/src/country-context.d.ts +10 -10
- package/src/country-context.js +22 -22
- package/src/currency.d.ts +14 -14
- package/src/currency.js +66 -66
- package/src/geo.js +169 -169
- package/src/geography-central-asia.js +42 -42
- package/src/geography-detection.d.ts +14 -14
- package/src/geography-detection.js +64 -64
- package/src/geography-display.d.ts +13 -13
- package/src/geography-display.js +113 -113
- package/src/geography.js +210 -210
- package/src/hiring-advanced.js +147 -147
- package/src/hiring-candidate-fields.d.ts +9 -9
- package/src/hiring-candidate-fields.js +92 -92
- package/src/hiring-context.d.ts +64 -64
- package/src/hiring-context.js +412 -412
- package/src/hiring-language-extensions.d.ts +19 -19
- package/src/hiring-language-extensions.js +139 -139
- package/src/hiring-languages.js +135 -135
- package/src/hiring-location-fields.d.ts +3 -3
- package/src/hiring-location-fields.js +53 -53
- package/src/hiring-professions-ro.js +191 -191
- package/src/hiring-professions.js +437 -437
- package/src/hiring-requirements.d.ts +16 -16
- package/src/hiring-requirements.js +170 -170
- package/src/hiring-salary-context.d.ts +27 -27
- package/src/hiring-salary-context.js +76 -76
- package/src/hiring-semantics.d.ts +29 -29
- package/src/hiring-semantics.js +218 -218
- package/src/hiring-skills.d.ts +21 -21
- package/src/hiring-skills.js +315 -315
- package/src/hiring-source-aliases.d.ts +32 -32
- package/src/hiring-source-aliases.js +185 -185
- package/src/hiring-source-semantics.d.ts +31 -31
- package/src/hiring-source-semantics.js +293 -293
- package/src/hiring-temporal.d.ts +15 -15
- package/src/hiring-temporal.js +67 -67
- package/src/hiring-vacancy-fields.d.ts +5 -5
- package/src/hiring-vacancy-fields.js +23 -23
- package/src/hiring-work-semantics.d.ts +34 -34
- package/src/hiring-work-semantics.js +72 -72
- package/src/hiring.js +180 -180
- package/src/housing-address.d.ts +18 -18
- package/src/housing-address.js +217 -210
- package/src/housing-commercial.d.ts +1 -0
- package/src/housing-commercial.js +9 -0
- package/src/housing-context.d.ts +36 -36
- package/src/housing-context.js +183 -183
- package/src/housing-features.js +30 -30
- package/src/housing-intent.d.ts +9 -9
- package/src/housing-intent.js +132 -132
- package/src/housing-listing-fields.js +131 -131
- package/src/housing-money.d.ts +7 -7
- package/src/housing-money.js +102 -102
- package/src/housing-source-aliases.d.ts +8 -8
- package/src/housing-source-aliases.js +51 -51
- package/src/housing-structured.d.ts +55 -55
- package/src/housing-structured.js +219 -219
- package/src/housing.js +200 -200
- package/src/index.js +45 -44
- package/src/kz-location-extensions.js +307 -307
- package/src/landmarks.js +21 -21
- package/src/lexicon-core.js +58 -58
- package/src/location-merge.js +106 -106
- package/src/locations.js +456 -456
- package/src/money-core.d.ts +10 -10
- package/src/money-core.js +81 -81
- package/src/money-lexicon.d.ts +5 -5
- package/src/money-lexicon.js +79 -79
- package/src/money.js +154 -154
- package/src/normalization.js +384 -384
- package/src/odesa-metropolitan.js +144 -144
- package/src/romania-geography.js +47 -47
- package/src/tashkent-colloquial.js +80 -72
- package/src/tashkent-housing-geography.d.ts +38 -38
- package/src/tashkent-housing-geography.js +211 -211
- package/src/tashkent-pois.js +215 -215
- package/src/tashkent-residential-complexes.js +272 -272
- package/src/ua-location-extensions-major.js +118 -118
- package/src/ua-location-extensions-metro.js +9 -9
- package/src/ua-location-extensions-regional.js +246 -246
- package/src/ua-secondary-cities.d.ts +2 -2
- package/src/ua-secondary-cities.js +57 -57
- package/src/ukraine.js +75 -75
- package/src/uz-location-extensions.js +259 -259
package/src/housing-intent.js
CHANGED
|
@@ -1,132 +1,132 @@
|
|
|
1
|
-
import { findCanonical } from './normalization.js';
|
|
2
|
-
import { lexiconEntity } from './lexicon-core.js';
|
|
3
|
-
|
|
4
|
-
const group = (canonical, aliases, extra = {}) => lexiconEntity(canonical, aliases, extra);
|
|
5
|
-
const KK_RENT_OUT_ALIASES = Object.freeze(['жалға беремін', 'жалға беріледі']);
|
|
6
|
-
const RO_SALE_OFFER_ALIASES = Object.freeze(['de vânzare', 'de vanzare']);
|
|
7
|
-
|
|
8
|
-
export const HOUSING_ACTIONS = Object.freeze([
|
|
9
|
-
group('sell', {
|
|
10
|
-
ru: ['продам', 'продаю', 'продаётся', 'продается', 'выставил на продажу', 'выставила на продажу'],
|
|
11
|
-
en: ['selling', 'for sale', 'selling apartment', 'selling house'],
|
|
12
|
-
uk: ['продам', 'продаю', 'продається'],
|
|
13
|
-
ro: ['vând', 'vand', ...RO_SALE_OFFER_ALIASES, 'se vinde'],
|
|
14
|
-
uzLatn: ['sotaman', 'sotiladi', 'sotuvga qoyildi', "sotuvga qo'yildi"],
|
|
15
|
-
uzCyrl: ['сотаман', 'сотилади', 'сотувга қўйилди'],
|
|
16
|
-
kk: ['сатамын', 'сатылады', 'сатылымға қойылды'],
|
|
17
|
-
}),
|
|
18
|
-
group('buy', {
|
|
19
|
-
ru: ['куплю', 'хочу купить', 'ищу купить', 'ищу для покупки', 'нужна квартира для покупки'],
|
|
20
|
-
en: ['want to buy', 'looking to buy', 'looking for a property to buy', 'need an apartment to buy'],
|
|
21
|
-
uk: ['куплю', 'хочу купити', 'шукаю купити', 'шукаю для купівлі'],
|
|
22
|
-
ro: ['vreau să cumpăr', 'vreau sa cumpar', 'caut să cumpăr', 'caut sa cumpar'],
|
|
23
|
-
uzLatn: ['sotib olaman', 'sotib olish uchun qidiryapman', 'sotib olishga uy qidiryapman'],
|
|
24
|
-
uzCyrl: ['сотиб оламан', 'сотиб олиш учун қидиряпман', 'сотиб олишга уй қидиряпман'],
|
|
25
|
-
kk: ['сатып аламын', 'сатып алуға іздеймін', 'сатып алуға пәтер іздеймін'],
|
|
26
|
-
}),
|
|
27
|
-
group('rentOut', {
|
|
28
|
-
ru: ['сдам', 'сдаю', 'сдаётся', 'сдается', 'сдаётся в аренду', 'сдается в аренду'],
|
|
29
|
-
en: ['for rent', 'renting out', 'available for rent', 'letting'],
|
|
30
|
-
uk: ['здам', 'здаю', 'здається', 'здається в оренду'],
|
|
31
|
-
ro: ['închiriez', 'inchiriez', 'de închiriat', 'de inchiriat', 'se închiriază', 'se inchiriaza'],
|
|
32
|
-
uzLatn: ['ijaraga beraman', 'ijaraga beriladi', 'ijaraga topshiraman'],
|
|
33
|
-
uzCyrl: ['ижарага бераман', 'ижарага берилади', 'ижарага топшираман'],
|
|
34
|
-
kk: KK_RENT_OUT_ALIASES,
|
|
35
|
-
}),
|
|
36
|
-
group('rentIn', {
|
|
37
|
-
ru: ['сниму', 'хочу снять', 'ищу снять', 'ищу квартиру', 'ищу жильё', 'ищу жилье', 'нужна квартира', 'нужно жильё', 'нужно жилье'],
|
|
38
|
-
en: ['looking to rent', 'want to rent', 'need an apartment', 'looking for an apartment', 'looking for housing'],
|
|
39
|
-
uk: ['зніму', 'хочу зняти', 'шукаю квартиру', 'шукаю житло', 'потрібна квартира'],
|
|
40
|
-
ro: ['vreau să închiriez', 'vreau sa inchiriez', 'caut să închiriez', 'caut sa inchiriez', 'caut apartament'],
|
|
41
|
-
uzLatn: ['ijaraga olaman', 'uy qidiryapman', 'kvartira qidiryapman', 'ijara uchun uy qidiryapman'],
|
|
42
|
-
uzCyrl: ['ижарага оламан', 'уй қидиряпман', 'квартира қидиряпман', 'ижара учун уй қидиряпман'],
|
|
43
|
-
kk: ['жалға аламын', 'пәтер іздеймін', 'үй іздеймін', 'жалға пәтер іздеймін'],
|
|
44
|
-
}),
|
|
45
|
-
]);
|
|
46
|
-
|
|
47
|
-
export const HOUSING_INTENT = Object.freeze([
|
|
48
|
-
group('offer', {
|
|
49
|
-
ru: ['продам', 'продаю', 'продаётся', 'продается', 'сдам', 'сдаю', 'сдаётся', 'сдается'],
|
|
50
|
-
en: ['for sale', 'selling', 'for rent', 'renting out'],
|
|
51
|
-
uk: ['продам', 'продаю', 'продається', 'здам', 'здаю', 'здається'],
|
|
52
|
-
ro: ['vând', 'vand', 'de vânzare', 'de vanzare', 'închiriez', 'inchiriez', 'de închiriat', 'de inchiriat'],
|
|
53
|
-
uzLatn: ['sotaman', 'sotiladi', 'ijaraga beraman', 'ijaraga beriladi'],
|
|
54
|
-
uzCyrl: ['сотаман', 'сотилади', 'ижарага бераман', 'ижарага берилади'],
|
|
55
|
-
kk: ['сатамын', 'сатылады', 'жалға беремін', 'жалға беріледі'],
|
|
56
|
-
}),
|
|
57
|
-
group('wanted', {
|
|
58
|
-
ru: ['куплю', 'ищу купить', 'сниму', 'ищу квартиру', 'ищу жильё', 'ищу жилье', 'нужна квартира'],
|
|
59
|
-
en: ['looking to buy', 'want to buy', 'looking to rent', 'need an apartment'],
|
|
60
|
-
uk: ['куплю', 'шукаю купити', 'зніму', 'шукаю квартиру', 'шукаю житло'],
|
|
61
|
-
ro: ['vreau să cumpăr', 'vreau sa cumpar', 'vreau să închiriez', 'vreau sa inchiriez', 'caut apartament'],
|
|
62
|
-
uzLatn: ['sotib olaman', 'sotib olish uchun qidiryapman', 'ijaraga olaman', 'uy qidiryapman'],
|
|
63
|
-
uzCyrl: ['сотиб оламан', 'сотиб олиш учун қидиряпман', 'ижарага оламан', 'уй қидиряпман'],
|
|
64
|
-
kk: ['сатып аламын', 'сатып алуға іздеймін', 'жалға аламын', 'пәтер іздеймін'],
|
|
65
|
-
}),
|
|
66
|
-
]);
|
|
67
|
-
|
|
68
|
-
// Deal type is transaction mechanics only. Direction is resolved by HOUSING_ACTIONS.
|
|
69
|
-
export const HOUSING_DEAL_TYPES = Object.freeze([
|
|
70
|
-
group('sale', {
|
|
71
|
-
ru: ['продажа', 'продать', 'покупка'],
|
|
72
|
-
en: ['sale', 'purchase'],
|
|
73
|
-
uk: ['продаж', 'продати', 'купівля'],
|
|
74
|
-
ro: ['vânzare', 'vanzare', ...RO_SALE_OFFER_ALIASES, 'cumpărare', 'cumparare'],
|
|
75
|
-
uzLatn: ['sotish', 'sotuv', 'sotib olish'],
|
|
76
|
-
uzCyrl: ['сотиш', 'сотув', 'сотиб олиш'],
|
|
77
|
-
kk: ['сату', 'сатып алу', 'сатылым'],
|
|
78
|
-
}),
|
|
79
|
-
group('longRent', {
|
|
80
|
-
ru: ['аренда', 'долгосрочно', 'долгосрочная аренда', 'помесячно', 'на длительный срок'],
|
|
81
|
-
en: ['rent', 'long term rent', 'long-term rent', 'monthly rent'],
|
|
82
|
-
uk: ['оренда', 'довгостроково', 'довгострокова оренда', 'помісячно'],
|
|
83
|
-
ro: ['închiriere', 'inchiriere', 'chirie', 'pe termen lung', 'lunar'],
|
|
84
|
-
uzLatn: ['ijara', 'uzoq muddatga', 'oylik ijara'],
|
|
85
|
-
uzCyrl: ['ижара', 'узоқ муддатга', 'ойлик ижара'],
|
|
86
|
-
kk: ['жалдау', 'жалға', ...KK_RENT_OUT_ALIASES, 'ұзақ мерзімге', 'айлық жалдау'],
|
|
87
|
-
}),
|
|
88
|
-
group('shortRent', {
|
|
89
|
-
ru: ['посуточно', 'посуточная аренда', 'на сутки', 'на час', 'почасово', 'краткосрочно'],
|
|
90
|
-
en: ['daily rent', 'short term', 'short-term rent', 'per day', 'hourly'],
|
|
91
|
-
uk: ['подобово', 'погодинно', 'на добу', 'на годину', 'короткострокова оренда'],
|
|
92
|
-
ro: ['regim hotelier', 'pe zi', 'zilnic', 'pe noapte', 'închiriere pe termen scurt', 'inchiriere pe termen scurt'],
|
|
93
|
-
uzLatn: ['kunlik', 'sutkaga', 'sutkalik', 'soatlik', 'kuniga'],
|
|
94
|
-
uzCyrl: ['кунлик', 'суткага', 'суткалик', 'соатлик', 'кунига'],
|
|
95
|
-
kk: ['тәулік', 'тәуліктік', 'тәулігіне', 'сағаттық', 'күндік'],
|
|
96
|
-
}),
|
|
97
|
-
]);
|
|
98
|
-
|
|
99
|
-
export const HOUSING_ACTION_MAP = Object.freeze({
|
|
100
|
-
sell: Object.freeze({ listingKind: 'propertyOffer', dealType: 'sale' }),
|
|
101
|
-
buy: Object.freeze({ listingKind: 'propertyWanted', dealType: 'sale' }),
|
|
102
|
-
rentOut: Object.freeze({ listingKind: 'propertyOffer', dealType: 'longRent' }),
|
|
103
|
-
rentIn: Object.freeze({ listingKind: 'propertyWanted', dealType: 'longRent' }),
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
export function resolveHousingIntent(value) {
|
|
107
|
-
const text = String(value || '');
|
|
108
|
-
if (!text.trim()) return null;
|
|
109
|
-
|
|
110
|
-
const action = findCanonical(text, HOUSING_ACTIONS, { partial: true });
|
|
111
|
-
const durationDeal = findCanonical(text, HOUSING_DEAL_TYPES, { partial: true });
|
|
112
|
-
|
|
113
|
-
if (action) {
|
|
114
|
-
const base = HOUSING_ACTION_MAP[action.canonical];
|
|
115
|
-
let dealType = base.dealType;
|
|
116
|
-
if (durationDeal?.canonical === 'shortRent' && (action.canonical === 'rentOut' || action.canonical === 'rentIn')) {
|
|
117
|
-
dealType = 'shortRent';
|
|
118
|
-
}
|
|
119
|
-
return Object.freeze({
|
|
120
|
-
action: action.canonical,
|
|
121
|
-
listingKind: base.listingKind,
|
|
122
|
-
dealType,
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (!durationDeal) return null;
|
|
127
|
-
return Object.freeze({
|
|
128
|
-
action: null,
|
|
129
|
-
listingKind: null,
|
|
130
|
-
dealType: durationDeal.canonical,
|
|
131
|
-
});
|
|
132
|
-
}
|
|
1
|
+
import { findCanonical } from './normalization.js';
|
|
2
|
+
import { lexiconEntity } from './lexicon-core.js';
|
|
3
|
+
|
|
4
|
+
const group = (canonical, aliases, extra = {}) => lexiconEntity(canonical, aliases, extra);
|
|
5
|
+
const KK_RENT_OUT_ALIASES = Object.freeze(['жалға беремін', 'жалға беріледі']);
|
|
6
|
+
const RO_SALE_OFFER_ALIASES = Object.freeze(['de vânzare', 'de vanzare']);
|
|
7
|
+
|
|
8
|
+
export const HOUSING_ACTIONS = Object.freeze([
|
|
9
|
+
group('sell', {
|
|
10
|
+
ru: ['продам', 'продаю', 'продаётся', 'продается', 'выставил на продажу', 'выставила на продажу'],
|
|
11
|
+
en: ['selling', 'for sale', 'selling apartment', 'selling house'],
|
|
12
|
+
uk: ['продам', 'продаю', 'продається'],
|
|
13
|
+
ro: ['vând', 'vand', ...RO_SALE_OFFER_ALIASES, 'se vinde'],
|
|
14
|
+
uzLatn: ['sotaman', 'sotiladi', 'sotuvga qoyildi', "sotuvga qo'yildi"],
|
|
15
|
+
uzCyrl: ['сотаман', 'сотилади', 'сотувга қўйилди'],
|
|
16
|
+
kk: ['сатамын', 'сатылады', 'сатылымға қойылды'],
|
|
17
|
+
}),
|
|
18
|
+
group('buy', {
|
|
19
|
+
ru: ['куплю', 'хочу купить', 'ищу купить', 'ищу для покупки', 'нужна квартира для покупки'],
|
|
20
|
+
en: ['want to buy', 'looking to buy', 'looking for a property to buy', 'need an apartment to buy'],
|
|
21
|
+
uk: ['куплю', 'хочу купити', 'шукаю купити', 'шукаю для купівлі'],
|
|
22
|
+
ro: ['vreau să cumpăr', 'vreau sa cumpar', 'caut să cumpăr', 'caut sa cumpar'],
|
|
23
|
+
uzLatn: ['sotib olaman', 'sotib olish uchun qidiryapman', 'sotib olishga uy qidiryapman'],
|
|
24
|
+
uzCyrl: ['сотиб оламан', 'сотиб олиш учун қидиряпман', 'сотиб олишга уй қидиряпман'],
|
|
25
|
+
kk: ['сатып аламын', 'сатып алуға іздеймін', 'сатып алуға пәтер іздеймін'],
|
|
26
|
+
}),
|
|
27
|
+
group('rentOut', {
|
|
28
|
+
ru: ['сдам', 'сдаю', 'сдаётся', 'сдается', 'сдаётся в аренду', 'сдается в аренду'],
|
|
29
|
+
en: ['for rent', 'renting out', 'available for rent', 'letting'],
|
|
30
|
+
uk: ['здам', 'здаю', 'здається', 'здається в оренду'],
|
|
31
|
+
ro: ['închiriez', 'inchiriez', 'de închiriat', 'de inchiriat', 'se închiriază', 'se inchiriaza'],
|
|
32
|
+
uzLatn: ['ijaraga beraman', 'ijaraga beriladi', 'ijaraga topshiraman'],
|
|
33
|
+
uzCyrl: ['ижарага бераман', 'ижарага берилади', 'ижарага топшираман'],
|
|
34
|
+
kk: KK_RENT_OUT_ALIASES,
|
|
35
|
+
}),
|
|
36
|
+
group('rentIn', {
|
|
37
|
+
ru: ['сниму', 'хочу снять', 'ищу снять', 'ищу квартиру', 'ищу жильё', 'ищу жилье', 'нужна квартира', 'нужно жильё', 'нужно жилье'],
|
|
38
|
+
en: ['looking to rent', 'want to rent', 'need an apartment', 'looking for an apartment', 'looking for housing'],
|
|
39
|
+
uk: ['зніму', 'хочу зняти', 'шукаю квартиру', 'шукаю житло', 'потрібна квартира'],
|
|
40
|
+
ro: ['vreau să închiriez', 'vreau sa inchiriez', 'caut să închiriez', 'caut sa inchiriez', 'caut apartament'],
|
|
41
|
+
uzLatn: ['ijaraga olaman', 'uy qidiryapman', 'kvartira qidiryapman', 'ijara uchun uy qidiryapman'],
|
|
42
|
+
uzCyrl: ['ижарага оламан', 'уй қидиряпман', 'квартира қидиряпман', 'ижара учун уй қидиряпман'],
|
|
43
|
+
kk: ['жалға аламын', 'пәтер іздеймін', 'үй іздеймін', 'жалға пәтер іздеймін'],
|
|
44
|
+
}),
|
|
45
|
+
]);
|
|
46
|
+
|
|
47
|
+
export const HOUSING_INTENT = Object.freeze([
|
|
48
|
+
group('offer', {
|
|
49
|
+
ru: ['продам', 'продаю', 'продаётся', 'продается', 'сдам', 'сдаю', 'сдаётся', 'сдается'],
|
|
50
|
+
en: ['for sale', 'selling', 'for rent', 'renting out'],
|
|
51
|
+
uk: ['продам', 'продаю', 'продається', 'здам', 'здаю', 'здається'],
|
|
52
|
+
ro: ['vând', 'vand', 'de vânzare', 'de vanzare', 'închiriez', 'inchiriez', 'de închiriat', 'de inchiriat'],
|
|
53
|
+
uzLatn: ['sotaman', 'sotiladi', 'ijaraga beraman', 'ijaraga beriladi'],
|
|
54
|
+
uzCyrl: ['сотаман', 'сотилади', 'ижарага бераман', 'ижарага берилади'],
|
|
55
|
+
kk: ['сатамын', 'сатылады', 'жалға беремін', 'жалға беріледі'],
|
|
56
|
+
}),
|
|
57
|
+
group('wanted', {
|
|
58
|
+
ru: ['куплю', 'ищу купить', 'сниму', 'ищу квартиру', 'ищу жильё', 'ищу жилье', 'нужна квартира'],
|
|
59
|
+
en: ['looking to buy', 'want to buy', 'looking to rent', 'need an apartment'],
|
|
60
|
+
uk: ['куплю', 'шукаю купити', 'зніму', 'шукаю квартиру', 'шукаю житло'],
|
|
61
|
+
ro: ['vreau să cumpăr', 'vreau sa cumpar', 'vreau să închiriez', 'vreau sa inchiriez', 'caut apartament'],
|
|
62
|
+
uzLatn: ['sotib olaman', 'sotib olish uchun qidiryapman', 'ijaraga olaman', 'uy qidiryapman'],
|
|
63
|
+
uzCyrl: ['сотиб оламан', 'сотиб олиш учун қидиряпман', 'ижарага оламан', 'уй қидиряпман'],
|
|
64
|
+
kk: ['сатып аламын', 'сатып алуға іздеймін', 'жалға аламын', 'пәтер іздеймін'],
|
|
65
|
+
}),
|
|
66
|
+
]);
|
|
67
|
+
|
|
68
|
+
// Deal type is transaction mechanics only. Direction is resolved by HOUSING_ACTIONS.
|
|
69
|
+
export const HOUSING_DEAL_TYPES = Object.freeze([
|
|
70
|
+
group('sale', {
|
|
71
|
+
ru: ['продажа', 'продать', 'покупка'],
|
|
72
|
+
en: ['sale', 'purchase'],
|
|
73
|
+
uk: ['продаж', 'продати', 'купівля'],
|
|
74
|
+
ro: ['vânzare', 'vanzare', ...RO_SALE_OFFER_ALIASES, 'cumpărare', 'cumparare'],
|
|
75
|
+
uzLatn: ['sotish', 'sotuv', 'sotib olish'],
|
|
76
|
+
uzCyrl: ['сотиш', 'сотув', 'сотиб олиш'],
|
|
77
|
+
kk: ['сату', 'сатып алу', 'сатылым'],
|
|
78
|
+
}),
|
|
79
|
+
group('longRent', {
|
|
80
|
+
ru: ['аренда', 'долгосрочно', 'долгосрочная аренда', 'помесячно', 'на длительный срок'],
|
|
81
|
+
en: ['rent', 'long term rent', 'long-term rent', 'monthly rent'],
|
|
82
|
+
uk: ['оренда', 'довгостроково', 'довгострокова оренда', 'помісячно'],
|
|
83
|
+
ro: ['închiriere', 'inchiriere', 'chirie', 'pe termen lung', 'lunar'],
|
|
84
|
+
uzLatn: ['ijara', 'uzoq muddatga', 'oylik ijara'],
|
|
85
|
+
uzCyrl: ['ижара', 'узоқ муддатга', 'ойлик ижара'],
|
|
86
|
+
kk: ['жалдау', 'жалға', ...KK_RENT_OUT_ALIASES, 'ұзақ мерзімге', 'айлық жалдау'],
|
|
87
|
+
}),
|
|
88
|
+
group('shortRent', {
|
|
89
|
+
ru: ['посуточно', 'посуточная аренда', 'на сутки', 'на час', 'почасово', 'краткосрочно'],
|
|
90
|
+
en: ['daily rent', 'short term', 'short-term rent', 'per day', 'hourly'],
|
|
91
|
+
uk: ['подобово', 'погодинно', 'на добу', 'на годину', 'короткострокова оренда'],
|
|
92
|
+
ro: ['regim hotelier', 'pe zi', 'zilnic', 'pe noapte', 'închiriere pe termen scurt', 'inchiriere pe termen scurt'],
|
|
93
|
+
uzLatn: ['kunlik', 'sutkaga', 'sutkalik', 'soatlik', 'kuniga'],
|
|
94
|
+
uzCyrl: ['кунлик', 'суткага', 'суткалик', 'соатлик', 'кунига'],
|
|
95
|
+
kk: ['тәулік', 'тәуліктік', 'тәулігіне', 'сағаттық', 'күндік'],
|
|
96
|
+
}),
|
|
97
|
+
]);
|
|
98
|
+
|
|
99
|
+
export const HOUSING_ACTION_MAP = Object.freeze({
|
|
100
|
+
sell: Object.freeze({ listingKind: 'propertyOffer', dealType: 'sale' }),
|
|
101
|
+
buy: Object.freeze({ listingKind: 'propertyWanted', dealType: 'sale' }),
|
|
102
|
+
rentOut: Object.freeze({ listingKind: 'propertyOffer', dealType: 'longRent' }),
|
|
103
|
+
rentIn: Object.freeze({ listingKind: 'propertyWanted', dealType: 'longRent' }),
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
export function resolveHousingIntent(value) {
|
|
107
|
+
const text = String(value || '');
|
|
108
|
+
if (!text.trim()) return null;
|
|
109
|
+
|
|
110
|
+
const action = findCanonical(text, HOUSING_ACTIONS, { partial: true });
|
|
111
|
+
const durationDeal = findCanonical(text, HOUSING_DEAL_TYPES, { partial: true });
|
|
112
|
+
|
|
113
|
+
if (action) {
|
|
114
|
+
const base = HOUSING_ACTION_MAP[action.canonical];
|
|
115
|
+
let dealType = base.dealType;
|
|
116
|
+
if (durationDeal?.canonical === 'shortRent' && (action.canonical === 'rentOut' || action.canonical === 'rentIn')) {
|
|
117
|
+
dealType = 'shortRent';
|
|
118
|
+
}
|
|
119
|
+
return Object.freeze({
|
|
120
|
+
action: action.canonical,
|
|
121
|
+
listingKind: base.listingKind,
|
|
122
|
+
dealType,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (!durationDeal) return null;
|
|
127
|
+
return Object.freeze({
|
|
128
|
+
action: null,
|
|
129
|
+
listingKind: null,
|
|
130
|
+
dealType: durationDeal.canonical,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
@@ -1,131 +1,131 @@
|
|
|
1
|
-
import { deepFreeze } from './lexicon-core.js';
|
|
2
|
-
import { normalizeUnicode } from './normalization.js';
|
|
3
|
-
import { parseHousingContext } from './housing-context.js';
|
|
4
|
-
import { parseHousingFeatures } from './housing-features.js';
|
|
5
|
-
|
|
6
|
-
const bool = (text, positive, negative = null) => {
|
|
7
|
-
if (negative?.test(text)) return false;
|
|
8
|
-
return positive.test(text) ? true : null;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const number = (match, min, max) => {
|
|
12
|
-
const value = match ? Number(match[1]) : null;
|
|
13
|
-
return Number.isFinite(value) && value >= min && value <= max ? value : null;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
function parseBedrooms(text) {
|
|
17
|
-
return number(text.match(/(\d+)\s*-?\s*(?:bedroom|спальн|спалень|dormitoare|dormitor|yotoq(?:xona)?|жатын)/iu), 1, 20);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function parseBathrooms(text) {
|
|
21
|
-
const match = text.match(/(\d)\s*(?:сан\s?уз(?:е)?л\p{L}*|с\/?у(?=$|[^\p{L}\p{N}_])|ванн[аы]|bathrooms?|sanuzel|hammom)/iu)
|
|
22
|
-
|| text.match(/(?:сан\s?уз(?:е)?л\p{L}*|bathrooms?|sanuzel|hammom)\D{0,4}(\d)/iu);
|
|
23
|
-
return number(match, 1, 10);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function parseBuildingYear(text) {
|
|
27
|
-
const match = text.match(/(?:год(?:а)?\s+постройк\p{L}*|построен\p{L}*|рік\s+побудов\p{L}*|built|year\s+built|an\s+construc\p{L}*|qurilgan|qurilish\s+yil\p{L}*|жыл(?:ы)?\s+салынған)\D{0,12}(19\d{2}|20[0-3]\d)/iu)
|
|
28
|
-
|| text.match(/(19\d{2}|20[0-3]\d)\s*(?:г\.?|года|р\.?|рік|йил|жыл|year)(?=$|[^\p{L}\p{N}_])/iu);
|
|
29
|
-
if (!match) return null;
|
|
30
|
-
const year = Number(match[1]);
|
|
31
|
-
return year >= 1900 && year <= new Date().getFullYear() + 3 ? year : null;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function parseMinRentTerm(text) {
|
|
35
|
-
const match = text.match(/(?:минимальн\p{L}*\s+(?:срок|термин)\p{L}*(?:\s+аренд\p{L}*)?|минимум|не\s+менее|від\s+|minimum(?:\s+term)?|at\s+least)\s*[:\-]?\s*(\d{1,3})\s*(дн\p{L}*|сут\p{L}*|недел\p{L}*|тижн\p{L}*|месяц\p{L}*|мес\.?|місяц\p{L}*|год\p{L}*|рік|days?|weeks?|months?|years?)/iu);
|
|
36
|
-
if (!match) return null;
|
|
37
|
-
const value = Number(match[1]);
|
|
38
|
-
const unitText = match[2].toLocaleLowerCase();
|
|
39
|
-
const unit = /дн|сут|day/u.test(unitText) ? 'day'
|
|
40
|
-
: /недел|тижн|week/u.test(unitText) ? 'week'
|
|
41
|
-
: /месяц|мес|місяц|month/u.test(unitText) ? 'month'
|
|
42
|
-
: 'year';
|
|
43
|
-
return value > 0 ? deepFreeze({ value, unit }) : null;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function parseAvailableFrom(text) {
|
|
47
|
-
const match = text.match(/(?:доступн\p{L}*\s+с|свободн\p{L}*\s+с|заселени\p{L}*\s+с|заезд\s+с|available\s+from|move[- ]?in\s+from)\s*[:\-]?\s*((?:\d{1,2}[./-]\d{1,2}(?:[./-]\d{2,4})?)|(?:\d{1,2}\s+[\p{L}]{3,12}(?:\s+\d{4})?))/iu);
|
|
48
|
-
return match?.[1]?.trim() || null;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function parseUtilitiesAmount(text) {
|
|
52
|
-
const match = text.match(/(?:коммунальн\p{L}*|коммуналк\p{L}*|ком\.?\s*услуг\p{L}*|utilities?|bills?)\D{0,24}(?:около|примерно|~|≈)?\s*(\d{2,8}(?:[.,]\d{1,2})?)\s*(₴|грн|uah|\$|usd|€|eur|сум|uzs|тг|kzt|lei|ron|руб|rub)?/iu);
|
|
53
|
-
if (!match) return null;
|
|
54
|
-
const amount = Number(match[1].replace(',', '.'));
|
|
55
|
-
if (!Number.isFinite(amount) || amount <= 0) return null;
|
|
56
|
-
const raw = (match[2] || '').toLocaleLowerCase();
|
|
57
|
-
const currency = /₴|грн|uah/u.test(raw) ? 'UAH'
|
|
58
|
-
: /\$|usd/u.test(raw) ? 'USD'
|
|
59
|
-
: /€|eur/u.test(raw) ? 'EUR'
|
|
60
|
-
: /сум|uzs/u.test(raw) ? 'UZS'
|
|
61
|
-
: /тг|kzt/u.test(raw) ? 'KZT'
|
|
62
|
-
: /lei|ron/u.test(raw) ? 'RON'
|
|
63
|
-
: /руб|rub/u.test(raw) ? 'RUB' : null;
|
|
64
|
-
return deepFreeze({ amount, currency, approximate: /около|примерно|~|≈/iu.test(match[0]) });
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function parseCommunalSeparated(text, country) {
|
|
68
|
-
if (/(коммунал\p{L}*(?:\s+услуг\p{L}*)?\s*(?:отдельно|сверху|плюс|оплачива\p{L}*\s*отдельно)|свет\s*вода\s*газ\s*отдельно|kommunal\p{L}*\s*(?:alohida|ustiga)|utilities?\s*(?:separate|extra|not included))/iu.test(text)) return true;
|
|
69
|
-
if (/(коммунал\p{L}*(?:\s+услуг\p{L}*)?\s*(?:включ|входит|в\s*стоимост)|вс[её]\s*включ|all\s*inclusive|kommunal\p{L}*\s*(?:kiritilgan|ichida)
|
|
70
|
-
return String(country || '').toUpperCase() === 'UA' ? true : null;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function parseDepositRequired(text) {
|
|
74
|
-
if (/(?:без\s+(?:залога|депозита)|залог\s+не\s+нужен|депозит\s+не\s+нужен|no\s+deposit)/iu.test(text)) return false;
|
|
75
|
-
if (/(?:^|[^\p{L}\p{N}_])(?:залог|депозит|deposit|depozit|garantie|garanție|кепіл)(?=$|[^\p{L}\p{N}_])/iu.test(text)) return true;
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function parseHousingListingFields(value, { country = '' } = {}) {
|
|
80
|
-
const text = normalizeUnicode(value ?? '');
|
|
81
|
-
const context = parseHousingContext(text);
|
|
82
|
-
const features = parseHousingFeatures(text);
|
|
83
|
-
if (!text) return deepFreeze({});
|
|
84
|
-
|
|
85
|
-
const gas = bool(text,
|
|
86
|
-
/(?:^|[^\p{L}\p{N}_])(?:газ|gaz|gas)(?=$|[^\p{L}\p{N}_])|метан|aragaz|gaz\s+ta['’]?min/iu,
|
|
87
|
-
/без\s+газа|нет\s+газа|no\s+gas|gaz\s*yo['’]?q/iu,
|
|
88
|
-
);
|
|
89
|
-
const elevator = bool(text, /лифт|elevator|\blift\b/iu, /без\s*лифт|no\s*elevator|lift\s*yo['’]?q/iu);
|
|
90
|
-
const furnished = context.furniture === 'none' ? false : context.furniture ? true : null;
|
|
91
|
-
const childrenAllowed = context.tenantPolicies.children === 'allowed' ? true
|
|
92
|
-
: context.tenantPolicies.children === 'notAllowed' ? false : null;
|
|
93
|
-
const smokingAllowed = context.tenantPolicies.smoking === 'allowed' ? true
|
|
94
|
-
: context.tenantPolicies.smoking === 'notAllowed' ? false : null;
|
|
95
|
-
|
|
96
|
-
const firstRent = bool(text,
|
|
97
|
-
/первая\s+(?:сдача|аренда)|впервые\s+(?:сда[её]тся|сдается|в\s+аренду)|first\s+(?:rental|letting)|never\s+rented/iu,
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
return deepFreeze({
|
|
101
|
-
bedrooms: parseBedrooms(text),
|
|
102
|
-
bathrooms: parseBathrooms(text),
|
|
103
|
-
buildingYear: parseBuildingYear(text),
|
|
104
|
-
balcony: bool(text, /балкон|лоджи|balkon|ayvon|balcon|loggia|balcony/iu),
|
|
105
|
-
terrace: bool(text, /террас|terrace|teras[ăa]?/iu),
|
|
106
|
-
privateYard: bool(text, /личн\p{L}*\s+двор|сво[йеё]\s+(?:закрыт\p{L}*\s+)?двор|собственн\p{L}*\s+двор|приватн\p{L}*\s+двір|власн\p{L}*\s+двір|private\s+(?:courtyard|yard)|curte\s+(?:proprie|privat[ăa])|shaxsiy\s+hovli/iu),
|
|
107
|
-
courtyard: features.courtyard,
|
|
108
|
-
gazebo: features.gazebo,
|
|
109
|
-
dishwasher: bool(text, /посудомоечн\p{L}*|посудомойк\p{L}*|dishwasher|mașin[ăa]\s+de\s+spălat\s+vase/iu),
|
|
110
|
-
airConditioner: bool(text, /кондицион|сплит[- ]?систем|konditsioner|klimat|air\s*con|aer\s+condi[țt]ionat/iu),
|
|
111
|
-
gas,
|
|
112
|
-
newBuilding: bool(text, /новостро|новобуд|новый\s+дом|new\s*build|newly\s*built|yangi\s+(?:bino|qurilgan|uy)|bloc\s+nou/iu),
|
|
113
|
-
communalSeparated: parseCommunalSeparated(text, country),
|
|
114
|
-
parking: bool(text, /паркинг|парков|машино[- ]?мест|parking|avtoturargoh|mashina\s*joyi/iu),
|
|
115
|
-
elevator,
|
|
116
|
-
heating: bool(text, /отоплени|heating|otoplenie|isitish|markaziy\s*issiq/iu),
|
|
117
|
-
hotWater: bool(text, /горяч\p{L}*\s*вод|hot\s*water|issiq\s*suv/iu),
|
|
118
|
-
internet: features.internet,
|
|
119
|
-
petsAllowed: features.petsAllowed,
|
|
120
|
-
childrenAllowed,
|
|
121
|
-
smokingAllowed,
|
|
122
|
-
negotiable: context.priceModifiers.includes('fixed') ? false
|
|
123
|
-
: context.priceModifiers.includes('negotiable') ? true : null,
|
|
124
|
-
furnished,
|
|
125
|
-
depositRequired: parseDepositRequired(text),
|
|
126
|
-
firstRent,
|
|
127
|
-
minRentTerm: parseMinRentTerm(text),
|
|
128
|
-
availableFrom: parseAvailableFrom(text),
|
|
129
|
-
utilitiesAmount: parseUtilitiesAmount(text),
|
|
130
|
-
});
|
|
131
|
-
}
|
|
1
|
+
import { deepFreeze } from './lexicon-core.js';
|
|
2
|
+
import { normalizeUnicode } from './normalization.js';
|
|
3
|
+
import { parseHousingContext } from './housing-context.js';
|
|
4
|
+
import { parseHousingFeatures } from './housing-features.js';
|
|
5
|
+
|
|
6
|
+
const bool = (text, positive, negative = null) => {
|
|
7
|
+
if (negative?.test(text)) return false;
|
|
8
|
+
return positive.test(text) ? true : null;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const number = (match, min, max) => {
|
|
12
|
+
const value = match ? Number(match[1]) : null;
|
|
13
|
+
return Number.isFinite(value) && value >= min && value <= max ? value : null;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
function parseBedrooms(text) {
|
|
17
|
+
return number(text.match(/(\d+)\s*-?\s*(?:bedroom|спальн|спалень|dormitoare|dormitor|yotoq(?:xona)?|жатын)/iu), 1, 20);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function parseBathrooms(text) {
|
|
21
|
+
const match = text.match(/(\d)\s*(?:сан\s?уз(?:е)?л\p{L}*|с\/?у(?=$|[^\p{L}\p{N}_])|ванн[аы]|bathrooms?|sanuzel|hammom)/iu)
|
|
22
|
+
|| text.match(/(?:сан\s?уз(?:е)?л\p{L}*|bathrooms?|sanuzel|hammom)\D{0,4}(\d)/iu);
|
|
23
|
+
return number(match, 1, 10);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function parseBuildingYear(text) {
|
|
27
|
+
const match = text.match(/(?:год(?:а)?\s+постройк\p{L}*|построен\p{L}*|рік\s+побудов\p{L}*|built|year\s+built|an\s+construc\p{L}*|qurilgan|qurilish\s+yil\p{L}*|жыл(?:ы)?\s+салынған)\D{0,12}(19\d{2}|20[0-3]\d)/iu)
|
|
28
|
+
|| text.match(/(19\d{2}|20[0-3]\d)\s*(?:г\.?|года|р\.?|рік|йил|жыл|year)(?=$|[^\p{L}\p{N}_])/iu);
|
|
29
|
+
if (!match) return null;
|
|
30
|
+
const year = Number(match[1]);
|
|
31
|
+
return year >= 1900 && year <= new Date().getFullYear() + 3 ? year : null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function parseMinRentTerm(text) {
|
|
35
|
+
const match = text.match(/(?:минимальн\p{L}*\s+(?:срок|термин)\p{L}*(?:\s+аренд\p{L}*)?|минимум|не\s+менее|від\s+|minimum(?:\s+term)?|at\s+least)\s*[:\-]?\s*(\d{1,3})\s*(дн\p{L}*|сут\p{L}*|недел\p{L}*|тижн\p{L}*|месяц\p{L}*|мес\.?|місяц\p{L}*|год\p{L}*|рік|days?|weeks?|months?|years?)/iu);
|
|
36
|
+
if (!match) return null;
|
|
37
|
+
const value = Number(match[1]);
|
|
38
|
+
const unitText = match[2].toLocaleLowerCase();
|
|
39
|
+
const unit = /дн|сут|day/u.test(unitText) ? 'day'
|
|
40
|
+
: /недел|тижн|week/u.test(unitText) ? 'week'
|
|
41
|
+
: /месяц|мес|місяц|month/u.test(unitText) ? 'month'
|
|
42
|
+
: 'year';
|
|
43
|
+
return value > 0 ? deepFreeze({ value, unit }) : null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function parseAvailableFrom(text) {
|
|
47
|
+
const match = text.match(/(?:доступн\p{L}*\s+с|свободн\p{L}*\s+с|заселени\p{L}*\s+с|заезд\s+с|available\s+from|move[- ]?in\s+from)\s*[:\-]?\s*((?:\d{1,2}[./-]\d{1,2}(?:[./-]\d{2,4})?)|(?:\d{1,2}\s+[\p{L}]{3,12}(?:\s+\d{4})?))/iu);
|
|
48
|
+
return match?.[1]?.trim() || null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function parseUtilitiesAmount(text) {
|
|
52
|
+
const match = text.match(/(?:коммунальн\p{L}*|коммуналк\p{L}*|ком\.?\s*услуг\p{L}*|utilities?|bills?)\D{0,24}(?:около|примерно|~|≈)?\s*(\d{2,8}(?:[.,]\d{1,2})?)\s*(₴|грн|uah|\$|usd|€|eur|сум|uzs|тг|kzt|lei|ron|руб|rub)?/iu);
|
|
53
|
+
if (!match) return null;
|
|
54
|
+
const amount = Number(match[1].replace(',', '.'));
|
|
55
|
+
if (!Number.isFinite(amount) || amount <= 0) return null;
|
|
56
|
+
const raw = (match[2] || '').toLocaleLowerCase();
|
|
57
|
+
const currency = /₴|грн|uah/u.test(raw) ? 'UAH'
|
|
58
|
+
: /\$|usd/u.test(raw) ? 'USD'
|
|
59
|
+
: /€|eur/u.test(raw) ? 'EUR'
|
|
60
|
+
: /сум|uzs/u.test(raw) ? 'UZS'
|
|
61
|
+
: /тг|kzt/u.test(raw) ? 'KZT'
|
|
62
|
+
: /lei|ron/u.test(raw) ? 'RON'
|
|
63
|
+
: /руб|rub/u.test(raw) ? 'RUB' : null;
|
|
64
|
+
return deepFreeze({ amount, currency, approximate: /около|примерно|~|≈/iu.test(match[0]) });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function parseCommunalSeparated(text, country) {
|
|
68
|
+
if (/(коммунал\p{L}*(?:\s+услуг\p{L}*)?\s*(?:отдельно|сверху|плюс|оплачива\p{L}*\s*отдельно)|свет\s*вода\s*газ\s*отдельно|kommunal\p{L}*\s*(?:alohida|ustiga)|utilities?\s*(?:separate|extra|not included))/iu.test(text)) return true;
|
|
69
|
+
if (/(коммунал\p{L}*(?:\s+услуг\p{L}*)?\s*(?:включ|входит|в\s*стоимост)|вс[её]\s*включ|all\s*inclusive|kommunal\p{L}*\s*(?:kiritilgan|ichida)|комунал(?:каси)?\s+ичида|коммунал(?:каси)?\s+ичида|utilities?\s*included)/iu.test(text)) return false;
|
|
70
|
+
return String(country || '').toUpperCase() === 'UA' ? true : null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function parseDepositRequired(text) {
|
|
74
|
+
if (/(?:без\s+(?:залога|депозита)|залог\s+не\s+нужен|депозит\s+не\s+нужен|no\s+deposit)/iu.test(text)) return false;
|
|
75
|
+
if (/(?:^|[^\p{L}\p{N}_])(?:залог|депозит|deposit|depozit|garantie|garanție|кепіл)(?=$|[^\p{L}\p{N}_])/iu.test(text)) return true;
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function parseHousingListingFields(value, { country = '' } = {}) {
|
|
80
|
+
const text = normalizeUnicode(value ?? '');
|
|
81
|
+
const context = parseHousingContext(text);
|
|
82
|
+
const features = parseHousingFeatures(text);
|
|
83
|
+
if (!text) return deepFreeze({});
|
|
84
|
+
|
|
85
|
+
const gas = bool(text,
|
|
86
|
+
/(?:^|[^\p{L}\p{N}_])(?:газ|gaz|gas)(?=$|[^\p{L}\p{N}_])|метан|aragaz|gaz\s+ta['’]?min/iu,
|
|
87
|
+
/без\s+газа|нет\s+газа|no\s+gas|gaz\s*yo['’]?q/iu,
|
|
88
|
+
);
|
|
89
|
+
const elevator = bool(text, /лифт|elevator|\blift\b/iu, /без\s*лифт|no\s*elevator|lift\s*yo['’]?q/iu);
|
|
90
|
+
const furnished = context.furniture === 'none' ? false : context.furniture ? true : null;
|
|
91
|
+
const childrenAllowed = context.tenantPolicies.children === 'allowed' ? true
|
|
92
|
+
: context.tenantPolicies.children === 'notAllowed' ? false : null;
|
|
93
|
+
const smokingAllowed = context.tenantPolicies.smoking === 'allowed' ? true
|
|
94
|
+
: context.tenantPolicies.smoking === 'notAllowed' ? false : null;
|
|
95
|
+
|
|
96
|
+
const firstRent = bool(text,
|
|
97
|
+
/первая\s+(?:сдача|аренда)|впервые\s+(?:сда[её]тся|сдается|в\s+аренду)|first\s+(?:rental|letting)|never\s+rented/iu,
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
return deepFreeze({
|
|
101
|
+
bedrooms: parseBedrooms(text),
|
|
102
|
+
bathrooms: parseBathrooms(text),
|
|
103
|
+
buildingYear: parseBuildingYear(text),
|
|
104
|
+
balcony: bool(text, /балкон|лоджи|balkon|ayvon|balcon|loggia|balcony/iu),
|
|
105
|
+
terrace: bool(text, /террас|terrace|teras[ăa]?/iu),
|
|
106
|
+
privateYard: bool(text, /личн\p{L}*\s+двор|сво[йеё]\s+(?:закрыт\p{L}*\s+)?двор|собственн\p{L}*\s+двор|приватн\p{L}*\s+двір|власн\p{L}*\s+двір|private\s+(?:courtyard|yard)|curte\s+(?:proprie|privat[ăa])|shaxsiy\s+hovli/iu),
|
|
107
|
+
courtyard: features.courtyard,
|
|
108
|
+
gazebo: features.gazebo,
|
|
109
|
+
dishwasher: bool(text, /посудомоечн\p{L}*|посудомойк\p{L}*|dishwasher|mașin[ăa]\s+de\s+spălat\s+vase/iu),
|
|
110
|
+
airConditioner: bool(text, /кондицион|сплит[- ]?систем|konditsioner|kansaner|klimat|air\s*con|aer\s+condi[țt]ionat/iu),
|
|
111
|
+
gas,
|
|
112
|
+
newBuilding: bool(text, /новостро|новобуд|новый\s+дом|novast(?:royka|iroyka)|navast(?:royka|iroyka)|new\s*build|newly\s*built|yangi\s+(?:bino|qurilgan|uy)|bloc\s+nou/iu),
|
|
113
|
+
communalSeparated: parseCommunalSeparated(text, country),
|
|
114
|
+
parking: bool(text, /паркинг|парков|машино[- ]?мест|parking|avtoturargoh|mashina\s*joyi/iu),
|
|
115
|
+
elevator,
|
|
116
|
+
heating: bool(text, /отоплени|heating|otoplenie|isitish|markaziy\s*issiq/iu),
|
|
117
|
+
hotWater: bool(text, /горяч\p{L}*\s*вод|hot\s*water|issiq\s*suv/iu),
|
|
118
|
+
internet: features.internet,
|
|
119
|
+
petsAllowed: features.petsAllowed,
|
|
120
|
+
childrenAllowed,
|
|
121
|
+
smokingAllowed,
|
|
122
|
+
negotiable: context.priceModifiers.includes('fixed') ? false
|
|
123
|
+
: context.priceModifiers.includes('negotiable') ? true : null,
|
|
124
|
+
furnished,
|
|
125
|
+
depositRequired: parseDepositRequired(text),
|
|
126
|
+
firstRent,
|
|
127
|
+
minRentTerm: parseMinRentTerm(text),
|
|
128
|
+
availableFrom: parseAvailableFrom(text),
|
|
129
|
+
utilitiesAmount: parseUtilitiesAmount(text),
|
|
130
|
+
});
|
|
131
|
+
}
|
package/src/housing-money.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type HousingPriceParseResult = Readonly<{
|
|
2
|
-
price: number | null;
|
|
3
|
-
currency: string;
|
|
4
|
-
}>;
|
|
5
|
-
|
|
6
|
-
export function parseHousingPrice(value: unknown, fallbackCurrency?: string): HousingPriceParseResult;
|
|
7
|
-
export const parsePriceFromText: typeof parseHousingPrice;
|
|
1
|
+
export type HousingPriceParseResult = Readonly<{
|
|
2
|
+
price: number | null;
|
|
3
|
+
currency: string;
|
|
4
|
+
}>;
|
|
5
|
+
|
|
6
|
+
export function parseHousingPrice(value: unknown, fallbackCurrency?: string): HousingPriceParseResult;
|
|
7
|
+
export const parsePriceFromText: typeof parseHousingPrice;
|