setOpen(false)} />}
);
}
// -- HERO -----------------------------------------------------
function Hero({ children, direction }) {
return (
v3 · API очистки адресов
Адреса{" "}
под ключ
для ваших форм{" "}
и баз.
Подсказки по ФИАС, нормализация, геокодинг и обратное преобразование координат —
одной строкой кода. SDK для шести языков, бесплатные 10 000 запросов в день.
28 мс
медиана ответа
1.7 М
населённых пунктов
10 000
запросов/сутки бесплатно
{children}
);
}
// -- SAGGEST WIDGET -------------------------------------------
function Saggest({ onSelect }) {
const { ADDRESSES } = window.__DATA;
const [q, setQ] = useState("тверская 12");
const [active, setActive] = useState(0);
const [focus, setFocus] = useState(false);
const matches = useMemo(() => {
if (!q.trim()) return ADDRESSES.slice(0, 5);
const lower = q.toLowerCase();
const scored = ADDRESSES.map((a) => {
const t = a.full.toLowerCase();
let score = 0;
lower.split(/\s+/).forEach((tok) => {
if (tok && t.includes(tok)) score += 10 + tok.length;
});
if (t.startsWith(lower)) score += 30;
return { a, score };
});
return scored
.filter((s) => s.score > 0)
.sort((x, y) => y.score - x.score)
.slice(0, 5)
.map((s) => s.a);
}, [q]);
useEffect(() => { setActive(0); }, [q]);
function highlight(text) {
if (!q.trim()) return text;
const toks = q.toLowerCase().split(/\s+/).filter(Boolean);
let parts = [{ t: text, hl: false }];
toks.forEach((tok) => {
const next = [];
parts.forEach((p) => {
if (p.hl) { next.push(p); return; }
const idx = p.t.toLowerCase().indexOf(tok);
if (idx === -1) { next.push(p); return; }
next.push({ t: p.t.slice(0, idx), hl: false });
next.push({ t: p.t.slice(idx, idx + tok.length), hl: true });
next.push({ t: p.t.slice(idx + tok.length), hl: false });
});
parts = next;
});
return parts.map((p, i) => p.hl ?
{p.t} :
{p.t});
}
return (
{matches.length === 0 && (
// нет совпадений · попробуйте другой запрос
)}
{matches.map((a, i) => (
setActive(i)}
onClick={() => { setQ(a.full); onSelect && onSelect(a); }}
>
{String(i + 1).padStart(2, "0")}
{highlight(a.full)}
{a.postal} · {a.fias.slice(0, 18)} · {a.lat.toFixed(4)}, {a.lon.toFixed(4)}
))}
↑ ↓ навигация
{" "}
↵ выбор
{matches.length} результат(ов) · 14 мс
);
}
// -- API CODE BLOCK (moved to api-block.jsx) --------------------
function ApiBlockLegacy_UNUSED() {
const { CODE_SAMPLES } = window.__DATA;
const [tab, setTab] = useState("curl");
const [copied, setCopied] = useState(false);
const tabs = [
{ k: "curl", l: "cURL" },
{ k: "js", l: "Node.js" },
{ k: "python", l: "Python" },
{ k: "go", l: "Go" },
];
const lines = CODE_SAMPLES[tab];
function copy() {
setCopied(true);
setTimeout(() => setCopied(false), 1400);
}
return (
{tabs.map((t) => (
))}
{lines.map((ln, i) => (
{ln.c && {ln.c}}
{ln.t}
{ln.end && {ln.end}}
))}
Ответ · 200 OK
↘ 14 мс
{"{"}
"suggestions": [
{"{"}
"value": "г Москва, ул Тверская, д 12 стр 9",
"unrestricted": "125009, г Москва, ул Тверская, д 12 стр 9",
"data": {"{"}
"postal_code": "125009",
"region": "Москва",
"city": "Москва",
"street": "Тверская",
"house": "12 стр 9",
"fias_id": "8da95206-5d3a-...",
"geo_lat": 55.7616,
"geo_lon": 37.6062,
"qc": 0 // точность: дом
{"}"}
{"}"}
]
{"}"}
);
}
// -- MAP / GEO (moved to map-block.jsx) -----------------------
function MapBlockLegacy_UNUSED() {
const { MAP_PINS } = window.__DATA;
const [active, setActive] = useState(MAP_PINS[1]);
const [mouse, setMouse] = useState({ x: 50, y: 50, lat: 55.7558, lon: 37.6173 });
const canvasRef = useRef(null);
function onMove(e) {
const r = canvasRef.current.getBoundingClientRect();
const x = ((e.clientX - r.left) / r.width) * 100;
const y = ((e.clientY - r.top) / r.height) * 100;
// synthesise lat/lon from x,y (just for display)
const lat = 65 - (y / 100) * 25;
const lon = 30 + (x / 100) * 110;
setMouse({ x, y, lat, lon });
}
const a = active.addr;
return (
{/* stylised russia silhouette */}
{MAP_PINS.map((p) => (
))}
курсор: {mouse.lat.toFixed(4)}, {mouse.lon.toFixed(4)}
{" "}
· ↓ POST /v1/geocode/reverse
→ Точка {active.label} · обратный геокодинг
{a.full}
Широта
{a.lat.toFixed(6)}
Долгота
{a.lon.toFixed(6)}
);
}
// -- FEATURES -------------------------------------------------
function FeatureIcon({ kind }) {
const props = { width: 22, height: 22, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.6 };
switch (kind) {
case "suggest":
return
;
case "geocode":
return
;
case "reverse":
return
;
case "norm":
return
;
case "hier":
return
;
case "fuzzy":
return
;
case "batch":
return
;
case "fias":
return
;
case "sla":
return
;
default: return null;
}
}
function FeaturesLegacy_UNUSED() {
const items = [
{ k: "suggest", t: "Подсказки на лету", d: "Авто-дополнение от региона до квартиры, разрезано на токены и нормализовано. До 25 подсказок за 14 мс.", tag: "/suggest" },
{ k: "geocode", t: "Прямой геокодинг", d: "Адрес → координаты с точностью до подъезда. Покрытие 1.7 М населённых пунктов РФ.", tag: "/geocode" },
{ k: "reverse", t: "Обратный геокодинг", d: "Координаты → структурированный адрес ФИАС. Возвращаем 32 поля включая ОКАТО, ОКТМО, индекс.", tag: "/reverse" },
{ k: "norm", t: "Нормализация ФИАС", d: "Распарсенные части адреса: регион, город, улица, дом, квартира. Сокращения по ФИАС.", tag: "/parse" },
{ k: "fuzzy", t: "Поиск с опечатками", d: "Fuzzy-матчинг по двойной метафонии. \"Тверска 12\" найдёт Тверскую без проблем.", tag: "/fuzzy" },
{ k: "fias", t: "Актуальные базы", d: "Ежесуточная синхронизация с ФИАС, КЛАДР, ЕГРЮЛ. Гарантия свежести данных.", tag: "ФИАС/КЛАДР" },
{ k: "batch", t: "Пакетная обработка", d: "До 50 000 адресов за один батч-запрос, CSV/JSONL на входе и выходе.", tag: "/batch" },
{ k: "hier", t: "Дерево адресов", d: "Иерархия от субъекта РФ до квартиры. Удобно для каталогов и отчётности.", tag: "/tree" },
{ k: "sla", t: "SLA 99.99%", d: "Два дата-центра в Москве и Питере, гео-резервирование, мониторинг 24/7.", tag: "SLA" },
];
return (
{items.map((it, i) => (
))}
);
}
// -- STATS ----------------------------------------------------
function Stats() {
const items = [
{ num: "28", unit: "мс", label: "медианное время ответа" },
{ num: "1.7", unit: "М", label: "населённых пунктов" },
{ num: "99.99", unit: "%", label: "годовая доступность" },
{ num: "240", unit: "млрд", label: "запросов обработано" },
];
return (
{items.map((s, i) => (
{s.num}{s.unit}
{s.label}
))}
);
}
// -- MARQUEE --------------------------------------------------
function Marquee() {
const words = ["ФИАС", "КЛАДР", "ЕГРЮЛ", "Геокодинг", "Suggest", "Нормализация", "Batch", "Webhooks", "SDK"];
const items = [...words, ...words];
return (
{items.map((w, i) =>
{w}
)}
);
}
// -- PRICING (replaced by calculator.jsx) ---------------------
function PricingLegacy_UNUSED() {
const tiers = [
{
name: "Старт",
price: "0",
per: "₽/мес",
meta: "Для пет-проектов и проверки гипотез",
cta: "Создать ключ",
feats: [
"10 000 запросов в сутки",
"Подсказки + нормализация",
"Прямой и обратный геокодинг",
"SDK для всех языков",
"Только публичный rate-limit",
],
},
{
name: "Прод",
price: "9 800",
per: "₽/мес",
meta: "Боевой продакшен · оплата помесячно",
popular: true,
cta: "Подключить тариф",
feats: [
"500 000 запросов в сутки",
"SLA 99.95%, ответ < 50 мс",
"Пакетная обработка batch",
"Webhooks и стриминг",
"Поддержка в Telegram · 4 ч",
],
},
{
name: "Энтерпрайз",
price: "по запросу",
per: "",
meta: "Свой контур, банки и госсектор",
cta: "Связаться",
feats: [
"On-premise установка",
"Персональный SLA до 99.99%",
"Юр.лицо РФ · договор · акты",
"Выделенный аккаунт-менеджер",
"Аудит ИБ и пентест",
],
},
];
return (
{tiers.map((t, i) => (
{t.popular &&
★ выбор большинства
}
{t.name}
{t.price === "по запросу" ? (
по запросу
) : (
<>
{t.price}
{t.per}
>
)}
{t.meta}
{t.feats.map((f, j) => - {f}
)}
))}
);
}
// -- USE CASES (removed) --------------------------------------
function UseCasesLegacy_UNUSED() {
const cases = [
{ n: "01", t: "E-commerce и доставка", d: "Подсказки при оформлении заказа сокращают долю неверных адресов на 78%. Меньше брошенных корзин, меньше возвратов с курьерами." },
{ n: "02", t: "Финтех и КYC", d: "Нормализация под ФИАС, валидация паспортных регионов, готовая выгрузка для отчётности в ЦБ. Соответствие 115-ФЗ из коробки." },
{ n: "03", t: "CRM и аналитика", d: "Геокодирование клиентской базы для тепловых карт и сегментации. Иерархия адресов для отчётов по регионам и федеральным округам." },
{ n: "04", t: "Госуслуги и подряд", d: "On-premise установка, контур без интернета, выгрузка ФИАС внутри периметра. Опыт интеграций с госсектором и муниципалитетами." },
];
return (
{cases.map((c, i) => (
))}
);
}
// -- CTA ------------------------------------------------------
function Cta() {
return (
ОТКРЫТЬ ПЕСОЧНИЦУ
API уже работает.
Подключите за 4 минуты.
Бесплатные 10 000 запросов в сутки. Карта не нужна. Откройте ключ — и начинайте парсить адреса прямо из терминала.
);
}
// -- FOOTER ---------------------------------------------------
function Footer() {
return (
);
}
Object.assign(window, {
Nav, Hero, Saggest, Stats, Marquee, Cta, Footer, LogoMark,
});