"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.hasCompactAccountCodeToken = hasCompactAccountCodeToken; exports.hasAccountNumberAnchor = hasAccountNumberAnchor; exports.resolveAddressIntent = resolveAddressIntent; const addressCounterpartyIntentSignals_1 = require("./addressCounterpartyIntentSignals"); const addressInventoryIntentSignals_1 = require("./addressInventoryIntentSignals"); const inventoryLifecycleCueHelpers_1 = require("./inventoryLifecycleCueHelpers"); const RECEIVABLES_STRONG = [ "кто должен нам", "кто нам должен", "кто нам должэн", "нам должны", "нам должен", "нам должэны", "who owes us", "receivable", "receivables", "debtor", "debtors", "дебитор", "дебиторск" ]; const PAYABLES_STRONG = [ "РєРѕРјСѓ должны РјС‹", "РєРѕРјСѓ должэны РјС‹", "РєРѕРјСѓ РјС‹ должны", "РєРѕРјСѓ РјС‹ должэны", "РјС‹ должны", "РјС‹ должэны", "who we owe", "payable", "payables", "creditor", "creditors", "кредитор", "кредиторск" ]; const ACCOUNT_BALANCE_HINTS = [ "account balance", "balance by account", "saldo", "баланс", "остаток РїРѕ счет", "сальдо РїРѕ счет", "РїРѕ счету", "что РЅР° счете", "что РЅР° счёте", "РЅР° конец" ]; const DOCUMENTS_FORMING_BALANCE_HINTS = [ "documents forming balance", "docs forming balance", "documents form balance", "docs form balance", "balance documents", "documents for balance", "which documents form balance", "РёР· чего состоит остаток", "какие документы формируют остаток", "раскрой остаток РїРѕ документам", "документы РїРѕРґ остатком" ]; const OPEN_CONTRACTS_HINTS = [ "open contracts", "unclosed contracts", "незакрыт", "РЅРµ закрыт", "открыт", "РґРѕРіРѕРІРѕСЂ", "контракт" ]; const OPEN_ITEMS_HINTS = [ "open items", "unclosed items", "С…РІРѕСЃС‚", "РІРёСЃСЏС‚", "незакрыт", "открыт", "долг", "задолж", "позици" ]; const DOCUMENTS_BY_COUNTERPARTY_HINTS = [ "documents by counterparty", "docs by counterparty", "documents by company", "documents by supplier", "documents by customer", "documents by client", "documents by partner", "show documents by counterparty", "list documents by counterparty", "документы РїРѕ", "доступные документы", "СЃРїРёСЃРѕРє документов", "документ", "РґРѕРєРё", "РґРѕРєРё РїРѕ", "РґРѕРє РїРѕ", "doki", "docy", "doci", "РїРѕ контрагент" ]; const BANK_OPERATIONS_BY_COUNTERPARTY_HINTS = [ "bank operations by counterparty", "bank payments by counterparty", "payment orders by counterparty", "bank operations by company", "bank operations by supplier", "bank operations by customer", "show bank operations by counterparty", "bank ops", "bank oper", "transactions by counterparty", "транзак", "банк", "банков", "РїРѕ банку", "опер", "выписк", "платеж", "платёж", "оплат", "списан", "списани", "поступлен", "поступлени", "движени" ]; const DOCUMENTS_BY_CONTRACT_HINTS = [ "documents by contract", "docs by contract", "show documents by contract", "list documents by contract", "документы РїРѕ РґРѕРіРѕРІРѕСЂСѓ", "РґРѕРєРё РїРѕ РґРѕРіРѕРІРѕСЂСѓ", "РґРѕРє РїРѕ РґРѕРіРѕРІРѕСЂСѓ", "документы РґРѕРіРѕРІРѕСЂ", "РґРѕРіРѕРІРѕСЂ", "документы РїРѕ контракту", "РґРѕРєРё РїРѕ контракту", "контракт" ]; const BANK_OPERATIONS_BY_CONTRACT_HINTS = [ "bank operations by contract", "bank payments by contract", "payment orders by contract", "transactions by contract", "bank ops by contract", "банковские операции РїРѕ РґРѕРіРѕРІРѕСЂСѓ", "платежи РїРѕ РґРѕРіРѕРІРѕСЂСѓ", "выписка РїРѕ РґРѕРіРѕРІРѕСЂСѓ", "банковские операции РїРѕ контракту", "платежи РїРѕ контракту", "выписка РїРѕ контракту" ]; const BANK_OPERATION_CORE_HINTS = [ "банк", "банков", "операц", "опер", "выписк", "платеж", "платёж", "оплат", "списан", "поступлен", "движени", "транзак", "bank", "payment", "payments", "transaction", "transactions", "statement", "wire" ]; const PERIOD_COVERAGE_PROFILE_HINTS = [ "Р·Р° какие РіРѕРґС‹", "Р·Р° какие РіРѕРґР°", "РІ базе есть данные", "покрытие периодов", "диапазон лет", "профиль данных", "самый активный РіРѕРґ", "самый активный месяц", "самый пассивный РіРѕРґ", "самый пассивный месяц", "наименее активный РіРѕРґ", "наименее активный месяц", "РјРёРЅРёРјСѓРј документов РїРѕ РіРѕРґСѓ", "РјРёРЅРёРјСѓРј операций РїРѕ месяцу", "РіРѕРґ СЃ минимальным количеством документов", "месяц СЃ минимальным количеством операций", "активный РіРѕРґ РїРѕ количеству документов", "активный месяц РїРѕ количеству операций", "most active year", "most active month", "least active year", "least active month", "year coverage", "data coverage" ]; const DOCUMENT_TYPE_AND_ACCOUNT_SECTION_PROFILE_HINTS = [ "типы документов", "типы РґРѕРєРѕРІ", "документы чаще всего", "документы реже всего", "редкие типы документов", "наименее используемые типы документов", "частые типы документов", "СЃРІРѕРґРєР° РїРѕ типам документов", "доля типов документов", "разделы учета", "разделы учёта", "наиболее заполнены", "наименее заполнены", "почти РЅРµ используются", "account section", "document types usage", "document type profile" ]; const COUNTERPARTY_POPULATION_AND_ROLES_HINTS = [ "сколько всего контрагентов", "сколько уникальных контрагентов", "сколько контрагентов РІ базе", "сколько заказчиков", "сколько поставщиков", "сколько клиентов", "сколько покупателей", "СЃРєРѕРєР° всего контрагентов", "СЃРєРѕРєР° уникальных контрагентов", "СЃРєРѕРєР° контрагентов РІ базе", "СЃРєРѕРєР° заказчиков", "СЃРєРѕРєР° поставщиков", "СЃРєРѕРєР° клиентов", "СЃРєРѕРєР° покупателей", "СЃРєРѕРє контрагентов", "СЃРєРѕРє контрагентов РІ базе", "СЃРєРѕРє заказчиков", "СЃРєРѕРє поставщиков", "СЃРєРѕРє клиентов", "СЃРєРѕРє покупателей", "сколько смешанных контрагентов", "типы контрагентов", "разбей контрагентов", "раздели контрагентов", "counterparty population", "counterparty roles", "customer supplier split" ]; const COUNTERPARTY_ACTIVITY_LIFECYCLE_HINTS = [ "какие заказчики работали", "какие заказчики активны", "какие клиенты работали", "какие клиенты активны", "какие контрагенты работали", "какие поставщики работали", "СЃРїРёСЃРѕРє заказчиков", "СЃРїРёСЃРѕРє клиентов", "СЃРїРёСЃРѕРє заказчиков Р·Р° РІСЃРµ время", "СЃРїРёСЃРѕРє клиентов Р·Р° РІСЃРµ время", "СЃРїРёСЃРѕРє активных заказчиков", "СЃРїРёСЃРѕРє активных клиентов", "новые заказчики", "новые клиенты", "новые контрагенты", "впервые РІ", "кто исчез", "кто ушел", "кто ушёл", "только РѕРґРёРЅ раз", "дольше всего", "дольше всех", "долгоживущие контрагенты", "регулярные поставщики", "эпизодические поставщики", "давно РЅРµ использовались поставщики", "всех заков", "кто был активен", "потом отвалился", "СЂРѕРІРЅРѕ РѕРґРёРЅ раз", "Рё пропал", "самые старые РїРѕ сотрудничеству", "разбей поставщиков РЅР° регуляр Рё разовые", "кто новые РІ этом РіРѕРґСѓ", "active customers", "сколько лет активности РІ базе", "сколько лет активности РІ 1СЃ", "сколько лет РІ базе 1СЃ", "какой первый платеж", "какое первое поступление", "РєРѕРіРґР° была первая активность", "РєРѕРіРґР° была последняя активность", "первая активность РІ базе", "последняя активность РІ базе", "customer activity list", "counterparty lifecycle" ]; const CONTRACT_USAGE_OVERVIEW_HINTS = [ "сколько всего РґРѕРіРѕРІРѕСЂРѕРІ", "сколько РґРѕРіРѕРІРѕСЂРѕРІ заведено", "сколько РґРѕРіРѕРІРѕСЂРѕРІ РІ базе", "сколько РґРѕРіРѕРІРѕСЂРѕРІ использовались", "сколько РґРѕРіРѕРІРѕСЂРѕРІ использовалось", "РґРѕРіРѕРІРѕСЂС‹ total vs used", "РѕР±Р·РѕСЂ РґРѕРіРѕРІРѕСЂРЅРѕР№ базы", "договорная база total used", "неиспользуемые РґРѕРіРѕРІРѕСЂС‹", "давно РЅРµ использовались РґРѕРіРѕРІРѕСЂС‹", "мертвые РґРѕРіРѕРІРѕСЂС‹", "мёртвые РґРѕРіРѕРІРѕСЂС‹", "stale contracts", "unused contracts", "contracts total used", "contract usage overview" ]; const CUSTOMER_REVENUE_AND_PAYMENTS_HINTS = [ "самые доходные клиенты", "самые доходные заказчики", "самые ликвидные клиенты", "самые ликвидные заказчики", "самых ликвидних заказчиков", "топ клиентов РїРѕ СЃСѓРјРјРµ поступлений", "топ заказчиков РїРѕ СЃСѓРјРјРµ поступлений", "кто больше всего принес денег", "кто больше всего принёс денег", "кто принес больше всего денег", "кто принёс больше всего денег", "кто нам больше денег принес", "кто нам больше денег принёс", "кто нам принес больше денег", "кто нам принёс больше денег", "кто нам больше всего занес", "кто нам больше всего занёс", "кто нам принес больше всего", "кто нам принёс больше всего", "кто платит чаще всего", "средний чек клиентов", "средний чек заказчиков", "крупные сделки РїРѕ поступлениям", "маленькие сделки РїРѕ поступлениям", "smallest deals by inflow", "largest deals by inflow", "top customers by inflow", "top customers by revenue" ]; const SUPPLIER_PAYOUTS_PROFILE_HINTS = [ "топ поставщиков РїРѕ СЃСѓРјРјРµ выплат", "РєРѕРјСѓ РјС‹ больше всего заплатили", "РєРѕРјСѓ ушло больше всего денег", "РєРѕРјСѓ РјС‹ больше всего сгрузили денег", "поставщики РїРѕ выплатам", "поставщики РїРѕ исходящим платежам", "поставщики СЃ максимальным числом выплат", "крупные разовые выплаты поставщикам", "top suppliers by payouts", "top suppliers by outgoing payments" ]; const CONTRACT_USAGE_AND_VALUE_HINTS = [ "РґРѕРіРѕРІРѕСЂС‹ РїРѕ обороту", "РґРѕРіРѕРІРѕСЂС‹ РїРѕ СЃСѓРјРјРµ оборота", "топ РґРѕРіРѕРІРѕСЂРѕРІ РїРѕ обороту", "контракты РїРѕ обороту", "контракты РїРѕ СЃСѓРјРјРµ оборота", "топ контрактов РїРѕ обороту", "РґРѕРіРѕРІРѕСЂС‹ СЃ минимальным бюджетом", "РґРѕРіРѕРІРѕСЂС‹ СЃ самым маленьким бюджетом", "контракты СЃ минимальным бюджетом", "контракты СЃ самым маленьким бюджетом", "активные РґРѕРіРѕРІРѕСЂС‹ РїРѕ бюджету", "активные контракты РїРѕ бюджету", "контрагенты СЃ несколькими договорами", "несколько РґРѕРіРѕРІРѕСЂРѕРІ Сѓ контрагента", "мультидоговорные контрагенты", "какие РґРѕРіРѕРІРѕСЂС‹ активны", "какие контракты активны", "рабочие РґРѕРіРѕРІРѕСЂС‹", "рабочие контракты", "contracts by turnover", "contracts by budget" ]; const CONTRACT_LIST_BY_COUNTERPARTY_HINTS = [ "РґРѕРіРѕРІРѕСЂС‹ РїРѕ", "РґРѕРіРѕРІРѕСЂР° РїРѕ", "СЃРїРёСЃРѕРє РґРѕРіРѕРІРѕСЂРѕРІ РїРѕ", "покажи РґРѕРіРѕРІРѕСЂС‹ РїРѕ", "выведи РґРѕРіРѕРІРѕСЂС‹ РїРѕ", "контракты РїРѕ", "СЃРїРёСЃРѕРє контрактов РїРѕ", "покажи контракты РїРѕ", "выведи контракты РїРѕ", "contracts by counterparty", "list contracts by counterparty", "show contracts by counterparty" ]; function hasAny(text, patterns) { return patterns.some((item) => text.includes(item)); } function hasFlexibleReceivablesDebtSignal(text) { const normalized = String(text ?? ""); if (!normalized) { return false; } const hasFlexibleWhoOwesUs = /(?:\u043a\u0442\u043e(?:\s+\S+){0,4}\s+\u043d\u0430\u043c(?:\s+\S+){0,4}\s+\u0434\u043e\u043b\u0436)/iu.test(normalized) || /(?:\u043d\u0430\u043c(?:\s+\S+){0,4}\s+\u043a\u0442\u043e(?:\s+\S+){0,4}\s+\u0434\u043e\u043b\u0436)/iu.test(normalized); const hasTorchatToUsSignal = /(?:\u043d\u0430\u043c(?:\s+\S+){0,3}\s+\u0442\u043e\u0440\u0447(?:\u0430\u0442|\u0438\u0442)|\u0442\u043e\u0440\u0447(?:\u0430\u0442|\u0438\u0442)(?:\s+\S+){0,3}\s+\u043d\u0430\u043c)/iu.test(normalized); return hasFlexibleWhoOwesUs || hasTorchatToUsSignal; } function hasFlexiblePayablesDebtSignal(text) { const normalized = String(text ?? ""); if (!normalized) { return false; } return (/(?:РєРѕРјСѓ(?:\s+\S+){0,4}\s+РјС‹(?:\s+\S+){0,4}\s+долж)/iu.test(normalized) || /(?:РјС‹(?:\s+\S+){0,4}\s+РєРѕРјСѓ(?:\s+\S+){0,4}\s+долж)/iu.test(normalized)); } function tokenizeText(text) { return String(text ?? "") .toLowerCase() .split(/[^a-zР°-СЏС‘0-9]+/iu) .map((token) => token.trim()) .filter((token) => token.length > 0); } function trimRussianEnding(token) { return token.replace(/(?:РёСЏРјРё|СЏРјРё|ами|РѕРіРѕ|ему|РѕРјСѓ|ыми|РёРјРё|ией|ей|РёР№|ый|РѕР№|СЏС…|ах|РѕРІ|ев|ам|СЏРј|РѕРј|ем|С‹|Рё|Р°|СЏ|Сѓ|СЋ|Рµ|Рѕ)$/u, ""); } function normalizeLexemeToken(rawToken) { const token = String(rawToken ?? "").toLowerCase().replace(/[^a-zР°-СЏС‘0-9]+/gu, ""); if (!token) { return ""; } if (/^[a-z0-9]+$/u.test(token)) { return token; } return trimRussianEnding(token); } function levenshteinDistance(a, b) { if (a === b) { return 0; } if (!a.length) { return b.length; } if (!b.length) { return a.length; } const prev = new Array(b.length + 1); const curr = new Array(b.length + 1); for (let j = 0; j <= b.length; j += 1) { prev[j] = j; } for (let i = 1; i <= a.length; i += 1) { curr[0] = i; for (let j = 1; j <= b.length; j += 1) { const cost = a[i - 1] === b[j - 1] ? 0 : 1; curr[j] = Math.min(prev[j] + 1, curr[j - 1] + 1, prev[j - 1] + cost); } for (let j = 0; j <= b.length; j += 1) { prev[j] = curr[j]; } } return prev[b.length]; } function hasFuzzyLexeme(text, lexemeRoots) { const normalizedRoots = lexemeRoots .map((root) => normalizeLexemeToken(root)) .filter((root) => root.length > 0); if (normalizedRoots.length === 0) { return false; } const tokens = tokenizeText(text) .map((token) => normalizeLexemeToken(token)) .filter((token) => token.length >= 4); for (const token of tokens) { for (const root of normalizedRoots) { if (token.includes(root)) { return true; } if (root.includes(token) && token.length >= 5) { return true; } const maxDistance = root.length >= 7 ? 2 : 1; if (Math.abs(token.length - root.length) > maxDistance) { continue; } if (levenshteinDistance(token, root) <= maxDistance) { return true; } } } return false; } function hasCompactAccountCodeToken(text) { // Match compact account tokens while reducing false positives on short-year literals like "22 РіРѕРґ". const source = String(text ?? ""); if (!source) { return false; } // Safe compact form: 60.01 / 62.1 if (/(? token.replace(/^[^\p{L}\p{N}#в„–]+|[^\p{L}\p{N}./_-]+$/gu, "").trim()) .filter((token) => token.length > 0); for (const rawToken of rawTokens) { const token = String(rawToken ?? "").trim(); if (!/^\d{1,6}[./_-]\d{1,6}(?:[./_-]\d{1,6})?$/u.test(token)) { continue; } if (!token) { continue; } if (/^\d{1,2}\.\d{1,2}$/u.test(token)) { // Likely an account code like 60.01/51.00, not a contract number. continue; } const parts = token.split(/[./_-]+/u).map((part) => Number(part)); if (!parts.every((part) => Number.isFinite(part))) { return true; } if (parts.length === 2) { const [a, b] = parts; const yearFirst = a >= 1900 && a <= 2099 && b >= 1 && b <= 12; const yearSecond = b >= 1900 && b <= 2099 && a >= 1 && a <= 12; if (yearFirst || yearSecond) { continue; } return true; } if (parts.length === 3) { const [a, b, c] = parts; const ymd = a >= 1900 && a <= 2099 && b >= 1 && b <= 12 && c >= 1 && c <= 31; const dmy = c >= 1900 && c <= 2099 && a >= 1 && a <= 31 && b >= 1 && b <= 12; if (ymd || dmy) { continue; } return true; } return true; } return false; } function hasContractAnchorSignal(text) { if (hasContractAnchorMention(text)) { return true; } // Allow short forms like "19/15" for follow-up prompts if document/bank signal exists. return hasContractNumberLikeToken(text) && hasDocsOrBankSignal(text); } function hasLooseByAnchorMention(text) { const match = text.match(/(?:^|\s)РїРѕ\s+([a-zР°-СЏС‘][a-zР°-СЏС‘0-9._-]{1,})(?=[\s,.;:!?)]|$)/iu); if (!match) { return false; } const token = String(match[1] ?? "").toLowerCase(); if (!token) { return false; } const stopWords = new Set([ "контрагенту", "контрагента", "контре", "компании", "компанию", "организации", "организацию", "поставщику", "поставщика", "клиенту", "клиента", "покупателю", "покупателя", "партнеру", "партнера", "РґРѕРіРѕРІРѕСЂСѓ", "РґРѕРіРѕРІРѕСЂР°", "счету", "счёту", "дате", "периоду", "период", "документам", "докам", "количество", "количеству", "количества", "количеством", "активности", "пассивности", "наименее", "РјРёРЅРёРјСѓРј" ]); return !stopWords.has(token); } function hasImplicitCounterpartyAnchorAroundDocs(text) { const beforeDocsMatch = text.match(/(?:^|\s)([a-zР°-СЏС‘][a-zР°-СЏС‘0-9._-]{1,})\s+(?:РґРѕРє(?:Рё|СѓРј(?:ент(?:С‹|РѕРІ|ам|Р°)?)?)|docs?|documents?|doki|docy|doci)(?=[\s,.;:!?)]|$)/iu); if (beforeDocsMatch && isLikelyCounterpartyToken(String(beforeDocsMatch[1] ?? ""))) { return true; } const afterDocsMatch = text.match(/(?:РґРѕРє(?:Рё|СѓРј(?:ент(?:С‹|РѕРІ|ам|Р°)?)?)|docs?|documents?|doki|docy|doci)\s+(?:РїРѕ\s+)?([a-zР°-СЏС‘][a-zР°-СЏС‘0-9._-]{1,})(?=[\s,.;:!?)]|$)/iu); if (afterDocsMatch && isLikelyCounterpartyToken(String(afterDocsMatch[1] ?? ""))) { return true; } return false; } function hasDocsOrBankSignal(text) { return /(?:РґРѕРє(?:Рё|умент|ументы|ументов)|docs?|documents?|doki|docy|doci|банк|выписк|платеж|платёж|оплат|transactions?|bank\s+ops|bank\s+operations?)/iu.test(text); } function hasBankOperationSignal(text) { return hasAny(text, BANK_OPERATION_CORE_HINTS) || hasAny(text, BANK_OPERATIONS_BY_COUNTERPARTY_HINTS) || hasAny(text, BANK_OPERATIONS_BY_CONTRACT_HINTS); } function hasDocumentSignal(text) { return (text.includes("РґРѕРє") || text.includes("РґРѕРєРё") || text.includes("документ") || text.includes("doki") || text.includes("docy") || text.includes("doci") || text.includes("docs") || text.includes("documents")); } function hasHeuristicCounterpartyAnchor(text) { if (!hasDocsOrBankSignal(text) && !hasBankOperationSignal(text)) { return false; } const tokens = String(text ?? "") .split(/[^a-zР°-СЏС‘0-9._-]+/iu) .map((item) => item.trim()) .filter((item) => item.length > 0); for (const token of tokens) { const lowered = token.toLowerCase(); if (!isLikelyCounterpartyToken(lowered)) { continue; } if (/^\d{2}$/.test(lowered) || /^\d{4}$/.test(lowered)) { continue; } if (/(?:^Р·Р°$|^for$|^from$|^to$|^РїРѕ$|^СЃ$|^РіРѕРґ$|^РіРѕРґР°$|^Рі$|^year$)/iu.test(lowered)) { continue; } return true; } return false; } function hasGenericAddressLookupSignal(text) { return (/\bесть\b/iu.test(text) || /\bпокажи\b/iu.test(text) || /\bвыведи\b/iu.test(text) || /\bкакие\b/iu.test(text) || /\bчто(?:-|\s)?то\b/iu.test(text) || /Р·Р°\s+любой\s+период/iu.test(text) || /Р·Р°\s+РІСЃ[её]\s+время/iu.test(text) || /for\s+all\s+time/iu.test(text) || /all\s+time/iu.test(text)); } function hasAccountNumberAnchor(text) { return /(?:account|СЃС‡[её]С‚|счет)\D{0,12}\d{2}(?:[.,]\d{1,2})?/i.test(text); } function hasInventoryAccount41Anchor(text) { return /(?:СЃС‡[её]С‚(?:Р°|Рµ|Сѓ)?|счет(?:Р°|Рµ|Сѓ)?)\D{0,12}41(?:[.,]0?1)?/iu.test(text) || /41(?:[.,]0?1)?\D{0,12}(?:СЃС‡[её]С‚(?:Р°|Рµ|Сѓ)?|счет(?:Р°|Рµ|Сѓ)?)/iu.test(text); } function hasInventoryAsOfCue(text) { return /(?:сейчас|текущ|РЅР°\s+дату|РїРѕ\s+состоянию|срез|РЅР°\s+конец|date|as\s+of|current|now|today)/iu.test(text); } function hasInventoryOnHandSignal(text) { const hasColloquialStockSnapshotCue = /(?:что|С‡[еёо])\s+(?:Сѓ\s+нас\s+)?РЅР°\s+склад(?:Рµ|Сѓ|РѕРј|ах)(?=$|[\s,.;:!?])/iu.test(text); const hasStockStateCue = /(?:(?:что|С‡[еёо])\s+там\s+РЅР°\s+склад(?:Рµ|Сѓ|РѕРј|ах)|(?:что|С‡[еёо]).*РїСЂРѕРёСЃС…РѕРґ(?:РёС‚|ило|ящее).*(?:РЅР°\s+)?склад(?:Рµ|Сѓ|РѕРј|ах)|РїСЂРѕРёСЃС…РѕРґ(?:РёС‚|ило|ящее)\s+РЅР°\s+склад(?:Рµ|Сѓ|РѕРј|ах)|ситуац(?:РёСЏ|РёРё)\s+РЅР°\s+склад(?:Рµ|Сѓ|РѕРј|ах)|обстановк(?:Р°|Рё)\s+РЅР°\s+склад(?:Рµ|Сѓ|РѕРј|ах)|what(?:'s| is)?\s+(?:there\s+)?(?:on|in)\s+(?:the\s+)?(?:warehouse|stock)|what(?:'s| is)?\s+happening\s+(?:on|in)\s+(?:the\s+)?(?:warehouse|stock))/iu.test(text); const hasAccount41Anchor = hasInventoryAccount41Anchor(text); const hasStockLexeme = /(?:склад(?:Рµ|Сѓ|РѕРј|С‹|РѕРІ)?|warehouse|stock(?:room)?|inventory|on[\s-]?hand)/iu.test(text); if (!hasStockLexeme && !hasAccount41Anchor) { return false; } if (hasInventoryProvenanceSignalV2(text) || hasInventoryPurchaseDocumentsSignalV2(text) || hasInventorySaleTraceSignalV2(text) || hasInventoryAgingSignal(text) || hasInventoryPurchaseToSaleChainSignal(text)) { return false; } const hasGoodsLexeme = /(?:товар(?:С‹|РѕРІ|РѕРј|Р°|ные)?|номенклатур|материал(?:С‹|РѕРІ|Р°|ам)?|item(?:s)?|sku|product(?:s)?)/iu.test(text); const hasBalanceLexeme = /(?:леж(?:РёС‚|ат)|есть|числ(?:РёС‚(?:СЃСЏ|СЃСЊ)|ятся)|остат(?:РѕРє|РєРё)|срез|РЅР°\s+дат|РїРѕ\s+состоянию|РЅР°\s+конец|РїСЂРѕРёСЃС…РѕРґ(?:РёС‚|ило|ящее)|ситуац(?:РёСЏ|РёРё)|обстановк(?:Р°|Рё)|today|now|current|as\s+of)/iu.test(text); const hasRequestCue = /(?:покажи|показать|выведи|дай|какие|что|С‡[еёо]|какой|сколько|проверь|проверить|чекни|check|show|list|which|what)/iu.test(text); if (hasAccount41Anchor && (hasGoodsLexeme || hasBalanceLexeme || hasRequestCue || hasInventoryAsOfCue(text))) { return true; } return (hasGoodsLexeme || hasBalanceLexeme || hasColloquialStockSnapshotCue || hasStockStateCue) && (hasRequestCue || hasBalanceLexeme || hasColloquialStockSnapshotCue || hasStockStateCue); } function hasInventoryProvenanceSignal(text) { return /(?:поставщик|закупк|РїСЂРѕРёСЃС…РѕР¶Рґ|откуда|РєРѕРіРґР° был куплен|активная закупк|purchase provenance|purchase date|supplier provenance|stock overlap)/iu.test(text); } function hasInventoryPurchaseDocumentsSignal(text) { return /(?:Р С—Р С• каким документам|документы закупки|purchase documents|documents of purchase|through which documents|chain of documents)/iu.test(text); } function hasInventorySaleTraceSignal(text) { return /(?:продаж|покупател|buyer|sale trace|purchase[\s-]?to[\s-]?sale|purchase -> warehouse -> sale|закупка.*продаж)/iu.test(text); } function hasSelectedObjectInventoryCue(text) { return /(?:РїРѕ\s+выбранному\s+объекту|РїРѕ\s+выбранной\s+позиции|РїРѕ\s+этой\s+позиции|РїРѕ\s+этому\s+товару|РїРѕ\s+нему|РїРѕ\s+ней|РїРѕ\s+РЅРёРј|РїРѕ\s+нему\s+Р¶Рµ|РїРѕ\s+ней\s+Р¶Рµ|selected\s+object)/iu.test(String(text ?? "")); } function hasSelectedObjectInventoryProvenanceSignal(text) { return hasSelectedObjectInventoryCue(text) && (0, inventoryLifecycleCueHelpers_1.hasInventorySupplierCue)(text); } function hasSelectedObjectInventoryPurchaseDocumentsSignal(text) { const hasPurchaseDocumentsCue = /(?:РїРѕ\s+каким\s+документам\s+(?:это|его|этот\s+товар|эту\s+позицию)\s+купили|РїРѕ\s+каким\s+документам\s+(?:был\s+)?куплен|какими\s+документами\s+(?:это|его|этот\s+товар|эту\s+позицию)\s+купили|какими\s+документами\s+(?:был\s+)?куплен|purchase\s+documents|documents\s+of\s+purchase|through\s+which\s+documents)/iu.test(text) || /(?:(?:РїРѕ\s+каким|какими)\s+РґРѕРє[Р°-СЏС‘]*[\s\S]{0,80}(?:РєСѓРїРёР»|куплен)|РґРѕРє(?:Рё|умент[Р°-СЏС‘]*)[\s\S]{0,80}(?:РїРѕ\s+(?:РЅРёРј|ней|нему|этой\s+позиции|этому\s+товару)|операци)|(?:РїРѕ\s+(?:РЅРёРј|ней|нему|этой\s+позиции|этому\s+товару))[\s\S]{0,80}РґРѕРє(?:Рё|умент[Р°-СЏС‘]*))/iu.test(text); return (hasSelectedObjectInventoryCue(text) && hasPurchaseDocumentsCue); } function hasSelectedObjectInventorySaleTraceSignal(text) { return hasSelectedObjectInventoryCue(text) && (0, inventoryLifecycleCueHelpers_1.hasInventorySaleCue)(text); } function hasSelectedObjectInventoryProfitabilitySignal(text) { return hasSelectedObjectInventoryCue(text) && (0, inventoryLifecycleCueHelpers_1.hasInventoryProfitabilityCue)(text); } function hasInventoryProvenanceSignalV2(text) { const hasItemCue = /(?:товар|номенклатур|sku|item|product|остат(?:РѕРє|РєРё)|склад)/iu.test(text); const hasSupplierCue = (0, inventoryLifecycleCueHelpers_1.hasInventorySupplierCue)(text) || /кем\s+поставлен/iu.test(text); const hasPurchaseCue = /(?:куплен(?:С‹|Р°|Рѕ)?|закупк|происхождени|откуда|РіРґРµ\s+(?:РјС‹\s+)?купили(?:\s+(?:это|его|товар|позицию))?|РіРґРµ\s+куплено|РєРѕРіРґР°\s+был\s+куплен|РєРѕРіРґР°\s+куплен|дата\s+закупк|кто\s+(?:нам\s+)?поставил|кем\s+поставлен|поставлен(?:С‹|Р°)?|purchase\s+provenance|purchase\s+date)/iu.test(text) || (0, inventoryLifecycleCueHelpers_1.hasInventoryPurchaseStem)(text); return hasItemCue && hasSupplierCue && hasPurchaseCue; } function hasInventoryPurchaseDateSignal(text) { const hasItemCue = /(?:товар|номенклатур|sku|item|product)/iu.test(text) || hasSelectedObjectInventoryCue(text); const hasPurchaseDateCue = /(?:РєРѕРіРґР°\s+(?:примерно\s+)?(?:РјС‹\s+)?купили|РєРѕРіРґР°\s+был\s+куплен|РєРѕРіРґР°\s+куплен|дата\s+закупк|purchase\s+date)/iu.test(text) || /(?:РєРѕРіРґР°\s+был(?:Р°|Рё|Рѕ)?\s+закупк\w*|РєРѕРіРґР°\s+закупк\w*)/iu.test(text); return hasItemCue && hasPurchaseDateCue; } function hasInventoryPurchaseDocumentsSignalV2(text) { const hasItemCue = /(?:товар|номенклатур|sku|item|product)/iu.test(text); const hasPurchaseDocCue = /(?:РїРѕ\s+каким\s+документам\s+был\s+куплен|РїРѕ\s+каким\s+документам\s+куплен|какими\s+документами\s+был\s+куплен|документ(?:ам|С‹)\s+закупк|purchase\s+documents|documents\s+of\s+purchase|through\s+which\s+documents)/iu.test(text); return hasItemCue && hasPurchaseDocCue; } function hasInventorySaleTraceSignalV2(text) { const value = String(text ?? ""); const hasPlainItemCue = /(?:\u0442\u043e\u0432\u0430\u0440|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442\u0443\u0440|\u043f\u043e\u0437\u0438\u0446|\u043f\u0440\u043e\u0434\u0443\u043a\u0446\u0438|sku|item|product)/iu.test(value); const hasPlainTraceCue = /(?:\u043a\u043e\u043c\u0443\s+(?:\u0432\s+\u0438\u0442\u043e\u0433\u0435\s+)?(?:\u043c\u044b\s+)?(?:\u043f\u0440\u043e\u0434\u0430\u043b\u0438|\u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438|\u0432\u043f\u0430\u0440\u0438\u043b\u0438)|\u043a\u043e\u043c\u0443\s+(?:\u0431\u044b\u043b[\u0430\u0438\u043e]?|\u0431\u044b\u043b\u0438)?\s*(?:\u043f\u0440\u043e\u0434\u0430\u043d|\u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d)|\u043a\u0442\u043e\s+\u043a\u0443\u043f\u0438\u043b|\u043f\u043e\u043a\u0443\u043f\u0430\u0442\u0435\u043b|buyer|sale\s+trace|trace\s+of\s+sale)/iu.test(value); if (hasPlainItemCue && (hasPlainTraceCue || (0, inventoryLifecycleCueHelpers_1.hasInventorySaleCue)(value))) { return true; } const hasItemCue = /(?:товар|номенклатур|sku|item|product|позици(?:СЏ|СЋ|Рё)|продукци(?:СЏ|СЋ|Рё))/iu.test(text); const hasTraceCue = /(?:РєРѕРјСѓ\s+(?:РІ\s+итоге\s+)?(?:РјС‹\s+)?продали|РєРѕРјСѓ\s+был\s+продан|РєСѓРґР°\s+(?:РІ\s+итоге\s+)?(?:РјС‹\s+)?продали(?:\s+(?:это|его|товар|позицию))?|РєСѓРґР°\s+(?:была\s+)?реализована\s+(?:позиция|номенклатура|продукция)|кто\s+РєСѓРїРёР»|buyer|sale\s+trace|trace\s+of\s+sale|через\s+какие\s+документы\s+РїСЂРѕС€[её]Р»\s+путь\s+товара|закупк.*склад.*продаж|purchase[\s-]?to[\s-]?sale|purchase\s*->\s*warehouse\s*->\s*sale|purchase\s*->\s*stock\s*->\s*sale)/iu.test(text); return hasItemCue && hasTraceCue; } function hasInventorySupplierStockOverlapSignal(text) { const hasDirectSingleItemSupplierQuestion = /(?:РѕС‚\s+какого\s+поставщика\s+куплен\s+(?:товар|номенклатур(?:Р°|Сѓ|С‹)|позици(?:СЏ|СЋ|Рё))|РѕС‚\s+РєРѕРіРѕ\s+куплен\s+(?:товар|номенклатур(?:Р°|Сѓ|С‹)|позици(?:СЏ|СЋ|Рё)))/iu.test(text); if (hasDirectSingleItemSupplierQuestion) { return false; } const hasSupplierCue = /(?:поставщик|supplier|vendor|РѕС‚\s+поставщика|Сѓ\s+поставщика)/iu.test(text); const hasStockCue = /(?:склад|остат(?:РѕРє|РєРµ|РєРѕРІ)|лежат|лежит|сейчас\s+еще|сейчас\s+ещ[её]|РЅР°\s+дату|РїРѕ\s+состоянию\s+РЅР°\s+дату|current\s+stock|stock\s+overlap|что\s+сейчас\s+лежит)/iu.test(text); return hasSupplierCue && hasStockCue; } function hasInventoryAgingSignal(text) { const hasResidueCue = /(?:остат(?:РѕРє|РєРё)|РІ\s+остатке|среди\s+текущих\s+остатков|РЅР°\s+складе|stock\s+residue|stock\s+balance)/iu.test(text); const hasAgingCue = /(?:стар(?:ые|ым|ых)\s+закупк|стары(?:Рј|С…)\s+закупк(?:ам|Рё|ах)|относит(?:СЃСЏ|СЃСЏ\s+ли)?\s+.*\s+Рє\s+старым\s+закупк|закупал(?:РёСЃСЊ|СЃСЏ)\s+очень\s+давно|очень\s+давно|давно\s+куплен|давно\s+приобретен|куплен\s+задолго\s+РґРѕ(?:\s+даты)?|закуплен(?:С‹|Р°)?\s+давно|приобретен\s+давно|задолго\s+РґРѕ(?:\s+даты)?|возраст\s+остатк|возраст\s+закупк|aged?\s+stock|old\s+purchase|old\s+purchases|old\s+stock|bought\s+long\s+ago|purchased\s+long\s+ago|aging\s+by\s+purchase\s+date|very\s+old\s+stock|very\s+old\s+purchase|old\s+procurement|older\s+purchases|aged\s+items|old\s+goods)/iu.test(text); return hasAgingCue || (hasResidueCue && /(?:давно\s+куплен|давно\s+приобретен|задолго\s+РґРѕ)/iu.test(text)); } function hasInventoryPurchaseToSaleChainSignal(text) { const value = String(text ?? ""); const hasPlainItemCue = /(?:товар|номенклатур|позици|sku|item|product)/iu.test(value); const hasPlainChainCue = /(?:закупк[а-яё]*\s*->\s*склад\s*->\s*продаж|закупк[а-яё]*[\s\S]{0,80}склад[\s\S]{0,80}продаж|через\s+какие\s+документы\s+прош[её]л\s+путь|путь\s+товар[а-яё]*[\s\S]{0,80}закуп|цепочк[а-яё]*\s+движен|документально\s+подтвержденн[а-яё]*\s+цепочк|supplier\s*->\s*item\s*->\s*(?:buyer|customer)|supplier\s+to\s+buyer|supplier\s+to\s+item\s+to\s+buyer|purchase[\s-]?to[\s-]?sale|purchase\s*->\s*(?:warehouse|stock)\s*->\s*sale)/iu.test(value) || value.includes("->"); if (hasPlainItemCue && hasPlainChainCue) { return true; } const hasItemCue = /(?:товар|номенклатур|sku|item|product)/iu.test(text); const hasChainCue = /(?:закупк.*склад.*продаж|purchase[\s-]?to[\s-]?sale|purchase\s*->\s*(?:warehouse|stock)\s*->\s*sale|закупка\s*->\s*склад\s*->\s*продажа|цепочк[аи]\s+движен|документально\s+подтвержденн\w+\s+цепочк|supplier\s*->\s*item\s*->\s*(?:buyer|customer)|supplier\s+to\s+buyer|supplier\s+to\s+item\s+to\s+buyer)/iu.test(text) || text.includes("->"); return hasItemCue && hasChainCue; } function hasInventorySupplierToBuyerChainSignal(text) { const hasSupplierCue = /(?:поставщик|supplier|vendor)/iu.test(text); const hasBuyerCue = /(?:покупател|buyer|customer|client)/iu.test(text); const hasItemCue = /(?:товар|номенклатур|sku|item|product)/iu.test(text); const hasChainCue = /(?:документально\s+подтвержденн\w+\s+цепочк|supplier\s*->\s*item\s*->\s*buyer|supplier\s*->\s*item\s*->\s*customer|supplier\s*->\s*buyer|supplier\s+to\s+buyer|supplier\s+to\s+buyer\s+chain|supplier\s+to\s+item\s+to\s+buyer|поставщик\s*->\s*товар\s*->\s*покупател|поставщик\s*->\s*товар\s*->\s*клиент|поставщик\s*->\s*товар\s*->\s*покупатель|поставщик\s+Рє\s+покупател|поставщик\s+Рє\s+клиент|поставщик\s+Рє\s+товару\s+Рё\s+покупателю)/iu.test(text) || text.includes("->"); return hasSupplierCue && hasBuyerCue && hasItemCue && hasChainCue; } function hasCustomerRevenueRankingBridgeSignal(text) { const normalized = String(text ?? "").trim().toLowerCase(); if (!normalized) { return false; } const hasSupplierCue = /(?:\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a|\u0432\u0435\u043d\u0434\u043e\u0440|supplier|vendor)/iu.test(normalized); if (hasSupplierCue) { return false; } const hasDirectRankingCue = /(?:\u0441\u0430\u043c(?:\u044b\u0439|\u0430\u044f|\u043e\u0435)?\s+\u0434\u043e\u0445\u043e\u0434\u043d(?:\u044b\u0439|\u0430\u044f|\u043e\u0435|\u044b\u0435|\u043e\u0433\u043e|\u043e\u043c\u0443|\u044b\u043c|\u044b\u0445)?\s+(?:\u043a\u043b\u0438\u0435\u043d\u0442|customer|client)|(?:\u043a\u0430\u043a\u043e\u0439|\u043a\u0430\u043a\u0430\u044f)\s+(?:\u0443\s+\u043d\u0430\u0441\s+)?\u0441\u0430\u043c(?:\u044b\u0439|\u0430\u044f|\u043e\u0435)?\s+\u0434\u043e\u0445\u043e\u0434\u043d(?:\u044b\u0439|\u0430\u044f|\u043e\u0435|\u044b\u0435|\u043e\u0433\u043e|\u043e\u043c\u0443|\u044b\u043c|\u044b\u0445)?\s+\u0433\u043e\u0434|(?:\u0430\s+)?(?:\u0441\u043a\u043e\u043b\u044c\u043a\u043e|\u0441\u043a\u043e\u043a)\s+(?:\u0432\u043e\u043e\u0431\u0449\u0435\s+)?(?:\u0434\u0435\u043d\u0435\u0433\s+)?\u043c\u044b\s+\u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438(?:\s+\u0437\u0430\s+\u0432\u0441\u0435\s+\u0432\u0440\u0435\u043c\u044f)?|(?:\u0430\s+)?(?:\u0437\u0430|for)\s+\d{4}\s+\u043c\u044b\s+(?:\u0441\u043a\u043e\u043b\u044c\u043a\u043e|\u0441\u043a\u043e\u043a)\s+\u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438|(?:\u0441\u043a\u043e\u043b\u044c\u043a\u043e|\u0441\u043a\u043e\u043a)\s+\u043c\u044b\s+\u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438\s+\u0437\u0430\s+\d{4}|(?:\u043e\u0431\u0449\u0430\u044f\s+)?\u0432\u044b\u0440\u0443\u0447\u043a\u0430\s+\u0437\u0430\s+\d{4})/iu.test(normalized); if (hasDirectRankingCue) { return true; } const hasMoneyCue = /(?:\u0434\u0435\u043d\u044c\u0433|\u0434\u0435\u043d\u0435\u0433|\u0432\u044b\u0440\u0443\u0447|\u0434\u043e\u0445\u043e\u0434|\u043e\u0431\u043e\u0440\u043e\u0442|revenue|turnover|money|inflow)/iu.test(normalized); if (!hasMoneyCue) { return false; } const hasCustomerRankingCue = /(?:\u043a\u0442\u043e\s+(?:\u043d\u0430\u043c\s+)?(?:\u0431\u043e\u043b\u044c\u0448\u0435(?:\s+\u0432\u0441\u0435\u0433\u043e)?\s+\u043f\u0440\u0438\u043d\u0435\u0441(?:\s+\u0434\u0435\u043d\u0435\u0433)?|\u043f\u0440\u0438\u043d\u0435\u0441\s+\u0431\u043e\u043b\u044c\u0448\u0435(?:\s+\u0432\u0441\u0435\u0433\u043e)?\s+\u0434\u0435\u043d\u0435\u0433)|who\s+brought\s+(?:us\s+)?(?:the\s+)?most\s+money|(?:\u0441\u0430\u043c(?:\u044b\u0439|\u0430\u044f|\u043e\u0435)?\s+\u0434\u043e\u0445\u043e\u0434\u043d\w*\s+(?:\u043a\u043b\u0438\u0435\u043d\u0442|customer|client)))/iu.test(normalized); const hasRevenueAggregateCue = /(?:(?:\u043a\u0430\u043a\u043e\u0439|\u043a\u0430\u043a\u0430\u044f)\s+(?:\u0443\s+\u043d\u0430\u0441\s+)?\u0441\u0430\u043c(?:\u044b\u0439|\u0430\u044f|\u043e\u0435)?\s+\u0434\u043e\u0445\u043e\u0434\u043d\w*\s+\u0433\u043e\u0434|(?:\u0441\u043a\u043e\u043b\u044c\u043a\u043e|скок)\s+(?:\u0432\u043e\u043e\u0431\u0449\u0435\s+)?(?:\u0434\u0435\u043d\u0435\u0433\s+)?\u043c\u044b\s+\u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438|(?:\u0437\u0430|for)\s+\d{4}\s+\u043c\u044b\s+(?:\u0441\u043a\u043e\u043b\u044c\u043a\u043e|скок)\s+\u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438|\u0432\u044b\u0440\u0443\u0447\u043a\w*\s+\u0437\u0430\s+\d{4})/iu.test(normalized); return hasCustomerRankingCue || hasRevenueAggregateCue; } function hasSpecificCounterpartyRevenueBridgeSignal(text) { const normalized = String(text ?? "").trim().toLowerCase(); if (!normalized) { return false; } const hasSupplierCue = /(?:\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a|\u0432\u0435\u043d\u0434\u043e\u0440|supplier|vendor)/iu.test(normalized); const hasNonRevenueEntityCue = /(?:\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\u0434\u043e\u043a\u0438|\u0434\u043e\u0433\u043e\u0432\u043e\u0440|\u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442|\u0431\u0430\u043d\u043a|\u043f\u043b\u0430\u0442\u0435\u0436|docs?|documents?|contract|bank|payment)/iu.test(normalized); if (hasSupplierCue || hasNonRevenueEntityCue) { return false; } const hasRevenueCue = /(?:\u043e\u0431\u043e\u0440\u043e\u0442|\u0432\u044b\u0440\u0443\u0447\w*|\u0434\u043e\u0445\u043e\u0434\w*|revenue|turnover)/iu.test(normalized); if (!hasRevenueCue) { return false; } const explicitEntityMatch = normalized.match(/(?:^|[\s,.;:!?])(?:\u043f\u043e|by|for)\s+([\p{L}\d][\p{L}\d._-]{1,})\s*$/iu) ?? normalized.match(/(?:\u043e\u0431\u043e\u0440\u043e\u0442|\u0432\u044b\u0440\u0443\u0447\w*|\u0434\u043e\u0445\u043e\u0434\w*|revenue|turnover)\s+(?:(?:\u0431\u044b\u043b(?:\u0430|\u043e)?|was)\s+)?(?:(?:\u0443|\u043f\u043e|by|for)\s+)?([\p{L}\d][\p{L}\d._-]{1,})\s*$/iu); const entity = explicitEntityMatch?.[1] ? String(explicitEntityMatch[1]).toLowerCase() : null; if (!entity || /^\d+$/.test(entity)) { return false; } const ignoredEntityTails = new Set([ "\u043d\u0430\u043c", "\u043d\u0430\u0441", "\u0432\u0441\u0435", "\u0432\u0441\u0435\u043c", "\u0433\u043e\u0434", "\u0433\u043e\u0434\u0430", "\u043c\u0435\u0441\u044f\u0446", "year", "month" ]); return !ignoredEntityTails.has(entity); } function hasInventoryProvenanceBridgeSignal(text) { const normalized = String(text ?? "").trim().toLowerCase(); if (!normalized) { return false; } const hasItemCue = /(?:\u0442\u043e\u0432\u0430\u0440|\u043f\u043e\u0437\u0438\u0446|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442\u0443\u0440|sku|item|product)/iu.test(normalized); const hasSupplierCue = /(?:\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a|\u043e\u0442\s+\u043a\u0430\u043a\u043e\u0433\u043e|\u043a\u0442\u043e\s+\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b|supplier|vendor)/iu.test(normalized); const hasPurchaseCue = /(?:\u043a\u0443\u043f\u043b\u0435\u043d|\u0437\u0430\u043a\u0443\u043f|\u043a\u043e\u0433\u0434\u0430\s+\u043a\u0443\u043f\u0438\u043b|\u043a\u0443\u043f\u0438\u043b\u0438|purchase)/iu.test(normalized); return hasItemCue && hasSupplierCue && hasPurchaseCue; } function hasInventoryDocumentaryChainBridgeSignal(text) { const normalized = String(text ?? "").trim().toLowerCase(); if (!normalized) { return false; } const hasChainCue = /(?:\u0446\u0435\u043f\u043e\u0447|\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u043b|\u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434|->|\u2192|chain|trace)/iu.test(normalized); const hasSupplierCue = /(?:\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a|supplier|vendor)/iu.test(normalized); const hasBuyerCue = /(?:\u043f\u043e\u043a\u0443\u043f\u0430\u0442\u0435\u043b|\u043a\u043b\u0438\u0435\u043d\u0442|buyer|customer|client)/iu.test(normalized); const hasItemCue = /(?:\u0442\u043e\u0432\u0430\u0440|\u043f\u043e\u0437\u0438\u0446|\u043d\u043e\u043c\u0435\u043d\u043a\u043b\u0430\u0442\u0443\u0440|sku|item|product)/iu.test(normalized); return hasChainCue && hasSupplierCue && hasBuyerCue && hasItemCue; } function hasColloquialInventoryOnHandBridgeSignal(text) { const normalized = String(text ?? "").trim().toLowerCase(); if (!normalized) { return false; } const hasInventoryAgingCue = /(?:\u043e\u0447\u0435\u043d\u044c\s+\u0434\u0430\u0432\u043d\u043e|\u0434\u0430\u0432\u043d\u043e\s+\u043a\u0443\u043f\u043b|\u0434\u0430\u0432\u043d\u043e\s+\u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0442|\u0441\u0442\u0430\u0440(?:\u044b\u0435|\u044b\u043c|\u044b\u0445)?\s+\u0437\u0430\u043a\u0443\u043f|\u0441\u0442\u0430\u0440\u044b\u0439\s+\u0442\u043e\u0432\u0430\u0440|old\s+stock|old\s+purchase|aging\s+by\s+purchase\s+date)/iu.test(normalized); if (hasInventoryAgingCue) { return false; } const tokenCount = normalized.split(/\s+/u).filter(Boolean).length; const hasWarehouseCue = /(?:\u0441\u043a\u043b\u0430\u0434(?:\u0430\u0445|\u0435|\u0443|\u043e\u043c|\u044b)?|\u043e\u0441\u0442\u0430\u0442|warehouse|stock|inventory)/iu.test(normalized); if (!hasWarehouseCue) { return false; } const hasQuestionCue = /(?:\u0447\u0442\u043e|\u0447\u0435|\u0447\u0451|\u043a\u0430\u043a\u0438\u0435|\u043f\u043e\u043a\u0430\u0436\u0438|\u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c|show|list|what)/iu.test(normalized); return hasQuestionCue && tokenCount <= 8; } function repairLikelyUtf8Mojibake(text) { const raw = String(text ?? ""); if (!raw) { return ""; } try { const repaired = Buffer.from(raw, "latin1").toString("utf8"); return repaired || raw; } catch { return raw; } } function unicodeBridgeResolution(intent, confidence, reason) { return { intent, confidence, reasons: [reason] }; } function hasBidirectionalValueFlowComparisonSignal(text) { const normalized = String(text ?? "").trim().toLowerCase(); if (!normalized) { return false; } const hasIncomingCue = /(?:\u0432\u0445\u043e\u0434\u044f\u0449|\u043f\u043e\u0441\u0442\u0443\u043f|\u043f\u043e\u043b\u0443\u0447|inflow|incoming)/iu.test(normalized); const hasOutgoingCue = /(?:\u0438\u0441\u0445\u043e\u0434\u044f\u0449|\u0441\u043f\u0438\u0441\u0430\u043d|\u0437\u0430\u043f\u043b\u0430\u0442|\u043f\u043b\u0430\u0442\u0438\u043b|\u043e\u043f\u043b\u0430\u0442|outflow|outgoing|payout)/iu.test(normalized); const hasComparisonCue = /(?:\u0431\u043e\u043b\u044c\u0448|\u043c\u0435\u043d\u044c\u0448|\u0441\u0440\u0430\u0432|\u0438\u043b\u0438|\u043d\u0435\u0442\u0442\u043e|\u0441\u0430\u043b\u044c\u0434\u043e|vs|versus)/iu.test(normalized); const hasValueFlowCue = /(?:\u0434\u0435\u043d\u044c\u0433|\u0434\u0435\u043d\u0435\u0433|\u0434\u0435\u043d\u0435\u0436|\u043f\u043e\u0442\u043e\u043a|\u043e\u0431\u043e\u0440\u043e\u0442|money|cash|flow)/iu.test(normalized); return hasIncomingCue && hasOutgoingCue && hasComparisonCue && hasValueFlowCue; } function resolveUnicodeAddressIntentBridge(text) { const normalized = String(text ?? "").trim().toLowerCase(); if (!normalized) { return null; } const hasAccountAnchor = /(?:\b(?:60|62|76)(?:[.,]\d{2})?\b|сч(?:е|ё)т(?:а|у|ом|е|ов)?|account)/iu.test(normalized); const hasDocumentCue = /(?:док(?:умент(?:ы|ов|а|ам|ами|ах)?|и|ам|ами|ах|ов|а)?|docs?|documents?)/iu.test(normalized); const hasBankCue = /(?:банк|банковск|плат[её]ж|оплат|транзакц|51|bank|payment|transaction)/iu.test(normalized); const hasContractCue = /(?:договор|дог(?:\s|$)|контракт|contract|dogovor)/iu.test(normalized); const hasSpecificContractCue = /(?:\b\d{1,4}\/\d{1,4}\b|этому\s+же\s+договор)/iu.test(normalized); const hasCounterpartyCue = /(?:контрагент|компани|организац|клиент|покупател|заказчик|поставщик|свк|альфа|жуковк|альтернатива|counterpart|company|supplier|customer|client|buyer)/iu.test(normalized); const byAnchorMatch = normalized.match(/(?:^|[\s,.;:!?])(?:по|для)\s+([\p{L}\d._-]{2,})/iu); const byAnchorToken = String(byAnchorMatch?.[1] ?? "").toLowerCase(); const hasLooseCounterpartyByAnchor = !!byAnchorToken && !new Set([ "количеству", "документам", "докам", "договору", "договорам", "счету", "счёту", "остатку", "операциям", "оплате", "платежам", "сальдо", "дате", "периоду", "складу", "товару", "этому", "этой", "нему", "ней" ]).has(byAnchorToken); const hasMoneyCue = /(?:деньг|денег|выручк|доход|оборот|заработ|прин[её]с|чек|ликвидн|revenue|turnover|money)/iu.test(normalized); const hasRankingCue = /(?:топ|ранк|сам(?:ый|ая|ое|ые)|больше\s+всего|наибольш|крупн|жирн|max|top|rank)/iu.test(normalized); const hasInventoryPurchaseToSaleDocumentChainCue = /(?:закупк[а-яё]*[\s\S]{0,80}склад[\s\S]{0,80}продаж|путь\s+товар[а-яё]*[\s\S]{0,80}закуп|purchase\s*->\s*(?:warehouse|stock)\s*->\s*sale|->\s*(?:склад|warehouse|stock)\s*->\s*(?:продаж|sale))/iu.test(normalized) && /(?:товар|позици|номенклатур|sku|item|product)/iu.test(normalized); if (hasInventoryPurchaseToSaleDocumentChainCue) { return unicodeBridgeResolution("inventory_purchase_to_sale_chain", "high", "unicode_inventory_purchase_to_sale_chain_bridge_signal_detected"); } const hasOpenItemsAccountCue = /(?:хвост|долг|незакрыт|вис)/iu.test(normalized) && /(?:сч(?:е|ё)т(?:а|у|ом|е|ов)?\s*(?:№|#)?\s*(?:60|62|76)(?:[.,]\d{1,2})?|\b(?:60|62|76)(?:[.,]\d{1,2})?\b\s*сч(?:е|ё)т)/iu.test(normalized); if (hasOpenItemsAccountCue) { return unicodeBridgeResolution("open_items_by_counterparty_or_contract", "medium", "open_items_signal_detected"); } const hasCounterpartyShipmentItemFlowCue = /(?:отгруж(?:ал|али|ен[аоы]?|енн(?:ый|ая|ое|ые)?))/iu.test(normalized) && /(?:товар|услуг|позици|номенклатур)/iu.test(normalized) && !/(?:выбранн(?:ый|ому)\s+объект|selected\s+object)/iu.test(normalized); if (hasCounterpartyShipmentItemFlowCue) { return unicodeBridgeResolution("list_documents_by_counterparty", "medium", "counterparty_item_flow_signal_detected"); } const hasHighestValueCustomerCue = /(?:сам(?:ый|ые|ая|ое)|топ|кто|какой|какие|больше\s+всего|наибольш)/iu.test(normalized) && /(?:доходн|выручк|денег|деньг|оборот|поступлен|прин[её]с)/iu.test(normalized) && /(?:клиент|покупател|заказчик|контрагент)/iu.test(normalized); if (!hasContractCue && hasHighestValueCustomerCue) { return unicodeBridgeResolution("customer_revenue_and_payments", "high", "unicode_customer_revenue_bridge_signal_detected"); } if (hasBidirectionalValueFlowComparisonSignal(normalized)) { return unicodeBridgeResolution("unknown", "high", "unicode_bidirectional_value_flow_deferred_to_discovery"); } if (/(?:за\s+какие\s+годы|диапазон\s+лет|покрыт(?:ие|ый)\s+период|какой\s+год.*актив|какой\s+месяц.*актив|год.*пассив|месяц.*пассив|минимальн.*док|минимальн.*операц|месяц[\s-]*пик|profile\s+period|top\s*year|top\s*month)/iu.test(normalized)) { return unicodeBridgeResolution("period_coverage_profile", "high", "unicode_period_coverage_bridge_signal_detected"); } if (/(?:тип(?:ы|ов)?\s+док|док(?:умент|ов).*?(?:чаще|редк|больше\s+всего|меньше\s+всего|крутит)|раздел(?:ы|ов)?\s+уч[её]та|сводк.*тип.*док|document\s+type|account\s+section)/iu.test(normalized)) { return unicodeBridgeResolution("document_type_and_account_section_profile", "high", "unicode_document_type_profile_bridge_signal_detected"); } if (hasAccountAnchor && hasDocumentCue && /(?:формирующ.*остат|раскрой\s+остат|остат.*по\s+документ|по\s+докам.*(?:60|62|76)|(?:60|62|76)(?:[.,]\d{2})?.*(?:по\s+докам|по\s+документ))/iu.test(normalized)) { return unicodeBridgeResolution("documents_forming_balance", "high", "unicode_documents_forming_balance_bridge_signal_detected"); } if (/(?:договор[а-я]*.*(?:все|список).*по\s+[\p{L}\d]|(?:покажи|показать).*договор[а-я]*.*по\s+[\p{L}\d])/iu.test(normalized)) { return unicodeBridgeResolution("list_contracts_by_counterparty", "high", "unicode_contracts_by_counterparty_bridge_signal_detected"); } if (/(?:проконтрол|акты\s+без\s+приход|без\s+приходок|засорять\s+бухгалтер)/iu.test(normalized)) { return unicodeBridgeResolution("unknown", "low", "unsupported_supplier_control_signal_detected"); } if (/(?:кроме\s+этого\s+документ.*(?:есть\s+еще\s+что|есть\s+ещ[её]\s+что|что[-\s]?то))/iu.test(normalized)) { return unicodeBridgeResolution("list_documents_by_counterparty", "medium", "generic_document_followup_with_previous_counterparty"); } if (/(?:плат[её]ж|оплат|отгрузк|документ|аванс|взаиморасчет|закрыт)/iu.test(normalized) && /(?:без\s+(?:закрыт|документ|оплат)|нет\s+(?:документ|оплат)|не\s+закрыт|оплат[а-я]*\s+нет|документ[а-я]*\s+есть|требует\s+ручн)/iu.test(normalized)) { return unicodeBridgeResolution("list_open_contracts", "high", "unicode_open_contract_gap_bridge_signal_detected"); } if (/(?:долгожител|долго\s+долж|задолженн(?:ост|остям).*(?:давн|долго)|не\s+плат|не\s+оплат|не\s+оплачен|неоплачен|просроч|сроки\s+давно\s+прошл|слишком\s+длинн.*оплат)/iu.test(normalized) && /(?:покупател|клиент|заказ|отгрузк|товар|услуг|задолженн|сальдо|не\s+плат|не\s+оплат|не\s+оплачен|неоплачен|просроч)/iu.test(normalized)) { return unicodeBridgeResolution("list_receivables_counterparties", "high", "receivables_debt_lifecycle_signal_detected"); } const inventoryBridgeIntent = (0, addressInventoryIntentSignals_1.resolveInventoryAddressIntent)(normalized); if (inventoryBridgeIntent) { if (inventoryBridgeIntent.intent === "inventory_aging_by_purchase_date") { return { ...inventoryBridgeIntent, confidence: "high" }; } return inventoryBridgeIntent; } if (/(?:поставщик|vendor|supplier)/iu.test(normalized) && /(?:хвост|задержк|проблем|систематическ)/iu.test(normalized)) { return unicodeBridgeResolution("list_payables_counterparties", "high", "supplier_tail_risk_signal_detected"); } if (hasDocumentCue && (hasCounterpartyCue || hasLooseCounterpartyByAnchor) && !hasContractCue) { return unicodeBridgeResolution("list_documents_by_counterparty", "high", "unicode_documents_by_counterparty_bridge_signal_detected"); } if (hasBankCue && (hasCounterpartyCue || hasLooseCounterpartyByAnchor) && !hasContractCue) { return unicodeBridgeResolution("bank_operations_by_counterparty", "high", "unicode_bank_ops_by_counterparty_bridge_signal_detected"); } if (/(?:есть\s+что[-\s]?то|что[-\s]?то)/iu.test(normalized) && (hasLooseCounterpartyByAnchor || /по\s+(?:ней|нему|этой|этому)/iu.test(normalized))) { return unicodeBridgeResolution("list_documents_by_counterparty", "medium", "generic_lookup_with_loose_anchor_fallback"); } if (hasDocumentCue && (hasLooseCounterpartyByAnchor || hasCounterpartyCue || /по\s+(?:ней|нему|этой|этому)/iu.test(normalized)) && !hasContractCue && !/(?:купил|куплен|закуп|товар|позици|номенклатур)/iu.test(normalized)) { return unicodeBridgeResolution("list_documents_by_counterparty", "medium", "unicode_documents_by_counterparty_bridge_signal_detected"); } if (/(?:долгожител|долго\s+долж|задолженн(?:ост|остям).*(?:давн|долго)|не\s+плат|не\s+оплат|не\s+оплачен|неоплачен|просроч|сроки\s+давно\s+прошл|слишком\s+длинн.*оплат)/iu.test(normalized) && /(?:покупател|клиент|заказ|отгрузк|товар|услуг|задолженн|сальдо|не\s+плат|не\s+оплат|не\s+оплачен|неоплачен|просроч)/iu.test(normalized)) { return unicodeBridgeResolution("list_receivables_counterparties", "high", "receivables_debt_lifecycle_signal_detected"); } if (/\b41(?:[.,]\d{2})?\b/iu.test(normalized) && /(?:товар|склад|остат|состоит|номенклатур)/iu.test(normalized)) { return unicodeBridgeResolution("inventory_on_hand_as_of_date", "high", "unicode_inventory_on_hand_bridge_signal_detected"); } if (/(?:год.*(?:док|операц).*(?:актив|пик|жив|много|движов)|год.*движов.*(?:док|операц)|(?:док|операц).*год.*(?:актив|пик|жив|много|движов)|месяц[\s-]*пик)/iu.test(normalized)) { return unicodeBridgeResolution("period_coverage_profile", "high", "unicode_period_coverage_bridge_signal_detected"); } if (!hasContractCue && /(?:скольк|скока).*(?:деньг|денег|выручк|доход|оборот)|(?:деньг|денег|выручк|доход|оборот).*(?:прин[её]с|зан[её]с|плат)/iu.test(normalized)) { return unicodeBridgeResolution("customer_revenue_and_payments", "high", "unicode_customer_revenue_bridge_signal_detected"); } if (!hasContractCue && /(?:кто|какие|выведи|покажи|список|самые)/iu.test(normalized) && /(?:список\s+(?:заказчик|клиент|покупател).*за\s+\d{2,4}\s*год|актив.*отвал|ровно\s+один\s+раз|один\s+раз.*пропал|стар(?:ые|ые)?\s+по\s+сотруднич|сотрудничеству\s+кто)/iu.test(normalized)) { return unicodeBridgeResolution("counterparty_activity_lifecycle", "high", "unicode_counterparty_lifecycle_bridge_signal_detected"); } if (!hasContractCue && /(?:кто|какие|выведи|покажи|список|разбей|раздели|самые)/iu.test(normalized) && /(?:заказчик|клиент|покупател|поставщик|контрагент|зак(?!рыт))/iu.test(normalized) && /(?:работал|работают|актив|все\s+время|вообще|регулярн|эпизодич|частот|давно\s+не\s+использ|операционн|разов|один\s+раз|пропал|отвал|сотруднич)/iu.test(normalized)) { return unicodeBridgeResolution("counterparty_activity_lifecycle", "high", "unicode_counterparty_lifecycle_bridge_signal_detected"); } if (/(?:поставщик|vendor|supplier|кому\s+(?:ушло|платили|заплатили)|выплат|исходящ|списан|сгрузил)/iu.test(normalized) && !/(?:аванс.*(?:не\s+)?закрыт|закрыт.*аванс)/iu.test(normalized) && (hasMoneyCue || hasRankingCue || /плат[её]ж|оплат|выплат|outflow|payout|хвост|задержк|проблем/iu.test(normalized))) { return unicodeBridgeResolution(/(?:хвост|задержк|проблем)/iu.test(normalized) ? "list_payables_counterparties" : "supplier_payouts_profile", "high", /(?:хвост|задержк|проблем)/iu.test(normalized) ? "supplier_tail_risk_signal_detected" : "unicode_supplier_payouts_bridge_signal_detected"); } if (!hasContractCue && (/(?:клиент|покупател|заказчик|контрагент|альтернатива|свк)/iu.test(normalized) || hasRankingCue) && (hasMoneyCue || /поступлен|приход|входящ|сделк|бюджет|inflow/iu.test(normalized))) { return unicodeBridgeResolution("customer_revenue_and_payments", "high", "unicode_customer_revenue_bridge_signal_detected"); } if (!hasContractCue && /(?:кто.*(?:деньг|денег|доход|выручк).*(?:прин[её]с|зан[её]с|плат)|(?:жирн|ликвидн).*контрагент.*(?:деньг|денег))/iu.test(normalized)) { return unicodeBridgeResolution("customer_revenue_and_payments", "high", "unicode_customer_revenue_bridge_signal_detected"); } if (/(?:общие\s+обороты|общая\s+выручк|оборот.*за\s+все\s+время|выручк.*за\s+все\s+время)/iu.test(normalized)) { return unicodeBridgeResolution("customer_revenue_and_payments", "high", "unicode_customer_revenue_bridge_signal_detected"); } if (/(?:открыт(?:ые|ая|ый)?\s+задолж|открыт(?:ые|ая|ый)?\s+позици|позици.*по\s+договор|open\s+items?)/iu.test(normalized) && (hasContractCue || hasCounterpartyCue || hasAccountAnchor || /покупател|клиент/iu.test(normalized))) { return unicodeBridgeResolution("open_items_by_counterparty_or_contract", "high", "unicode_open_items_bridge_signal_detected"); } if (hasContractCue && /(?:нескольк(?:ими|о)?\s+договор|контрагент.*нескольк.*договор|какие\s+из\s+договор.*актив)/iu.test(normalized)) { return unicodeBridgeResolution("contract_usage_and_value", "high", "unicode_contract_usage_value_bridge_signal_detected"); } if (hasContractCue && (hasMoneyCue || hasRankingCue || /оборот|бюджет|сумм|стоим|value|amount/iu.test(normalized))) { return unicodeBridgeResolution("contract_usage_and_value", "high", "unicode_contract_usage_value_bridge_signal_detected"); } if (/(?:сальдо.*(?:расход|не\s+совпад)|расход.*сальдо|акт(?:ом|ах)?\s+сверк|плат[её]ж[и]?,?\s+но\s+нет\s+док|документ(?:ы)?\s+есть,?\s+а\s+оплат\s+нет|(?:оплат|плат[её]ж|отгрузк|закрыти[ея]\s+счет)[\p{L}\s,]*\s+без\s+(?:закрыт|документ|подтвержд)|аванс.*давно\s+не\s+закрыт)/iu.test(normalized)) { return unicodeBridgeResolution("list_open_contracts", "high", "unicode_open_contracts_list_bridge_signal_detected"); } if (/(?:долгожител|долго\s+долж|задолженн(?:ост|остям).*(?:давн|долго)|не\s+плат|не\s+оплат|не\s+оплачен|неоплачен|просроч|сроки\s+давно\s+прошл|слишком\s+длинн.*оплат)/iu.test(normalized) && /(?:покупател|клиент|заказ|отгрузк|товар|услуг|задолженн|сальдо|не\s+плат|не\s+оплат|не\s+оплачен|неоплачен|просроч)/iu.test(normalized)) { return unicodeBridgeResolution("list_receivables_counterparties", "high", "receivables_debt_lifecycle_signal_detected"); } if (/(?:сальдо.*(?:расход|не\s+совпад)|расход.*сальдо|акт(?:ом|ах)?\s+сверк|плат[её]ж[и]?,?\s+но\s+нет\s+док|документ(?:ы)?\s+есть,?\s+а\s+оплат\s+нет|(?:оплат|плат[её]ж|отгрузк|закрыти[ея]\s+счет)[\p{L}\s,]*\s+без\s+(?:закрыт|документ|подтвержд)|аванс.*давно\s+не\s+закрыт)/iu.test(normalized)) { return unicodeBridgeResolution("list_open_contracts", "high", "unicode_open_contracts_list_bridge_signal_detected"); } if (/(?:открыт(?:ые|ая|ый)?\s+позици|позици.*по\s+договор|open\s+items?)/iu.test(normalized) && (hasContractCue || hasCounterpartyCue || hasAccountAnchor)) { return unicodeBridgeResolution("open_items_by_counterparty_or_contract", "high", "unicode_open_items_bridge_signal_detected"); } if (hasAccountAnchor && hasDocumentCue && /(?:формир|под\s+остат|раскр(?:ой|ыть|ывай)|остат(?:ок|ком)?\s+по\s+док|documents?\s+forming|docs?\s+forming)/iu.test(normalized)) { return unicodeBridgeResolution("documents_forming_balance", "high", "unicode_documents_forming_balance_bridge_signal_detected"); } if (hasContractCue && hasSpecificContractCue && hasBankCue) { return unicodeBridgeResolution("bank_operations_by_contract", "high", "unicode_bank_ops_by_contract_bridge_signal_detected"); } if (hasContractCue && hasSpecificContractCue && hasDocumentCue) { return unicodeBridgeResolution("list_documents_by_contract", "high", "unicode_documents_by_contract_bridge_signal_detected"); } if (hasAccountAnchor && !hasDocumentCue && /(?:баланс|остат(?:ок)?|сальдо|что\s+на\s+сч(?:е|ё)те|по\s+сч(?:е|ё)ту|скольк|скока|account\s+balance|balance\s+account|as\s+of)/iu.test(normalized)) { return unicodeBridgeResolution("account_balance_snapshot", "high", "unicode_account_balance_bridge_signal_detected"); } if (/(?:ндс|vat)/iu.test(normalized)) { const hasVatDebtCue = /(?:долг|должн|подтвержд)/iu.test(normalized); const hasTaxPeriodCue = /(?:налогов|налоговую|бюджет|декларац|квартал|\b[1-4]\s*кв)/iu.test(normalized); const hasVatMonthPeriodCue = /(?:за|на|в)\s+(?:январ|феврал|март|апрел|ма[йя]|июн|июл|август|сентябр|октябр|ноябр|декабр)\S*(?:\s+(?:19|20)\d{2})?/iu.test(normalized) && !/\b\d{1,2}\s+(?:январ|феврал|март|апрел|ма[йя]|июн|июл|август|сентябр|октябр|ноябр|декабр)\S*(?:\s+(?:19|20)\d{2})?/iu.test(normalized); if ((hasTaxPeriodCue || (hasVatMonthPeriodCue && !hasVatDebtCue)) && /(?:скольк|скока|надо|нужно|заплат|уплат|оплат|прикин)/iu.test(normalized)) { return unicodeBridgeResolution("vat_liability_confirmed_for_tax_period", "high", "vat_liability_confirmed_tax_period_signal_detected"); } if (/(?:прогноз|прикин|план)/iu.test(normalized) || (!hasVatDebtCue && /(?:надо|нужно)\s+(?:заплат|оплат|уплат)/iu.test(normalized))) { return unicodeBridgeResolution("vat_payable_forecast", "high", "forecast_tax_signal_detected"); } if (/(?:долг|подтвержд|скольк|скока|надо|нужно|заплат|уплат|оплат)/iu.test(normalized)) { return unicodeBridgeResolution(hasTaxPeriodCue ? "vat_liability_confirmed_for_tax_period" : "vat_payable_confirmed_as_of_date", "high", "vat_payable_confirmed_signal_detected"); } } if (/(?:незакрыт|открыт).*договор/iu.test(normalized) && !/(?:долг|задолж|хвост|висит|расчет|расчёт)/iu.test(normalized)) { return unicodeBridgeResolution("open_contracts_confirmed_as_of_date", "high", "unicode_open_contracts_snapshot_bridge_signal_detected"); } if (/(?:долг|задолж|хвост|висит|открыт(?:ые|ая|ый)?\s+задолж|open\s+items?)/iu.test(normalized) && (hasContractCue || hasCounterpartyCue || hasAccountAnchor || /покупател|клиент/iu.test(normalized))) { return unicodeBridgeResolution("open_items_by_counterparty_or_contract", "high", "unicode_open_items_bridge_signal_detected"); } if (hasContractCue && /(?:без\s+(?:закрыт|оплат|плат[её]ж|док)|не\s+закрыт|аванс|отгрузк|плат[её]ж.*без|док.*без|расхожд|mismatch)/iu.test(normalized)) { return unicodeBridgeResolution("list_open_contracts", "high", "unicode_open_contracts_list_bridge_signal_detected"); } if (hasContractCue && /(?:скольк.*(?:всего\s+)?договор|договор.*(?:заведен|использовал|реально\s+использ)|сколько\s+из\s+них)/iu.test(normalized)) { return unicodeBridgeResolution("contract_usage_overview", "high", "unicode_contract_usage_overview_bridge_signal_detected"); } if (hasContractCue && /(?:нескольк(?:ими|о)?\s+договор|контрагент.*нескольк.*договор|какие\s+из\s+договор.*актив)/iu.test(normalized)) { return unicodeBridgeResolution("contract_usage_and_value", "high", "unicode_contract_usage_value_bridge_signal_detected"); } if (hasContractCue && /(?:все|покажи|показать|какие|список|list|show)/iu.test(normalized) && !hasSpecificContractCue && !hasDocumentCue && !hasBankCue && (hasCounterpartyCue || hasLooseCounterpartyByAnchor)) { return unicodeBridgeResolution("list_contracts_by_counterparty", "high", "unicode_contracts_by_counterparty_bridge_signal_detected"); } if (hasContractCue && !hasSpecificContractCue && !hasDocumentCue && !hasBankCue && hasCounterpartyCue) { return unicodeBridgeResolution("list_contracts_by_counterparty", "high", "unicode_contracts_by_counterparty_bridge_signal_detected"); } if (hasBankCue && (hasCounterpartyCue || hasLooseCounterpartyByAnchor) && !hasContractCue) { return unicodeBridgeResolution("bank_operations_by_counterparty", "high", "unicode_bank_ops_by_counterparty_bridge_signal_detected"); } if (hasDocumentCue && (hasCounterpartyCue || hasLooseCounterpartyByAnchor) && !hasContractCue && !hasAccountAnchor) { return unicodeBridgeResolution("list_documents_by_counterparty", "high", "unicode_documents_by_counterparty_bridge_signal_detected"); } if (/(?:за\s+какие\s+годы|диапазон\s+лет|покрыт(?:ие|ый)\s+период|какой\s+год.*актив|какой\s+месяц.*актив|год.*пассив|месяц.*пассив|минимальн.*док|минимальн.*операц|profile\s+period|top\s*year|top\s*month)/iu.test(normalized)) { return unicodeBridgeResolution("period_coverage_profile", "high", "unicode_period_coverage_bridge_signal_detected"); } if (/(?:тип(?:ы|ов)?\s+док|документ.*(?:чаще|редк|больше\s+всего|меньше\s+всего)|раздел(?:ы|ов)?\s+уч[её]та|сводк.*тип.*док|document\s+type|account\s+section)/iu.test(normalized)) { return unicodeBridgeResolution("document_type_and_account_section_profile", "high", "unicode_document_type_profile_bridge_signal_detected"); } if (/(?:скольк|скока|число|количеств|разбей|раздели|сформируй\s+сводк)/iu.test(normalized) && /(?:контрагент|поставщик|клиент|покупател|заказчик|рол)/iu.test(normalized) && !/(?:активн|давно|нов(?:ые|ых)|однораз|уш[её]л|исчез|регулярн|эпизодич|частот|разов|churn|lifecycle)/iu.test(normalized)) { return unicodeBridgeResolution("counterparty_population_and_roles", "high", "unicode_counterparty_population_bridge_signal_detected"); } if (/(?:скок|скока|сколько)\s+(?:клиент|покупател|заказчик)/iu.test(normalized)) { return unicodeBridgeResolution("counterparty_population_and_roles", "high", "unicode_counterparty_population_bridge_signal_detected"); } if (/(?:активн(?:ые|ость)?\s+(?:клиент|покупател|поставщик|контрагент)|все\s+время|однораз|давно\s+(?:не\s+)?(?:покупал|платил|актив)|уш[её]л|исчез|нов(?:ые|ых)\s+(?:клиент|контрагент)|регулярн|разов(?:ый|ые)|stale\s+supplier|churn|lifecycle)/iu.test(normalized)) { return unicodeBridgeResolution("counterparty_activity_lifecycle", "high", "unicode_counterparty_lifecycle_bridge_signal_detected"); } if (hasContractCue && /(?:давно\s+не\s+использ|не\s+использ|stale|inactive)/iu.test(normalized)) { return unicodeBridgeResolution("contract_usage_overview", "high", "unicode_contract_usage_overview_bridge_signal_detected"); } if (hasContractCue && (hasMoneyCue || hasRankingCue || /оборот|бюджет|сумм|стоим|value|amount/iu.test(normalized))) { return unicodeBridgeResolution("contract_usage_and_value", "high", "unicode_contract_usage_value_bridge_signal_detected"); } if (/(?:поставщик|vendor|supplier|кому\s+(?:ушло|платили|заплатили)|выплат|исходящ|списан|сгрузил)/iu.test(normalized) && (hasMoneyCue || hasRankingCue || /плат[её]ж|оплат|выплат|outflow|payout/iu.test(normalized))) { return unicodeBridgeResolution("supplier_payouts_profile", "high", "unicode_supplier_payouts_bridge_signal_detected"); } if ((/(?:клиент|покупател|заказчик|контрагент|альтернатива|свк)/iu.test(normalized) || hasRankingCue) && (hasMoneyCue || /поступлен|приход|входящ|inflow/iu.test(normalized))) { return unicodeBridgeResolution("customer_revenue_and_payments", "high", "unicode_customer_revenue_bridge_signal_detected"); } if (/(?:к[оа]му\s+мы\s+должны|мы\s+должны\s+к[оа]му|кредитор|payables?)/iu.test(normalized)) { return unicodeBridgeResolution("payables_confirmed_as_of_date", "high", "payables_debt_lifecycle_signal_detected"); } if (/(?:кто\s+нам\s+должен|нам\s+должны|дебитор|receivables?)/iu.test(normalized)) { return unicodeBridgeResolution("receivables_confirmed_as_of_date", "high", "unicode_receivables_snapshot_bridge_signal_detected"); } if (/(?:покупател|клиент).*(?:не\s+плат|просроч|долго\s+долж|долг.*давн)|(?:долг|задолж).*(?:покупател|клиент)/iu.test(normalized)) { return unicodeBridgeResolution("list_receivables_counterparties", "high", "unicode_receivables_list_bridge_signal_detected"); } if (/(?:что|че|чё|какие|покажи|показать|список).*(?:склад|остат|товар)|(?:склад|остат).*(?:сейчас|лежит|есть|на\s+дату|на\s+конец|what|show|list)/iu.test(normalized) && !/(?:поставщик|продаж|реализ|цепоч|документал|давно|стар(?:ые|ый|ым|ых)|закуп)/iu.test(normalized)) { return unicodeBridgeResolution("inventory_on_hand_as_of_date", "high", "unicode_inventory_on_hand_bridge_signal_detected"); } return null; } function resolveAddressIntent(userMessage) { const text = String(userMessage ?? "").trim().toLowerCase(); const repairedText = repairLikelyUtf8Mojibake(text).trim().toLowerCase(); const bridgeText = repairedText && repairedText !== text ? `${text} ${repairedText}` : text; const turnNoiseNormalizedBridgeText = bridgeText .replace(/(^|[^\p{L}0-9_])\u043d\u0430\u043c\u0441(?=$|[^\p{L}0-9_])/giu, "$1\u043d\u0430\u043c") .replace(/(^|[^\p{L}0-9_])\u043a\u0430\u043a\u0438\u0435\u043a(?=$|[^\p{L}0-9_])/giu, "$1\u043a\u0430\u043a\u0438\u0435"); const currentTurnBridgeText = turnNoiseNormalizedBridgeText !== bridgeText ? `${bridgeText} ${turnNoiseNormalizedBridgeText}` : bridgeText; const unicodeAddressIntent = resolveUnicodeAddressIntentBridge(currentTurnBridgeText); if (unicodeAddressIntent) { return unicodeAddressIntent; } const hasLooseVatPayableBridge = /(?:\u043d\u0434\u0441|vat)/iu.test(text) && /(?:\u043a\u0430\u043a\u043e\u0439\s+\u043d\u0434\u0441\s+(?:(?:\u043d\u0430\u043c|(?:\u043c\u044b\s+)?\u0434\u043e\u043b\u0436\u043d\u044b)\s+)?(?:\u043d\u0430\u0434\u043e|\u043d\u0443\u0436\u043d\u043e|\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e)|(?:\u043d\u0430\u043c|\u043c\u044b\s+)?\u043d\u0430\u0434\u043e\s+(?:\u0437\u0430\u043f\u043b\u0430\u0442\u0438\u0442\u044c|\u0441\u0433\u0440\u0443\u0437\u0438\u0442\u044c)|(?:\u043d\u0430\u043c|\u043c\u044b\s+)?\u043d\u0443\u0436\u043d\u043e\s+(?:\u0437\u0430\u043f\u043b\u0430\u0442\u0438\u0442\u044c|\u0441\u0433\u0440\u0443\u0437\u0438\u0442\u044c)|\u043c\u044b\s+\u0434\u043e\u043b\u0436\u043d\u044b\s+(?:\u0437\u0430\u043f\u043b\u0430\u0442\u0438\u0442\u044c|\u0441\u0433\u0440\u0443\u0437\u0438\u0442\u044c)|\u043d\u0434\u0441\s+\u043a\s+\u0443\u043f\u043b\u0430\u0442\u0435)/iu.test(text) && /(?:\u0437\u0430\s+(?:\d{4}|(?:\u044f\u043d\u0432\u0430\u0440|\u0444\u0435\u0432\u0440\u0430\u043b|\u043c\u0430\u0440\u0442|\u0430\u043f\u0440\u0435\u043b|\u043c\u0430[\u0439\u044f]|\u0438\u044e\u043d|\u0438\u044e\u043b|\u0430\u0432\u0433\u0443\u0441\u0442|\u0441\u0435\u043d\u0442\u044f\u0431\u0440|\u043e\u043a\u0442\u044f\u0431\u0440|\u043d\u043e\u044f\u0431\u0440|\u0434\u0435\u043a\u0430\u0431\u0440)\S*(?:\s+(?:19|20)\d{2})?)|\u043d\u0430\s+(?:\u044f\u043d\u0432\u0430\u0440|\u0444\u0435\u0432\u0440\u0430\u043b|\u043c\u0430\u0440\u0442|\u0430\u043f\u0440\u0435\u043b|\u043c\u0430[\u0439\u044f]|\u0438\u044e\u043d|\u0438\u044e\u043b|\u0430\u0432\u0433\u0443\u0441\u0442|\u0441\u0435\u043d\u0442\u044f\u0431\u0440|\u043e\u043a\u0442\u044f\u0431\u0440|\u043d\u043e\u044f\u0431\u0440|\u0434\u0435\u043a\u0430\u0431\u0440)\S*(?:\s+(?:19|20)\d{2})?|\u0432\s+(?:\u044f\u043d\u0432\u0430\u0440|\u0444\u0435\u0432\u0440\u0430\u043b|\u043c\u0430\u0440\u0442|\u0430\u043f\u0440\u0435\u043b|\u043c\u0430[\u0439\u044f]|\u0438\u044e\u043d|\u0438\u044e\u043b|\u0430\u0432\u0433\u0443\u0441\u0442|\u0441\u0435\u043d\u0442\u044f\u0431\u0440|\u043e\u043a\u0442\u044f\u0431\u0440|\u043d\u043e\u044f\u0431\u0440|\u0434\u0435\u043a\u0430\u0431\u0440)\S*(?:\s+(?:19|20)\d{2})?|\b[1-4]\s*(?:\u043a\u0432\u0430\u0440\u0442\u0430\u043b|\u043a\u0432\.?)\b)/iu.test(text); if (hasLooseVatPayableBridge) { return { intent: "vat_liability_confirmed_for_tax_period", confidence: "high", reasons: ["vat_liability_colloquial_bridge_signal_detected"] }; } const hasExplicitReceivablesSnapshotBridge = /(?:\u043d\u0430\u043c\s+\u043a\u0442\u043e-\u0442\u043e\s+\u0434\u043e\u043b\u0436\u0435\u043d|\u043d\u0430\u043c\s+\u043a\u0442\u043e\s+\u0434\u043e\u043b\u0436\u0435\u043d|\u043a\u0442\u043e\s+\u043d\u0430\u043c\s+\u0434\u043e\u043b\u0436\u0435\u043d|\u0435\u0441\u0442\u044c\s+\u043b\u0438\s+\u0434\u0435\u0431\u0438\u0442\u043e\u0440\u0441\u043a\w+\s+\u0437\u0430\u0434\u043e\u043b\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u044c|\u0437\u0430\u0434\u043e\u043b\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u044c\s+\u043d\u0430\u043c|receivables?)/iu.test(currentTurnBridgeText); if (hasExplicitReceivablesSnapshotBridge) { return { intent: "receivables_confirmed_as_of_date", confidence: "high", reasons: currentTurnBridgeText !== bridgeText ? ["receivables_snapshot_bridge_signal_detected", "current_turn_noise_normalized"] : ["receivables_snapshot_bridge_signal_detected"] }; } const hasExplicitPayablesSnapshotBridge = /(?:\u043c\u044b\s+\u0434\u043e\u043b\u0436\u043d\u044b\s+\u043a\u043e\u043c\u0443-\u0442\u043e\s+\u0434\u0435\u043d\u0435\u0433|\u043c\u044b\s+\u0434\u043e\u043b\u0436\u043d\u044b\s+\u043a\u043e\u043c\u0443\u0442\u043e\s+\u0434\u0435\u043d\u0435\u0433|\u043c\u044b\s+\u043a\u043e\u043c\u0443-\u0442\u043e\s+\u0434\u043e\u043b\u0436\u043d\u044b|\u043a\u043e\u043c\u0443\s+\u043c\u044b\s+\u0434\u043e\u043b\u0436\u043d\u044b|\u0435\u0441\u0442\u044c\s+\u043b\u0438\s+\u0437\u0430\u0434\u043e\u043b\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u044c\s+\u043f\u0435\u0440\u0435\u0434\s+\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442\u0430\u043c\u0438|\u0437\u0430\u0434\u043e\u043b\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u044c\s+\u043f\u0435\u0440\u0435\u0434\s+\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442\u0430\u043c\u0438|payables?)/iu.test(currentTurnBridgeText); if (hasExplicitPayablesSnapshotBridge) { return { intent: "payables_confirmed_as_of_date", confidence: "high", reasons: currentTurnBridgeText !== bridgeText ? ["payables_snapshot_bridge_signal_detected", "current_turn_noise_normalized"] : ["payables_snapshot_bridge_signal_detected"] }; } const hasDirectInventoryAgingBridge = /(?:\u043e\u0447\u0435\u043d\u044c\s+\u0434\u0430\u0432\u043d\u043e|\u0434\u0430\u0432\u043d\u043e\s+\u043a\u0443\u043f\u043b|\u0434\u0430\u0432\u043d\u043e\s+\u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0442|\u0441\u0442\u0430\u0440(?:\u044b\u0435|\u044b\u043c|\u044b\u0445)?\s+\u0437\u0430\u043a\u0443\u043f|\u0441\u0442\u0430\u0440(?:\u044b\u0439|\u0430\u044f|\u043e\u0435)?\s+\u0442\u043e\u0432\u0430\u0440|\u0437\u0430\u043a\u0443\u043f\u043b\u0435\u043d(?:\u043d\u044b\u0435|\u043d\u044b\u043c|\u043d\u044b\u0445|\u0430\u044f|\u044b\u0439)?\s+\u0437\u0430\u0434\u043e\u043b\u0433\u043e\s+\u0434\u043e|\u0437\u0430\u0434\u043e\u043b\u0433\u043e\s+\u0434\u043e|old\s+stock|old\s+purchase|very\s+old\s+stock|aging\s+by\s+purchase\s+date)/iu.test(bridgeText); if (hasDirectInventoryAgingBridge || hasInventoryAgingSignal(text) || hasInventoryAgingSignal(repairedText)) { return { intent: "inventory_aging_by_purchase_date", confidence: "high", reasons: ["inventory_aging_bridge_signal_detected"] }; } const hasDirectRevenueAggregateBridge = /(?:\u0441\u0430\u043c(?:\u044b\u0439|\u0430\u044f|\u043e\u0435)?\s+\u0434\u043e\u0445\u043e\u0434\u043d(?:\u044b\u0439|\u0430\u044f|\u043e\u0435|\u044b\u0435|\u043e\u0433\u043e|\u043e\u043c\u0443|\u044b\u043c|\u044b\u0445)?\s+\u043a\u043b\u0438\u0435\u043d\u0442|(?:\u043a\u0430\u043a\u043e\u0439|\u043a\u0430\u043a\u0430\u044f)\s+(?:\u0443\s+\u043d\u0430\u0441\s+)?\u0441\u0430\u043c(?:\u044b\u0439|\u0430\u044f|\u043e\u0435)?\s+\u0434\u043e\u0445\u043e\u0434\u043d(?:\u044b\u0439|\u0430\u044f|\u043e\u0435|\u044b\u0435|\u043e\u0433\u043e|\u043e\u043c\u0443|\u044b\u043c|\u044b\u0445)?\s+\u0433\u043e\u0434|(?:\u0441\u043a\u043e\u043b\u044c\u043a\u043e|\u0441\u043a\u043e\u043a).*(?:\u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438|\u0432\u044b\u0440\u0443\u0447\u0438\u043b\u0438)|\u0432\u044b\u0440\u0443\u0447\u043a\u0430\s+\u0437\u0430\s+\d{4})/iu.test(bridgeText); const hasSpecificCounterpartyRevenueBridge = [text, repairedText, turnNoiseNormalizedBridgeText, currentTurnBridgeText].some((sample) => hasSpecificCounterpartyRevenueBridgeSignal(sample)); if (hasDirectRevenueAggregateBridge || hasCustomerRevenueRankingBridgeSignal(bridgeText) || hasSpecificCounterpartyRevenueBridge) { return { intent: "customer_revenue_and_payments", confidence: "medium", reasons: [ hasSpecificCounterpartyRevenueBridge ? "specific_counterparty_revenue_bridge_signal_detected" : "customer_revenue_ranking_bridge_signal_detected" ] }; } const hasHistoricalInventorySnapshotBridge = [text, repairedText, bridgeText].some((sample) => /(?:\u043e\u0441\u0442\u0430\u0442|inventory|stock|\u0441\u043a\u043b\u0430\u0434|остат|склад)/iu.test(sample) && /(?:(?:\u043d\u0430|\u0437\u0430|РЅР°|Р·Р°)\s+(?:\u044f\u043d\u0432\u0430\u0440|\u0444\u0435\u0432\u0440\u0430\u043b|\u043c\u0430\u0440\u0442|\u0430\u043f\u0440\u0435\u043b|\u043c\u0430[\u0439\u044f]|\u0438\u044e\u043d|\u0438\u044e\u043b|\u0430\u0432\u0433\u0443\u0441\u0442|\u0441\u0435\u043d\u0442\u044f\u0431\u0440|\u043e\u043a\u0442\u044f\u0431\u0440|\u043d\u043e\u044f\u0431\u0440|\u0434\u0435\u043a\u0430\u0431\u0440|март|апрел|май|РёСЋРЅ|РёСЋР»|август|сентябр|октябр|РЅРѕСЏР±СЂ|декабр)\S*(?:\s+(?:19|20)\d{2})?|(?:\u043d\u0430|\u0437\u0430|РЅР°|Р·Р°)\s+\d{4}|\b(?:19|20)\d{2}\b)/iu.test(sample)); if (hasHistoricalInventorySnapshotBridge) { return { intent: "inventory_on_hand_as_of_date", confidence: "medium", reasons: ["inventory_historical_snapshot_bridge_signal_detected"] }; } if (hasInventoryDocumentaryChainBridgeSignal(text)) { return { intent: "inventory_purchase_to_sale_chain", confidence: "medium", reasons: ["inventory_documentary_chain_bridge_signal_detected"] }; } if (hasInventoryProvenanceBridgeSignal(text)) { return { intent: "inventory_purchase_provenance_for_item", confidence: "medium", reasons: ["inventory_provenance_bridge_signal_detected"] }; } if (hasColloquialInventoryOnHandBridgeSignal(text)) { return { intent: "inventory_on_hand_as_of_date", confidence: "medium", reasons: ["inventory_on_hand_colloquial_bridge_signal_detected"] }; } if (hasVatLiabilityConfirmedTaxPeriodSignal(text)) { return { intent: "vat_liability_confirmed_for_tax_period", confidence: "high", reasons: ["vat_liability_confirmed_tax_period_signal_detected"] }; } if (hasForecastTaxSignal(text)) { return { intent: "vat_payable_forecast", confidence: "high", reasons: ["forecast_tax_signal_detected"] }; } if (hasVatPayableConfirmedSignal(text)) { return { intent: "vat_payable_confirmed_as_of_date", confidence: "high", reasons: ["vat_payable_confirmed_signal_detected"] }; } if (hasAny(text, RECEIVABLES_STRONG) || hasFlexibleReceivablesDebtSignal(text)) { const receivablesDebtLifecycleSignal = hasReceivablesDebtLifecycleSignal(text) || hasFlexibleReceivablesDebtSignal(text); const reasons = ["receivables_signal_detected"]; if (receivablesDebtLifecycleSignal) { reasons.push("receivables_debt_lifecycle_signal_detected"); if (hasFlexibleReceivablesDebtSignal(text)) { reasons.push("receivables_signal_detected_flexible_phrase"); } } return { intent: receivablesDebtLifecycleSignal ? "receivables_confirmed_as_of_date" : "list_receivables_counterparties", confidence: "high", reasons }; } if (hasAny(text, PAYABLES_STRONG) || hasFlexiblePayablesDebtSignal(text)) { const reasons = ["payables_signal_detected"]; const payablesDebtLifecycleSignal = hasPayablesDebtLifecycleSignal(text) || hasFlexiblePayablesDebtSignal(text); if (payablesDebtLifecycleSignal) { reasons.push("payables_debt_lifecycle_signal_detected"); if (hasFlexiblePayablesDebtSignal(text)) { reasons.push("payables_signal_detected_flexible_phrase"); } } return { intent: payablesDebtLifecycleSignal ? "payables_confirmed_as_of_date" : "list_payables_counterparties", confidence: "high", reasons }; } if (hasSettlementGapSignal(text)) { return { intent: "list_open_contracts", confidence: "medium", reasons: ["settlement_gap_signal_detected"] }; } if (hasReconciliationMismatchSignal(text)) { return { intent: "list_open_contracts", confidence: "medium", reasons: ["reconciliation_mismatch_signal_detected"] }; } if (hasReceivablesLatencyRiskSignal(text)) { return { intent: "list_receivables_counterparties", confidence: "medium", reasons: ["receivables_payment_lag_signal_detected"] }; } if (hasCounterpartyDebtLongevitySignal(text)) { return { intent: "list_receivables_counterparties", confidence: "medium", reasons: ["receivables_debt_lifecycle_signal_detected"] }; } if (hasSupplierTailRiskSignal(text)) { return { intent: "list_payables_counterparties", confidence: "medium", reasons: ["supplier_tail_risk_signal_detected", "payables_debt_lifecycle_signal_detected"] }; } if (hasDocumentsFormingBalanceSignal(text) && hasDocumentsFormingBalanceAccountAnchor(text)) { return { intent: "documents_forming_balance", confidence: "high", reasons: ["documents_forming_balance_signal_detected"] }; } if (hasDocumentsByAccountDrilldownSignal(text)) { return { intent: "documents_forming_balance", confidence: "medium", reasons: ["documents_by_account_drilldown_signal_detected"] }; } const inventoryIntent = (0, addressInventoryIntentSignals_1.resolveInventoryAddressIntent)(text); if (inventoryIntent) { return inventoryIntent; } const counterpartyIntent = (0, addressCounterpartyIntentSignals_1.resolveCounterpartyAddressIntent)(text, { hasAny, openItemsHints: OPEN_ITEMS_HINTS, openContractsHints: OPEN_CONTRACTS_HINTS, documentsByCounterpartyHints: DOCUMENTS_BY_COUNTERPARTY_HINTS, bankOperationsByCounterpartyHints: BANK_OPERATIONS_BY_COUNTERPARTY_HINTS, documentsByContractHints: DOCUMENTS_BY_CONTRACT_HINTS, hasCounterpartyDebtLongevitySignal, hasInventoryAgingSignal, hasInventoryProvenanceSignalV2, hasInventoryPurchaseDocumentsSignalV2, hasInventorySaleTraceSignalV2, hasAccountNumberAnchor, hasCompactAccountCodeToken, hasPeriodCoverageProfileSignal, hasPartyAnchorMention, hasContractAnchorSignal, hasAccountBalanceSignal, hasDocumentTypeAndAccountSectionProfileSignal, hasCounterpartyPopulationAndRolesSignal, hasCounterpartyActivityLifecycleSignal, hasContractUsageOverviewSignal, hasOpenContractsListSignal, hasCustomerRevenueAndPaymentsSignal, hasSupplierPayoutsProfileSignal, hasContractUsageAndValueSignal, hasContractListByCounterpartySignal, hasBankOperationSignal, hasDocumentSignal, hasLooseByAnchorMention, hasHeuristicCounterpartyAnchor, hasCounterpartyShipmentItemFlowSignal, hasImplicitCounterpartyAnchorAroundDocs, hasGenericAddressLookupSignal }); if (counterpartyIntent) { return counterpartyIntent; } return { intent: "unknown", confidence: "low", reasons: ["intent_not_supported_in_v1"] }; }