Below is a conversation between the user and the assistant. Give a concise name for this chat. Output ONLY the name of the chat (WITHOUT quotes) and NOTHING else.

User: ---
File: /Users/alexeykotomin/node_modules/lsd/node_modules/dictionary-search/server/index.js

// server/index.js
const express = require("express");
const fetch = require("node-fetch");
const cheerio = require("cheerio");
const TurndownService = require("turndown");
const LRU = require("lru-cache");

// Настройка сервера
const app = express();
const PORT = process.env.PORT || 3000;

// Инициализация Turndown для конвертации HTML в Markdown
const turndownService = new TurndownService({
  headingStyle: "atx",
  codeBlockStyle: "fenced",
});

// Простое локальное кеширование в памяти (можно заменить на redis или файловый кеш)
const cache = new LRU.LRUCache({
  max: 500,           // макс. количество элементов
  ttl: 1000 * 60 * 30 // время жизни кеша - 30 минут
});

app.get("/search", async (req, res) => {
  const queryRaw = req.query.q?.trim();
  if (!queryRaw) {
    return res.status(400).json({ error: "Query parameter 'q' is required" });
  }

  // Кешируем по районированному ключу
  const cacheKey = queryRaw.toLowerCase();
  if (cache.has(cacheKey)) {
    return res.json(cache.get(cacheKey));
  }

  try {
    const searchUrl = `https://lsj.gr/index.php?search=${encodeURIComponent(queryRaw)}&title=Special%3ASearch`;

    const response = await fetch(searchUrl, {
      headers: {
        "User-Agent": "Mozilla/5.0 (compatible; RaycastBot/1.0)",
        "Accept-Language": "en-US,en;q=0.9",
      },
    });

    if (!response.ok) {
      return res.status(response.status).json({ error: `Server returned ${response.status}` });
    }

    const html = await response.text();

    const $ = cheerio.load(html);

    // Если есть результаты поиска
    if ($(".mw-search-results").length > 0) {
      const results = [];
      $(".mw-search-result").each((i, el) => {
        const heading = $(el).find(".mw-search-result-heading a");
        if (!heading.length) return;

        results.push({
          title: heading.text().trim(),
          url: "https://lsj.gr" + heading.attr("href"),
          description: $(el).find(".searchresult").text().trim(),
        });
      });

      const resultJson = { query: queryRaw, type: "search", results };
      cache.set(cacheKey, resultJson);
      return res.json(resultJson);
    }

    // Если статья с заголовком

    if ($("#firstHeading").length > 0) {
      const title = $("#firstHeading").text().trim();

      // Берём весь HTML содержимого статьи
      let contentHtml = $("#mw-content-text").html() || "";

      // Обрабатываем все ссылки в тексте (произвольные внутренние или внешние)
      const $content = cheerio.load(contentHtml);
      $content("a").each((i, el) => {
        const href = $content(el).attr("href");
        if (href) {
          if (href.startsWith("/wiki/")) {
            // Преобразуем внутренние ссылки в полные URL и добавляем target="_blank"
            $content(el).attr("href", `https://lsj.gr${href}`);
            $content(el).attr("target", "_blank");
          } else if (href.startsWith("#")) {
            // Якорные ссылки оставляем, добавлять ничего не нужно
          } else if (!href.startsWith("http")) {
            // Относительные ссылки - если есть, превращаем в абсолютные тоже
            $content(el).attr("href", `https://lsj.gr${href}`);
            $content(el).attr("target", "_blank");
          } else {
            // Внешние ссылки - просто открываем в новой вкладке
            $content(el).attr("target", "_blank");
          }
        }
      });
      contentHtml = $content.html();

      // Конвертируем HTML статьи в Markdown для удобного рендера в Raycast
      const contentMarkdown = turndownService.turndown(contentHtml);

      // Сниппет из Markdown (первые 800 символов)
      const snippet = contentMarkdown.substring(0, 800) + (contentMarkdown.length > 800 ? "…" : "");

      // Парсим оглавление
      const tocItems = [];
      $("#toc li.toclevel-1 a").each((i, el) => {
        const anchor = $(el);
        tocItems.push({
          n...