Перейти к содержимому

Справочник elide.pkl

Все блоки и поля манифеста проекта Elide elide.pkl: метаданные, исходники, зависимости, JVM, Kotlin, JavaScript, артефакты, тестирование и рабочие пространства.

На этой странице

elide.pkl — манифест проекта: в нём объявляются сборки, зависимости, тесты и артефакты. Каждый файл начинается так:

amends "elide:project.pkl"

elide: указывает на схему, встроенную в запущенный Elide, для этого и всех остальных модулей (elide:Jvm.pkl). Чтобы закрепить версию схемы, расширяйте схему по опубликованному URL: pkl.elide.dev/1.6.0/project.pkl.

Версия в разработке следует за main до стабильного выпуска. Выпущенные версии схемы неизменяемы.

Патч-выпуски в пределах линии MAJOR.MINOR только добавляют свойства. Минорный выпуск может удалять, переименовывать свойства, менять их тип и значения по умолчанию.

Закреплённая версияРезультат
Старше запущенного ElideИспользуется эта версия; свойство, удалённое позже, вызывает ошибку с указанием версии.
Новее запущенного ElideДопускается; свойство, которого нет в запущенном Elide, вызывает ошибку с указанием нужного обновления.
Другая мажорная версияОтклоняется.

elide project export выводит вычисленный манифест в JSON; elide build --inspect перечисляет его задачи.

Метаданные проекта

СвойствоНазначение
name, version, descriptionИдентификация проекта; version также входит в имена архивов приложений.
entrypointФайл(ы), которые elide run использует, если ничего не передано.
scriptsИменованные shell-команды для elide run NAME.
sourcesНаборы исходников; см. Исходники.
dependenciesПакеты Maven, npm и PyPI; см. Зависимости.
jvm, kotlin, javascriptНастройки языков и компиляторов.
nativeImageПринимается, но не применяется; задавайте options каждого артефакта.
engineКонтексты для обслуживания запросов; см. Контексты движка.
toolchainДопустимые версии Elide; см. Инструментарий.
devСведения об исходниках, MCP, сервер разработки; см. Разработка.
webНастройки веб-ресурсов; см. Веб.
artifactsРезультаты сборки; см. Артефакты.
testingОтчёты о тестах; см. Тестирование.
coverageПокрытие; см. Тестирование › Покрытие.
workspaceПроекты-участники; см. Рабочие пространства.

build.flags содержит значения -f/--flag; см. Флаги сборки.

Контексты движка

engine {
  topology = "prespawn"
  contexts { spawn = "auto"; reserve = 2; min = 1; max = 16 }
}
СвойствоОписаниеПо умолчанию
topology"prespawn", единственное значение."prespawn"
contexts.spawnЧисло контекстов: положительное целое или "auto" (физические ядра минус reserve, в пределах границ).1
contexts.reserveЯдра, вычитаемые для "auto"; к процессорам не привязывает.2
contexts.min, contexts.maxГраницы для любого числа.1, нет
maxContextsУстаревшее фиксированное число; нельзя сочетать с contexts.—

Каждый контекст один раз вычисляет входной модуль со своими глобальными объектами, прежде чем сервер станет готов. --contexts=N|auto у run, serve и dev переопределяет spawn. Больше одного контекста — только в Linux.

Блок OpenTelemetry

opentelemetry {
  service { name = "checkout"; version = "1.4.2"; environment = "production" }
  resource { ["cloud.region"] = "us-east-1" }

  destinations {
    ["collector"] { endpoint = "http://localhost:4317"; protocol = "grpc" }
    ["datadog"] { provider = "datadog"; site = "us5" }
    ["sentry"] { provider = "sentry" }
  }

  traces { sampler = "parentbased_traceidratio"; ratio = 0.25 }
  metrics { interval = 30.s }
  logs { level = "info" }
  runtime { logs = "warn" }
}

Телеметрия выключена, пока не задано место назначения: здесь, в переменных OTEL_*/ELIDE_OTEL_* или во флагах --otel-*. Они переопределяют этот блок, причём флаги важнее всего; см. Переменные окружения среды выполнения. elide run, elide serve, elide test, elide build и elide install в проекте читают этот блок; elide run file.js внутри проекта читает его, если elide.pkl содержит слово opentelemetry. См. Конфигурация. Учётные данные здесь не записываются: укажите переменную окружения, в которой они хранятся.

СвойствоОписаниеПо умолчанию
enabledfalse выключает телеметрию независимо от окружения.—
service.name, .version, .namespace, .environmentАтрибуты ресурса service.* и deployment.environment.name.unknown_service:elide
resourceДополнительные атрибуты ресурса.—
destinationsИменованные места назначения телеметрии.нет
traces.enabled, .sampler, .ratio, .propagatorsСпаны приложения. Сэмплеры — как в OTEL_TRACES_SAMPLER.вкл., parentbased_always_on, tracecontext + baggage
metrics.enabled, .interval, .temporalityМетрики приложения.вкл., 60.s, cumulative
logs.enabled, .level, .consoleЛоги приложения; console экспортирует вывод console.*, Python logging и подобный.вкл., info, вкл.
profiles.enabled, .frequencyПрофили CPU гостевого кода (экспериментально).выкл., 100 в секунду
runtime.traces, .metrics, .logsСобственные спаны и метрики Elide и порог его логов.вкл., вкл., warn
propagation.baggageW3C baggage в HTTP-сервере и клиентах Elide; см. Baggage.выкл.
shutdownTimeoutКрайний срок последнего экспорта при завершении.5.s

Каждое место назначения:

СвойствоОписаниеПо умолчанию
providerotlp, sentry, datadog, posthog, honeycomb или grafana.otlp
endpointБазовый URL; заменяет хост провайдера. Для HTTP добавляется /v1/<signal>.http://localhost:4318 (4317 для gRPC)
protocolgrpc, http/protobuf или http/json.http/protobuf
headers, headerEnvЗаголовки в явном виде и заголовки из указанных переменных.—
credentialПеременная с ключом провайдера: DD_API_KEY, POSTHOG_PROJECT_TOKEN, HONEYCOMB_API_KEY, GRAFANA_CLOUD_OTLP_CREDENTIAL.как указано
dsnПеременная с DSN Sentry.SENTRY_DSN
siteСайт Datadog: us1, us3, us5, eu, ap1, ap2, gov или домен.DD_SITE, затем us1
regionus/eu (PostHog, Honeycomb) или зона Grafana Cloud, например prod-us-east-0.us
signalstraces, metrics, logs, profiles.то, что принимает провайдер
compression, timeoutСжатие и крайний срок запроса.gzip, 10.s
perSignalendpoint, protocol, headers, headerEnv, compression, timeout для отдельных сигналов.—
ПровайдерСигналы по умолчаниюТакже принимаютсяПротоколы
otlpтрассировки, метрики, логипрофиливсе
sentryтрассировки, логи—http/protobuf
datadogметрики (delta), логитрассировки (предварительная версия agentless intake)http/protobuf; http/json, кроме логов
posthogлогитрассировкиhttp/protobuf
honeycombтрассировки, метрики, логи—все
grafanaтрассировки, метрики, логи—http/protobuf

Ошибки отправляются как записи логов exception и события спанов, а также как метрика elide.errors, поэтому их получает любой провайдер, который принимает логи, трассировки или метрики. Об использовании см. Обзор OpenTelemetry, о каждом провайдере — Провайдеры. Запросить у провайдера сигнал или протокол, который он не принимает, — ошибка.

Baggage

HTTP-сервер и клиенты Elide передают traceparent и tracestate. W3C baggage они передают, только если вы включите соответствующее направление, потому что baggage от клиента — недоверенные входные данные:

opentelemetry {
  propagation {
    baggage {
      inbound = true
      outbound = true
      allow { "tenant"; "region" }
      spanAttributes { "tenant" }
    }
  }
}
СвойствоОписаниеПо умолчанию
inboundЗаголовки baggage обслуживаемых запросов становятся baggage обработчика.false
outboundИсходящие запросы fetch и HTTP-клиента несут текущий baggage, если запрос сам не задаёт baggage.false
allowКлючи, разрешённые в обоих направлениях.все ключи
spanAttributesВходящие ключи, записываемые в серверный спан как baggage.<key>; каждый должен быть в allow.нет

Заголовок больше 8192 байт или 180 элементов либо с любым некорректным элементом отбрасывается целиком. Baggage от клиента попадает в исходящие запросы, только если включены оба направления. Код приложения всегда может читать, задавать и отправлять baggage через API OpenTelemetry; OTEL_PROPAGATORS влияет только на этот API.

Исходники

sources {
  ["main"] = "lib/**/*.kt"
  ["integrationTest"] {
    type = "test"
    dependsOn { "main" }
    paths { "it/**/*.kt" }
    resources { "it/fixtures"; new { from = "it/config"; into = "META-INF" } }
  }
}
СвойствоОписаниеЕсли пусто или не задано
type"source", "test", "example" или "other".Определяется по имени.
pathsGlob-шаблоны или каталоги.src/<name>/<language>.
resourcesПути или корни new { from; into }.src/<name>/resources.
dependsOnНаборы исходников, видимые этому набору.Не задано: наборы тестов и примеров видят main. Пусто: ничего.

См. Наборы исходников.

Зависимости

dependencies {
  maven {
    packages { "com.google.guava:guava:33.5.0-jre" }
    testPackages { "org.junit.jupiter:junit-jupiter:5.13.4" }
    substitutions { ["com.google.guava:guava"] = "libs/guava-patched.jar" }
  }
  npm { packages { "react@19.0.0" }; devPackages { "typescript@5.6.2" } }
  pypi { packages { "requests>=2" }; optionalPackages { ["dev"] { "pytest>=8" } } }
  spring { version = "4.0.0"; starter { "web" }; testStarter { "test" } }
}
БлокСвойства
mavenpackages, devPackages, modules, compileOnly, runtimeOnly, processors, testPackages, kotlinPlugins, exclusions, substitutions, repositories, enableDefaultRepositories, localRepository
npmpackages, devPackages
pypipackages, optionalPackages (именованные группы); elide install их не устанавливает.
springversion, starter, testStarter; разворачивается в maven.
ЗначениеФорма
Запись Maven"group:artifact:version[:classifier]", MavenPackageSpec (group, name, version, classifier или coordinate), путь к локальному JAR или ссылка на проект.
РепозиторийURL или описание с url, name, description, credentials (username, password, ntlmDomain, ntlmWorkstation).
Ключ substitutionsgroup:artifact (любая версия) или group:artifact:version; значение — путь к файлу.

Подстановка сохраняет транзитивные зависимости координаты и ставит файл вместо неё в каждый classpath. Пути разрешаются относительно объявившего их манифеста; участники наследуют подстановки корня. Задача, которая генерирует файл, должна выполняться раньше. Группы и репозитории: Зависимости.

JVM

jvm {
  main = "example.Main"
  target = 25
  flags { "--add-opens=java.base/java.lang=ALL-UNNAMED" }
  defs { ["app.env"] = "dev" }
  java { release = 25; compiler { flags { "-Xlint:all" } } }
}
СвойствоОписаниеПо умолчанию
mainКласс точки входа для elide run, JAR, приложений и нативных образов.—
targetЦелевой байт-код: 8 … 29, 1.8, "latest", "stable" или "auto"."auto" (21)
javaHomeКаталог Java для внешней компиляции и отдельных процессов JVM.собственный Elide
preferBaliВнешние запуски JVM вызывают bali из PATH вместо java, а без него выводят предупреждение и используют java.false
features.testingЗависимости JUnit в наборах тестов.true
features.automodulesАвтоматические модули для JAR без дескриптора.true
features.graalvmAPI SDK org.graalvm в classpath компиляции.false
java.source, java.releaseУровни исходного кода и --release; см. Компилятор Java."auto"
java.compiler.mode"embedded" или "external"."embedded"
java.compiler.flagsДополнительные флаги javac.нет
java.sourceSetsrelease и flags для отдельных наборов исходников; см. Компилятор Java.нет
flagsФлаги JVM для elide run, тестовой JVM и стартовых скриптов.нет
defsСистемные свойства (-D), применяются везде, где и flags.нет
debugКомпилировать с -g.true

Kotlin

kotlin {
  apiLevel = "auto"
  languageLevel = "auto"
  compilerOptions { allWarningsAsErrors = true; optIn { "kotlin.time.ExperimentalTime" } }
  features { serialization = true; metro = false }
  toolchain = "embedded"
  plugins { ["org.jetbrains.kotlinx.serialization"] { ["mode"] = "json" } }
}
СвойствоОписание
apiLevel, languageLevel"auto", "latest", "stable" или "1.9" … "2.5".
compilerOptionsoptIn, progressiveMode, extraWarnings, allWarningsAsErrors, suppressWarnings, verbose, freeCompilerArgs, apiVersion, languageVersion, includeRuntime, noStdlib, javaParameters, jvmTarget, noJdk, jvmTargetValidationMode, incremental
featurestesting, kotlinx, defaultPlugins, serialization, coroutines, atomicfu, powerAssert, metro, reflection
toolchain"embedded", new Kotlin.ManagedKotlinToolchain { version } или new Kotlin.CustomKotlinToolchain { path }.
pluginsПараметры для каждого id плагина компилятора, передаются как -P plugin:<id>:<key>=<value>.

Значения по умолчанию: Компилятор Kotlin.

JavaScript

СвойствоОписаниеПо умолчанию
javascript.ecmaОбъявленная редакция ECMAScript: год 2015 … 2025, "stable" или "latest". Её показывает elide project info; она не меняет ни выполняемый синтаксис, ни способ сборки кода (Язык JavaScript)."stable"

Инструментарий

toolchain { engines { ["elide"] = ">=1.6.0" } }
СвойствоОписание
engines["elide"]Версия или диапазон semver либо new { version = "…" }; запущенный Elide вне этого диапазона не проходит проверку.
engines[<other>]Принимается, но не проверяется.

Разработка

dev {
  source { platform = "github"; project = "example/app" }
  mcp {
    registerElide = true
    advice = true
    resources { new { path = "docs/ARCHITECTURE.md"; name = "architecture" } }
  }
}
СвойствоОписаниеПо умолчанию
source.platform, source.project, source.subpathХостинг исходников: "github", "gitlab", "bitbucket", "git" или другое имя.—
mcp.registerElideЗарегистрировать Elide как инструмент MCP.true
mcp.adviceПредоставлять elide project advice как ресурс MCP.true
mcp.resourcesДополнительные ресурсы MCP: path, name, description, mimeType (определяется, если не указан).нет
server.host, server.portНе используются в elide dev, который принимает --host/--port (по умолчанию 127.0.0.1:3000)."0.0.0.0", 8080

Веб

СвойствоОписаниеПо умолчанию
web.css.minifyМинифицировать собранный CSS.true
web.css.targetsЦелевые браузеры: new { browser = "chrome"; version = "120" }.нет
web.minifyHtmlМинифицировать отрендеренный HTML.true
web.browsersЦелевые браузеры для всех результатов; для CSS его переопределяет css.targets.нет

См. Веб-инструментарий.

Артефакты

import "elide:Jvm.pkl" as Jvm

artifacts {
  ["app"] = new Jvm.Jar {
    name = "app.jar"
    options { entrypoint = "example.Main" }
    sources { "main" }  // optional; empty packages every non-test source set
  }
}

Ключ задаёт имя задачи сборки. Результаты попадают в .dev/artifacts/<kind>/.

ТипМодульПоля
Jar, SourceJar, JavadocJar, JvmApplicationelide:Jvm.pklСборка JAR
NativeImageelide:NativeImage.pklNative Image
WebImageelide:NativeImage.pklWebImage
ContainerImageelide:Container.pklJVM-контейнеры
StaticSiteelide:Web.pklСтатические сайты
Общее полеОписание
dependsOnИмена артефактов, которые нужно собрать раньше.
name (JAR)И "app", и "app.jar" дают app.jar; SourceJar даёт app-sources.jar.

WebImage

WebImage принимает поля NativeImage from, name, entrypoint, moduleName, dependsOn и options, не имеет type и добавляет:

СвойствоЗначенияПо умолчанию
backend"wasm-gc" (GC хоста) или "wasm-lm" (линейная память)."wasm-gc"
runtime"generic", "browser" или "node"."generic"
autoRunЗапускать программу, когда загрузчик загружен.true
sourceMapСоздавать source map JavaScript.false

entrypoint (или jvm.main) обязателен даже при autoRun = false. Не передавайте сырые флаги для этих четырёх настроек. Руководство: WebImage; артефакты на флагах: миграция.

Публикация

publishing {
  maven {
    groupId = "dev.example"
    artifactId = "example"                 // default: the project name
    localRepository = "~/.m2/repository"   // the default
    artifacts { "lib"; "lib-sources" }      // default: every Jar, SourceJar and JavadocJar
    pom {
      name = "Example"
      description = "An example library."  // default: the project description
      url = "https://example.dev"
      licenses { new { name = "Apache-2.0"; url = "https://www.apache.org/licenses/LICENSE-2.0" } }
      developers { new { id = "jdoe"; name = "J. Doe" } }
      scm { url = "https://github.com/example/example" }
    }
    repositories {
      ["internal"] = "https://repo.example.dev/releases"  // or new Jvm.MavenRepositorySpec { url = … }
      ["central"] = new Publishing.CentralPortal {}       // Maven Central; import "elide:Publishing.pkl" as Publishing
    }
    signing { gpg { keyName = "0123ABCD" } }  // optional; omit keyName for gpg's default key
  }
}

elide publish собирает выбранные JAR и устанавливает их вместе с POM в локальный репозиторий Maven. Версия берётся из version проекта. Публикации нужны groupId, version и ровно один Jar. SourceJar публикуется со своим classifier (по умолчанию sources), JavadocJar — с javadoc. Относительный localRepository разрешается относительно манифеста, в котором он объявлен.

МанифестОпубликованный POM
packages, modulesЗависимости compile
runtimeOnlyЗависимости runtime
compileOnly, devPackages, processors, kotlinPlugins, testPackagesНе включаются
exclusions без версии<exclusion> у каждой зависимости
Соседний проектСобственные координаты публикации этого проекта
Соседний проект в Jar.fromЕго packages, modules и runtimeOnly, если они ещё не перечислены
Путь к локальному JARОшибка: потребители не могут его разрешить

POM также перечисляет как зависимости compile библиотеки, которые Elide без объявления добавляет в classpath проекта Kotlin, потому что они нужны потребителям во время выполнения: kotlin-stdlib и kotlin-reflect версии Kotlin проекта, а также библиотеки времени выполнения, которые включает kotlin.features (kotlinx-coroutines-core, kotlinx-serialization, библиотека времени выполнения Metro). Они попадают в опубликованный POM, хотя elide.pkl их не называет. Отключите такую библиотеку там, откуда она берётся (kotlin.features или kotlin.compilerOptions.noStdlib), или объявите её сами, чтобы закрепить другую версию. jvm.features.graalvm добавляет GraalVM SDK с областью runtime.

elide publish --to <name> вместо этого публикует в репозиторий из repositories, с контрольными суммами .md5, .sha1, .sha256 и .sha512 для каждого файла. Учётные данные берутся из ELIDE_MAVEN_<NAME>_USERNAME и ELIDE_MAVEN_<NAME>_PASSWORD, где <NAME> — имя репозитория в верхнем регистре, в котором каждый символ, кроме букв и цифр, заменён на _ (internal → ELIDE_MAVEN_INTERNAL_USERNAME, my-repo → ELIDE_MAVEN_MY_REPO_…), а если их нет — из credentials репозитория. Два имени, которые дают одни и те же переменные (my-repo и my_repo), отклоняются. Репозитории с простым http://, кроме localhost, отклоняются без --allow-http-repositories.

Если задан signing, удалённая публикация подписывает каждый файл программой gpg (<file>.asc); signing {} подписывает ключом gpg по умолчанию, а signing { gpg { keyName = "…" } } выбирает ключ. Локальная публикация подписывает только с --sign, а --no-sign отключает подпись. Парольную фразу запрашивает gpg-agent. Для CI задайте ELIDE_GPG_PASSPHRASE, и Elide передаст её gpg через loopback pinentry. Сам ключ Elide никогда не читает.

Репозиторий CentralPortal публикует в Maven Central через Central Publisher Portal. Создайте в Portal пользовательский токен и передайте его как ELIDE_MAVEN_<NAME>_USERNAME и ELIDE_MAVEN_<NAME>_PASSWORD. Все проекты запуска попадают в один подписанный пакет с контрольными суммами и одно развёртывание, которое Portal проверяет и выпускает целиком. Elide ждёт, пока Portal проверит его, и завершается с ошибками Portal, если проверка не пройдена. --no-wait вместо этого возвращает управление сразу после загрузки.

Свойство CentralPortalОписаниеПо умолчанию
publishingTypeUSER_MANAGED: проверенное развёртывание вы выпускаете в Portal сами. AUTOMATIC: выпуск сразу после проверки.USER_MANAGED
urlPortal, в который выполняется загрузка.https://central.sonatype.com

Перед сборкой Elide проверяет требования Central и сразу сообщает обо всём, чего не хватает: в pom — name, description, url, licenses, developers и scm.url; артефакты SourceJar и JavadocJar; подпись (поэтому --no-sign отклоняется); версия, которая не является -SNAPSHOT.

В рабочем пространстве участники наследуют блок publishing корня, кроме artifactId и artifacts, а собственные настройки участника имеют приоритет по каждому полю. Репозитории наследуются по имени. Проект, который не собирает JAR, ничего унаследованного не публикует.

Чтобы опубликовать только часть проектов рабочего пространства, перечислите их (elide publish core util), а не меняйте их блоки publishing, или передайте --skip-existing, чтобы пропустить все версии, которые уже есть в целевом репозитории; см. elide publish.

Тестирование

import "elide:Testing.pkl" as Testing

testing { reports { Testing.xmlReport() } }
СвойствоОписание
testing.reportsФорматы отчётов для всех средств запуска тестов, записываются в .dev/reports/tests/<language>/<source-set>/; то же, что --reporter=junit.

Покрытие

import "elide:Coverage.pkl" as Coverage

coverage {
  enabled = true
  scope = "tests"
  jvm {
    excludes { "org.example.generated.*" }
    reports { Coverage.xmlReport(); Coverage.htmlReport() }
  }
  js { paths { "src" } }
}
СвойствоОписаниеПо умолчанию
coverage.enabledСобирать покрытие без --coverage.false
coverage.scopeЗадачи, которые собирают покрытие: "tests", "runs" или "all". --coverage всегда покрывает задачу, которой он передан."tests"
coverage.jvm.reportsФорматы отчётов JVM: Coverage.htmlReport(), xmlReport(), csvReport(), записываются в .dev/reports/coverage/jvm/<task>/.нет
coverage.jvm.excludesШаблоны имён классов (*, ?), которые не инструментируются, например сгенерированный код.нет
coverage.js.pathsКорни исходников JavaScript и TypeScript для отчёта в формате LCOV в .dev/reports/coverage/js/lcov.info. Пустое значение — отчёт по всему проекту.нет

См. Тестирование › Покрытие.

Рабочие пространства

workspace { members { "core"; "app" } }

Каждый участник — это каталог со своим elide.pkl; у участников не может быть своих участников. elide init --template workspace создаёт корень с библиотекой core и приложением app, которое от неё зависит.

ПоведениеПравило
Область сборкиИз корня elide build/elide test охватывают все проекты; из участника — только его.
Задачи других проектовelide build core:compile-kotlin-main или elide build core для его задач по умолчанию.
Общее состояниеРазрешённые зависимости и состояние сборки хранятся в .dev корня; результаты остаются в .dev каждого проекта.
Закрепление версийУчастник может не указывать версию Maven и брать её из корня; конфликтующая версия — ошибка.
// core/elide.pkl
import "elide:Jvm.pkl" as Jvm

dependencies {
  maven {
    packages { "com.google.guava:guava" }  // version from the root
  }
}

artifacts {
  ["jar"] = new Jvm.Jar { name = "core" }
}
// app/elide.pkl
local core = project("core")

dependencies { maven { packages { core } } }
СсылкаОписание
project("core")Артефакт Jvm.Jar проекта и его classpath компиляции; собирается при необходимости. Одни лишь исходники JVM не считаются.
project("core").artifact("fat")Выбрать один JAR, если проект объявляет несколько.
project("core").friend()Дополнительно видеть объявления Kotlin internal из core, но не из его зависимостей. Только в packages, modules, compileOnly, testPackages.
new Jvm.Jar { from { core } }Распаковать JAR core в этот JAR, предварительно собрав его; зависимость не нужна.
module.project("core")Используйте эту форму внутри тела объекта: простой project(…) там не разрешается.
new Artifacts.ProjectArtifact { project = "core"; artifact = "fat" }Явная форма; import "elide:Artifacts.pkl" as Artifacts.

Ссылка на проект без JAR или friend() не на своём месте вызывает ошибку на этапе конфигурации сборки.

Была ли эта страница полезной?