diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml
index 8c62cd4eaa..3f8a287e3a 100644
--- a/.github/workflows/autofix.yml
+++ b/.github/workflows/autofix.yml
@@ -20,26 +20,21 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1
with:
node-version: lts/*
-
- - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c
- name: ๐ง Install pnpm
-
- - name: ๐ฆ Install dependencies
- run: pnpm install
+ cache: true
- name: ๐จ Check for non-RTL/non-a11y CSS classes
- run: pnpm vp run lint:css
+ run: vp run lint:css
- name: ๐ Compare translations
- run: pnpm vp run i18n:check
+ run: vp run i18n:check
- name: ๐ Update lunaria data
- run: pnpm vp run build:lunaria
+ run: vp run build:lunaria
- name: ๐ Fix lint errors
- run: pnpm vp run lint:fix
+ run: vp run lint:fix
- uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27 # 635ffb0c9798bd160680f18fd73371e355b85f27
diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml
index 0a4860dc5f..5adb687647 100644
--- a/.github/workflows/chromatic.yml
+++ b/.github/workflows/chromatic.yml
@@ -26,15 +26,13 @@ jobs:
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1
with:
node-version: lts/*
+ cache: true
- - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c
- name: ๐ง Install pnpm
-
- - name: ๐ฆ Install dependencies
- run: pnpm install
+ - name: ๐ง Install pnpm globally
+ run: vp install -g pnpm
- name: ๐งช Run Chromatic Visual and Accessibility Tests
uses: chromaui/action@f191a0224b10e1a38b2091cefb7b7a2337009116 # v16.0.0
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b26e2a37b3..f4c414458b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -28,18 +28,16 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1
with:
node-version: lts/*
-
- - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c
- name: ๐ง Install pnpm
+ run-install: false
- name: ๐ฆ Install dependencies (root only, no scripts)
- run: pnpm install --filter . --ignore-scripts
+ run: vp install --filter . --ignore-scripts
- name: ๐ Lint project
- run: pnpm vp run lint
+ run: vp run lint
types:
name: ๐ช Type check
@@ -48,18 +46,13 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1
with:
node-version: lts/*
-
- - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c
- name: ๐ง Install pnpm
-
- - name: ๐ฆ Install dependencies
- run: pnpm install
+ cache: true
- name: ๐ช Type check
- run: pnpm vp run test:types
+ run: vp run test:types
unit:
name: ๐งช Unit tests
@@ -68,18 +61,13 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1
with:
node-version: lts/*
-
- - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c
- name: ๐ง Install pnpm
-
- - name: ๐ฆ Install dependencies
- run: pnpm install
+ cache: true
- name: ๐งช Unit tests
- run: pnpm vp test --project unit --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml
+ run: vp test --project unit --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml
- name: โฌ๏ธ Upload test results to Codecov
if: ${{ !cancelled() }}
@@ -94,21 +82,16 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1
with:
node-version: lts/*
-
- - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c
- name: ๐ง Install pnpm
-
- - name: ๐ฆ Install dependencies
- run: pnpm install
+ cache: true
- name: ๐ Install browser
- run: pnpm vp exec playwright install chromium-headless-shell
+ run: vp exec playwright install chromium-headless-shell
- name: ๐งช Component tests
- run: pnpm vp test --project nuxt --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml
+ run: vp test --project nuxt --coverage --reporter=default --reporter=junit --outputFile=test-report.junit.xml
- name: โฌ๏ธ Upload coverage reports to Codecov
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6
@@ -131,23 +114,18 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1
with:
node-version: lts/*
-
- - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c
- name: ๐ง Install pnpm
-
- - name: ๐ฆ Install dependencies
- run: pnpm install
+ cache: true
- name: ๐๏ธ Build project
- run: pnpm vp run build:test
+ run: vp run build:test
env:
VALIDATE_HTML: true
- name: ๐ฅ๏ธ Test project (browser)
- run: pnpm vp run test:browser:prebuilt
+ run: vp run test:browser:prebuilt
a11y:
name: โฟ Accessibility audit
@@ -159,21 +137,16 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1
with:
node-version: lts/*
-
- - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c
- name: ๐ง Install pnpm
-
- - name: ๐ฆ Install dependencies
- run: pnpm install
+ cache: true
- name: ๐๏ธ Build project
- run: pnpm vp run build:test
+ run: vp run build:test
- name: โฟ Accessibility audit (Lighthouse - ${{ matrix.mode }} mode)
- run: pnpm vp run test:a11y:prebuilt
+ run: vp run test:a11y:prebuilt
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
LIGHTHOUSE_COLOR_MODE: ${{ matrix.mode }}
@@ -185,18 +158,13 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1
with:
node-version: lts/*
-
- - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c
- name: ๐ง Install pnpm
-
- - name: ๐ฆ Install dependencies
- run: pnpm install
+ cache: true
- name: ๐งน Check for unused code
- run: pnpm vp run knip
+ run: vp run knip
i18n:
name: ๐ i18n validation
@@ -205,20 +173,18 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1
with:
node-version: lts/*
-
- - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c
- name: ๐ง Install pnpm
+ run-install: false
- name: ๐ฆ Install dependencies (root only, no scripts)
- run: pnpm install --filter . --ignore-scripts
+ run: vp install --filter . --ignore-scripts
- name: ๐ Check for missing or dynamic i18n keys
- run: pnpm vp run i18n:report
+ run: vp run i18n:report
- name: ๐ Check i18n schema is up to date
run: |
- pnpm vp run i18n:schema
+ vp run i18n:schema
git diff --exit-code i18n/schema.json
diff --git a/.github/workflows/lunaria.yml b/.github/workflows/lunaria.yml
index b2bc818360..4e1cf26604 100644
--- a/.github/workflows/lunaria.yml
+++ b/.github/workflows/lunaria.yml
@@ -28,15 +28,10 @@ jobs:
# Makes the action clone the entire git history
fetch-depth: 0
- - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1
with:
node-version: lts/*
-
- - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c
- name: ๐ง Install pnpm
-
- - name: ๐ฆ Install dependencies
- run: pnpm install
+ cache: true
- name: Generate Lunaria Overview
uses: lunariajs/action@4911ad0736d1e3b20af4cb70f5079aea2327ed8e # v1-prerelease
diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml
index fc244db18e..bb8d7cc779 100644
--- a/.github/workflows/release-pr.yml
+++ b/.github/workflows/release-pr.yml
@@ -20,9 +20,10 @@ jobs:
with:
fetch-depth: 0
- - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1
with:
node-version: lts/*
+ run-install: false
- name: ๐ Check for unreleased commits
id: check
diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml
index 331540e6d9..5e318171f9 100644
--- a/.github/workflows/release-tag.yml
+++ b/.github/workflows/release-tag.yml
@@ -23,9 +23,10 @@ jobs:
with:
fetch-depth: 0
- - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1
with:
node-version: lts/*
+ run-install: false
- name: ๐ข Determine next version
id: version
@@ -58,13 +59,9 @@ jobs:
git tag -a "$VERSION" -m "Release $VERSION"
git push origin "$VERSION"
- - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c
- if: steps.check.outputs.skip == 'false'
- name: ๐ง Install pnpm
-
- name: ๐ฆ Install dependencies
if: steps.check.outputs.skip == 'false'
- run: pnpm vp install --filter . --ignore-scripts
+ run: vp install --filter . --ignore-scripts
- name: ๐ Generate release notes
if: steps.check.outputs.skip == 'false'
@@ -98,18 +95,14 @@ jobs:
with:
ref: release
- - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+ - uses: voidzero-dev/setup-vp@a03302daa50cf2f017c8c7345730c2740df207d6 # v1
with:
node-version: lts/*
registry-url: https://registry.npmjs.org
-
- - uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # 5e1c8eafbd745f64b1ef30a7d7ed7965034c486c
- name: ๐ง Install pnpm
- with:
- cache: false
+ run-install: false
- name: ๐ฆ Install dependencies
- run: pnpm install --filter npmx-connector...
+ run: vp install --filter npmx-connector...
- name: ๐ข Set connector version
env:
@@ -122,7 +115,7 @@ jobs:
echo "Publishing npmx-connector@${PKG_VERSION}"
- name: ๐๏ธ Build connector
- run: pnpm --filter npmx-connector build
+ run: vp run --filter npmx-connector build
- name: ๐ค Publish to npm with provenance
# Uses OIDC trusted publishing โ no NPM_TOKEN needed.
diff --git a/.storybook/decorators.ts b/.storybook/decorators.ts
new file mode 100644
index 0000000000..270cdec3a5
--- /dev/null
+++ b/.storybook/decorators.ts
@@ -0,0 +1,20 @@
+import AppFooter from '~/components/AppFooter.vue'
+import AppHeader from '~/components/AppHeader.vue'
+
+/**
+ * Wraps a page story with the standard site chrome: AppHeader, main content
+ * area, and AppFooter. Use this for any full-page story so the layout stays
+ * consistent and changes only need to be made in one place.
+ */
+export const pageDecorator = () => ({
+ components: { AppHeader, AppFooter },
+ template: `
+
+ `,
+})
diff --git a/.storybook/docs/colors.mdx b/.storybook/docs/colors.mdx
new file mode 100644
index 0000000000..74a856d273
--- /dev/null
+++ b/.storybook/docs/colors.mdx
@@ -0,0 +1,110 @@
+import { Meta, ColorPalette, ColorItem } from '@storybook/addon-docs/blocks'
+import { theme } from '../../uno.theme.ts'
+
+
+
+# Colors
+
+The npmx color system is built on CSS custom properties with support for light/dark themes and multiple background variants.
+
+Color values are defined in `uno.theme.ts`.
+
+## Background Colors
+
+
+ ({
+ ...acc,
+ [key === 'DEFAULT' ? 'bg' : `bg-${key}`]: value,
+ }),
+ {},
+ )}
+ />
+
+
+## Foreground Colors
+
+
+ ({
+ ...acc,
+ [key === 'DEFAULT' ? 'fg' : `fg-${key}`]: value,
+ }),
+ {},
+ )}
+ />
+
+
+## Border Colors
+
+
+ ({
+ ...acc,
+ [key === 'DEFAULT' ? 'border' : `border-${key}`]: value,
+ }),
+ {},
+ )}
+ />
+
+
+## Accent Colors
+
+
+ ({
+ ...acc,
+ [key === 'DEFAULT' ? 'accent' : `accent-${key}`]: value,
+ }),
+ {},
+ )}
+ />
+
+
+## Syntax Highlighting
+
+
+
+
+
+## Badge Colors
+
+
+
+
+
+## Provider Brand Colors
+
+
+
+
+
+---
+
+## Related
+
+- [Design System Guidelines](https://storybook.npmx.dev/?path=/docs/guidelines--docs)
diff --git a/.storybook/docs/guidelines.mdx b/.storybook/docs/guidelines.mdx
new file mode 100644
index 0000000000..c559719d0f
--- /dev/null
+++ b/.storybook/docs/guidelines.mdx
@@ -0,0 +1,86 @@
+import { Meta } from '@storybook/addon-docs/blocks'
+
+
+
+# Guidelines
+
+## Containers
+
+We use three container types depending on content density.
+
+**Main Container** is the default layout container. It should be used for pages with minimal or non-text content (e.g. graphs, dashboards).
+
+**Content Container** is used for text-heavy layouts. All long-form content must be placed inside this container. The maximum readable width is **768px**.
+
+**Extra Container** is used for dense layouts (e.g. code, detailed views) where additional horizontal space is required.
+
+A right sidebar (304px) may be used for secondary content when needed.
+
+Text and input fields should not exceed **768px** in width
+
+## Element Sizes
+
+Interactive element sizes:
+
+- 24 โ 2xs (rare)
+- 28 โ xs (compact)
+- 32 โ sm (minimum recommended)
+- 36 โ md (default)
+- 42 โ lg
+- 48 โ xl
+- 56 โ 2xl
+- 64 โ 3xl
+
+## Typography
+
+- Base font size: **16px**
+- Minimum font size: **14px** (use sparingly)
+
+Text casing:
+
+- **Uppercase** โ for headings
+- **Lowercase** โ for UI elements
+- **Normal** - for body content
+
+[See Typography](https://storybook.npmx.dev/?path=/docs/tokens-typography--docs)
+
+## Surfaces & Sections
+
+To visually separate content blocks (grouped content, cards, settings sections), use subtle background variations:
+
+- `bg-muted`
+- `bg-subtle`
+
+## Borders & Radius
+
+- subtle border
+- light border radius
+- soft "glass-like" appearance
+
+Only avatars should have fully circular shapes.
+
+## Colors
+
+- Primary surfaces: **white** (`fg`)
+- Secondary or less important content: use softer, muted tones
+
+[See Colors](https://storybook.npmx.dev/?path=/docs/tokens-colors--docs)
+
+## Layout Stability
+
+Interfaces must remain visually stable across screens and pages. Avoid layout shifts. If shifts are unavoidable, place elements where movement is not critical to user interaction.
+
+## Responsiveness specifics
+
+On smaller screens:
+
+- Button text may be hidden (icons only)
+- Keyboard shortcuts may be hidden
+
+## General Principles
+
+- Preserve the meaning of elements (avoid links like button, etc)
+- Maintain sufficient spacing
+- Keep interfaces accessible
+- Prefer simple, predictable layouts
+- Design components to be easy to implement and scale
diff --git a/.storybook/docs/typography.mdx b/.storybook/docs/typography.mdx
new file mode 100644
index 0000000000..c9f99afa82
--- /dev/null
+++ b/.storybook/docs/typography.mdx
@@ -0,0 +1,166 @@
+import { Meta, Typeset } from '@storybook/addon-docs/blocks'
+import { theme } from '../../uno.theme.ts'
+
+
+
+export const wind4FontSizes = {
+ 'xs': '0.75rem',
+ 'sm': '0.875rem',
+ 'base': '1rem',
+ 'lg': '1.125rem',
+ 'xl': '1.25rem',
+ '2xl': '1.5rem',
+ '3xl': '1.875rem',
+ '4xl': '2.25rem',
+ '5xl': '3rem',
+}
+
+# Typography
+
+The npmx typography system uses Geist for sans-serif text and Geist Mono for monospace code.
+
+Typography values are defined in `uno.theme.ts`.
+
+## Font Families
+
+### Sans Serif โ Geist
+
+
+
+
+
+### Monospace โ Geist Mono
+
+Code and monospace typography scale:
+
+
+
+
+
+## Font Sizes
+
+The complete typography scale combines custom micro sizes (`5xs`-`2xs` from our theme) with standard Wind4 preset sizes (`xs`-`5xl`).
+
+**Custom Micro Sizes (from `theme.text`):**
+
+- `5xs` = {theme.text['5xs'].fontSize} (8px)
+- `4xs` = {theme.text['4xs'].fontSize} (9px)
+- `3xs` = {theme.text['3xs'].fontSize} (10px)
+- `2xs` = {theme.text['2xs'].fontSize} (11px)
+
+**Wind4 Standard Sizes:**
+
+- `xs` = {wind4FontSizes['xs']} (12px)
+- `sm` = {wind4FontSizes['sm']} (14px)
+- `base` = {wind4FontSizes['base']} (16px)
+- `lg` = {wind4FontSizes['lg']} (18px)
+- `xl` = {wind4FontSizes['xl']} (20px)
+- `2xl` = {wind4FontSizes['2xl']} (24px)
+- `3xl` = {wind4FontSizes['3xl']} (30px)
+- `4xl` = {wind4FontSizes['4xl']} (36px)
+- `5xl` = {wind4FontSizes['5xl']} (48px)
+
+## Font Weights
+
+
+
+
+
+
+
+
+
+
+
+## Line Height
+
+Base line height is set to **1.6** for optimal readability. This provides comfortable spacing for multi-line text blocks while maintaining density for UI components.
+
+## Typography Features
+
+- **Font smoothing**: Antialiased rendering (`-webkit-font-smoothing: antialiased`) applied globally
+- **Text rendering**: `optimizeLegibility` applied globally for consistent cross-browser rendering
+
+---
+
+## Related
+
+- [Design System Guidelines](https://storybook.npmx.dev/?path=/docs/guidelines--docs) - See typography guidelines and usage
+- [Colors](https://storybook.npmx.dev/?path=/docs/colors--docs) - View the color system
diff --git a/.storybook/storybook-welcome.mdx b/.storybook/docs/welcome.mdx
similarity index 100%
rename from .storybook/storybook-welcome.mdx
rename to .storybook/docs/welcome.mdx
diff --git a/.storybook/main.ts b/.storybook/main.ts
index 1dd56a7a34..31dc739ca8 100644
--- a/.storybook/main.ts
+++ b/.storybook/main.ts
@@ -1,7 +1,12 @@
import type { StorybookConfig } from '@storybook-vue/nuxt'
const config = {
- stories: ['../.storybook/*.mdx', '../app/**/*.stories.@(js|ts)'],
+ stories: [
+ // List welcome first in sidebar
+ '../.storybook/docs/welcome.mdx',
+ '../.storybook/docs/*.mdx',
+ '../app/**/*.@(mdx|stories.@(js|ts))',
+ ],
addons: [
'@storybook/addon-a11y',
'@storybook/addon-docs',
diff --git a/app/app.vue b/app/app.vue
index 5916e3e328..26c409c88f 100644
--- a/app/app.vue
+++ b/app/app.vue
@@ -50,6 +50,8 @@ if (import.meta.server) {
const keyboardShortcuts = useKeyboardShortcuts()
const { settings } = useSettings()
+initKeyShortcuts()
+
onKeyDown(
'/',
e => {
diff --git a/app/components/AppHeader.vue b/app/components/AppHeader.vue
index 1ccfc31d40..7d0ffeda71 100644
--- a/app/components/AppHeader.vue
+++ b/app/components/AppHeader.vue
@@ -1,10 +1,8 @@
diff --git a/app/components/Chart/PatternSlot.vue b/app/components/Chart/PatternSlot.vue
deleted file mode 100644
index ed0ae0a1fe..0000000000
--- a/app/components/Chart/PatternSlot.vue
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
diff --git a/app/components/Chart/SplitSparkline.vue b/app/components/Chart/SplitSparkline.vue
index f3c5537e8e..583f36a909 100644
--- a/app/components/Chart/SplitSparkline.vue
+++ b/app/components/Chart/SplitSparkline.vue
@@ -1,5 +1,6 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ crumb.name }}/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/components/Code/MobileTreeDrawer.vue b/app/components/Code/MobileTreeDrawer.vue
index ecdf1f4f4e..dd524bf635 100644
--- a/app/components/Code/MobileTreeDrawer.vue
+++ b/app/components/Code/MobileTreeDrawer.vue
@@ -22,18 +22,17 @@ watch(
const isLocked = useScrollLock(document)
// Prevent body scroll when drawer is open
watch(isOpen, open => (isLocked.value = open))
+
+function toggle() {
+ isOpen.value = !isOpen.value
+}
+
+defineExpose({
+ toggle,
+})
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/components/Code/Viewer.vue b/app/components/Code/Viewer.vue
index 90bcf0c221..5edf96eb84 100644
--- a/app/components/Code/Viewer.vue
+++ b/app/components/Code/Viewer.vue
@@ -86,7 +86,7 @@ watch(
-
+
import { ref, computed } from 'vue'
import { VueUiHorizontalBar } from 'vue-data-ui/vue-ui-horizontal-bar'
+import { VueUiPatternSeed } from 'vue-data-ui/vue-ui-pattern-seed'
import type { VueUiHorizontalBarConfig, VueUiHorizontalBarDatasetItem } from 'vue-data-ui'
import { getFrameworkColor, isListedFramework } from '~/utils/frameworks'
-import { createChartPatternSlotMarkup } from '~/utils/charts'
+import { createPatternDef } from 'vue-data-ui/utils'
import { drawSmallNpmxLogoAndTaglineWatermark } from '~/composables/useChartWatermark'
import {
@@ -12,6 +13,7 @@ import {
sanitise,
applyEllipsis,
copyAltTextForCompareFacetBarChart,
+ CHART_PATTERN_CONFIG,
} from '~/utils/charts'
import('vue-data-ui/style.css')
@@ -227,14 +229,15 @@ const config = computed
(() => {
const patternId = `tooltip-pattern-${safeSeriesIndex}`
const usePattern = safeSeriesIndex !== 0
- const patternMarkup = usePattern
- ? createChartPatternSlotMarkup({
+ const patternDef = usePattern
+ ? createPatternDef({
id: patternId,
seed: safeSeriesIndex,
foregroundColor: colors.value.bg!,
- fallbackColor: 'transparent',
- maxSize: 24,
- minSize: 16,
+ backgroundColor: 'transparent',
+ maxSize: CHART_PATTERN_CONFIG.maxSize,
+ minSize: CHART_PATTERN_CONFIG.minSize,
+ disambiguator: CHART_PATTERN_CONFIG.disambiguator,
})
: ''
@@ -252,9 +255,7 @@ const config = computed(() => {
@@ -286,14 +287,15 @@ const config = computed
(() => {
-
diff --git a/app/components/Package/Header.vue b/app/components/Package/Header.vue
index 7cf6b4c8bc..e0aeab97be 100644
--- a/app/components/Package/Header.vue
+++ b/app/components/Package/Header.vue
@@ -1,7 +1,6 @@
@@ -346,113 +332,51 @@ defineOgImageComponent('Default', {
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t('code.raw') }}
-
-
-
-
+
+
+
+
+
-
+
@@ -462,10 +386,12 @@ defineOgImageComponent('Default', {
:html="fileContent.html"
:lines="fileContent.lines"
:selected-lines="selectedLines"
+ class="flex-1"
@line-click="handleLineClick"
/>
-
-
+
+
+
{{
$t('code.lines', { count: fileContent.lines })
}}
@@ -477,7 +403,7 @@ defineOgImageComponent('Default', {
-
+
{{ $t('code.binary_file') }}
@@ -496,7 +422,7 @@ defineOgImageComponent('Default', {
-
+
{{ $t('code.file_too_large') }}
@@ -512,44 +438,6 @@ defineOgImageComponent('Default', {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -580,6 +468,7 @@ defineOgImageComponent('Default', {
+
+
diff --git a/app/pages/package/[[org]]/[name]/versions.vue b/app/pages/package/[[org]]/[name]/versions.vue
index d8a317f604..b07f8aac92 100644
--- a/app/pages/package/[[org]]/[name]/versions.vue
+++ b/app/pages/package/[[org]]/[name]/versions.vue
@@ -49,7 +49,7 @@ const distTags = computed(() => versionSummary.value?.distTags ?? {})
const versionStrings = computed(() => versionSummary.value?.versions ?? [])
const versionTimes = computed(() => versionSummary.value?.time ?? {})
-// โโโ Phase 2: full metadata (loaded on first group expand) โโโโโโโโโโโโโโโโโโโโ
+// โโโ Phase 2: full metadata (fired automatically after phase 1 completes) โโโโ
// Fetches deprecated status, provenance, and exact times needed for version rows.
const fullVersionMap = shallowRef
-
+
+
+
+
+
+
+
+
@@ -230,18 +270,26 @@ const flatItems = computed
(() => {
v-for="tag in latestTagRow!.tags.filter(t => t !== 'latest')"
:key="tag"
class="text-3xs font-semibold uppercase tracking-wide text-fg-subtle"
+ :title="tag"
>{{ tag }}
{{ latestTagRow!.version }}
-
+
+
deprecated
(() => {
v-for="tag in row.tags"
:key="tag"
class="text-3xs font-semibold uppercase tracking-wide text-fg-subtle"
+ :title="tag"
>{{ tag }}
@@ -284,30 +333,36 @@ const flatItems = computed
(() => {
{{ row.version }}
-
-
-
-
-
+
+
@@ -351,15 +406,9 @@ const flatItems = computed
(() => {
-
(() => {
{{ item.label }}
+ deprecated
({{ item.versions.length }})
- {{ item.versions[0] }}
+ {{
+ item.versions[0]
+ }}
(() => {
? 'i-lucide:octagon-alert'
: undefined
"
+ :title="
+ fullVersionMap?.get(item.version)?.deprecated
+ ? $t('package.versions.deprecated_title', { version: item.version })
+ : item.version
+ "
dir="ltr"
>
{{ item.version }}
@@ -424,6 +485,7 @@ const flatItems = computed(() => {
:key="tag"
class="text-4xs font-semibold uppercase tracking-wide"
:class="tag === 'latest' ? 'text-accent' : 'text-fg-subtle'"
+ :title="tag"
>
{{ tag }}
@@ -521,17 +583,4 @@ const flatItems = computed(() => {
opacity: 0;
transform: scale(0.5);
}
-
-@keyframes searching {
- from {
- transform: rotate(0deg) translateY(-2px) rotate(0deg);
- }
- to {
- transform: rotate(360deg) translateY(-2px) rotate(-360deg);
- }
-}
-
-.animate-searching {
- animation: searching 1.2s linear infinite;
-}
diff --git a/app/pages/privacy.stories.ts b/app/pages/privacy.stories.ts
new file mode 100644
index 0000000000..7e2e566b3e
--- /dev/null
+++ b/app/pages/privacy.stories.ts
@@ -0,0 +1,16 @@
+import Privacy from './privacy.vue'
+import type { Meta, StoryObj } from '@storybook-vue/nuxt'
+import { pageDecorator } from '../../.storybook/decorators'
+
+const meta = {
+ component: Privacy,
+ parameters: {
+ layout: 'fullscreen',
+ },
+ decorators: [pageDecorator],
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {}
diff --git a/app/utils/charts.ts b/app/utils/charts.ts
index b11c8775bd..6997b8c025 100644
--- a/app/utils/charts.ts
+++ b/app/utils/charts.ts
@@ -722,377 +722,13 @@ export function applyEllipsis(text: string, maxLength = 45) {
return text.slice(0, maxLength) + '...'
}
-// a11y pattern generation
-export type SvgPatternType =
- | 'diagonalLines'
- | 'verticalLines'
- | 'horizontalLines'
- | 'crosshatch'
- | 'dots'
- | 'grid'
- | 'zigzag'
-
-export type SeededSvgPatternOptions = {
- foregroundColor?: string
- backgroundColor?: string
- minimumSize?: number
- maximumSize?: number
-}
-
-export type SeededSvgPatternResult = {
- width: number
- height: number
- rotation: number
- patternType: SvgPatternType
- contentMarkup: string
-}
-
-type NonEmptyReadonlyArray = readonly [T, ...T[]]
-
/**
- * Generates a deterministic 32-bit unsigned integer hash from a string.
- *
- * This function is based on the FNV-1a hashing algorithm. It is used to
- * transform any string input into a stable numeric seed suitable for
- * deterministic pseudo-random number generation.
- *
- * The same input string will always produce the same output number.
- *
- * @param value - The input string to hash.
- * @returns A 32-bit unsigned integer hash.
- */
-export function createSeedNumber(value: string): number {
- let hashValue = 2166136261
- for (let index = 0; index < value.length; index += 1) {
- hashValue ^= value.charCodeAt(index)
- hashValue = Math.imul(hashValue, 16777619)
- }
- return hashValue >>> 0
-}
-
-/**
- * Creates a deterministic pseudo-random number generator (PRNG) based on a numeric seed.
- *
- * This function implements a fast, non-cryptographic PRNG similar to Mulberry32.
- * It produces a reproducible sequence of numbers in the range [0, 1), meaning
- * the same seed will always generate the same sequence.
- *
- * The returned function maintains internal state and should be called repeatedly
- * to obtain successive pseudo-random values.
- *
- * @param seedNumber - 32 bit integer seed
- * @returns A function that returns a pseudo rand number between 0 (inclusive) and 1 (exclusive).
- *
- * @example
- * const random = createDeterministicRandomGenerator(12345)
- * const a = random() // always the same for seed 12345
- * const b = random()
+ * Constants shared among chart components using seeded patterns with the component.
+ * Important: `disambiguator` can be any number, and is used to cycle through different pattern sets. Its
+ * value was chosen for the diversity of its motifs.
*/
-function createDeterministicRandomGenerator(seedNumber: number): () => number {
- // Ensure the seed is treated as an unsigned 32 bit int
- let state = seedNumber >>> 0
-
- return function generateRandomNumber(): number {
- // Advance internal state using a constant
- state += 0x6d2b79f5
- let intermediateValue = state
-
- // First mixing step:
- // - XOR with a right shifted version of itself
- // - Multiply with a derived value to further scramble bits
- intermediateValue = Math.imul(
- intermediateValue ^ (intermediateValue >>> 15),
- intermediateValue | 1,
- )
-
- // Second mixing step:
- // - Combine current value with another transformed version of itself
- // - Multiply again to increase entropy and spread bits
- intermediateValue ^=
- intermediateValue +
- Math.imul(intermediateValue ^ (intermediateValue >>> 7), intermediateValue | 61)
-
- // Final step:
- // - Final XOR with shifted value for additional scrambling
- // - Convert to unsigned 32 bit int
- // - Normalize to a float in range 0 to 1
- return ((intermediateValue ^ (intermediateValue >>> 14)) >>> 0) / 4294967296
- }
-}
-
-function pickValue(values: NonEmptyReadonlyArray, generateRandomNumber: () => number): T {
- const selectedIndex = Math.floor(generateRandomNumber() * values.length)
- const selectedValue = values[selectedIndex]
- if (selectedValue === undefined) {
- throw new Error('pickValue requires a non-empty array')
- }
- return selectedValue
-}
-
-function escapeSvgAttribute(value: string): string {
- return value
- .replace(/&/g, '&')
- .replace(/"/g, '"')
- .replace(//g, '>')
-}
-
-function createLineElement(
- x1: number,
- y1: number,
- x2: number,
- y2: number,
- stroke: string,
- strokeWidth: number,
- opacity: number,
-): string {
- const safeStroke = escapeSvgAttribute(stroke)
- return ``
-}
-
-function createCircleElement(
- centerX: number,
- centerY: number,
- radius: number,
- fill: string,
- opacity: number,
-): string {
- const safeFill = escapeSvgAttribute(fill)
- return ``
-}
-
-function createPathElement(
- pathData: string,
- fill: string,
- stroke: string,
- strokeWidth: number,
- opacity: number,
-): string {
- const safeFill = escapeSvgAttribute(fill)
- const safeStroke = escapeSvgAttribute(stroke)
- return ``
-}
-
-function toNonEmptyReadonlyArray(values: readonly T[]): NonEmptyReadonlyArray {
- if (values.length === 0) {
- throw new Error('Expected a non-empty array')
- }
-
- return values as NonEmptyReadonlyArray
-}
-
-export function createSeededSvgPattern(
- seed: string | number,
- options?: SeededSvgPatternOptions,
-): SeededSvgPatternResult {
- const normalizedSeed = String(seed)
- const foregroundColor = options?.foregroundColor ?? '#111111'
- const backgroundColor = options?.backgroundColor ?? 'transparent'
- const minimumSize = options?.minimumSize ?? 8
- const maximumSize = options?.maximumSize ?? 20
-
- if (
- !Number.isFinite(minimumSize) ||
- !Number.isFinite(maximumSize) ||
- minimumSize <= 0 ||
- maximumSize <= 0 ||
- minimumSize > maximumSize
- ) {
- throw new RangeError(
- 'minimumSize and maximumSize must be finite, positive, and minimumSize must not exceed maximumSize',
- )
- }
-
- const seedNumber = createSeedNumber(normalizedSeed)
- const generateRandomNumber = createDeterministicRandomGenerator(seedNumber)
-
- const patternType = pickValue(
- [
- 'diagonalLines',
- 'verticalLines',
- 'horizontalLines',
- 'crosshatch',
- 'dots',
- 'grid',
- 'zigzag',
- ] as const,
- generateRandomNumber,
- )
-
- const availableSizes: number[] = []
- for (let size = minimumSize; size <= maximumSize; size += 2) {
- availableSizes.push(size)
- }
-
- const tileSize = pickValue(toNonEmptyReadonlyArray(availableSizes), generateRandomNumber)
- const gap = pickValue([2, 3, 4, 5, 6] as const, generateRandomNumber)
- const strokeWidth = pickValue([1, 1.25, 1.5, 1.75, 2] as const, generateRandomNumber)
- const opacity = pickValue([0.7, 0.8, 0.9, 1] as const, generateRandomNumber)
- const rotation = pickValue([0, 15, 30, 45, 60, 75, 90, 120, 135] as const, generateRandomNumber)
-
- let contentMarkup = ''
-
- switch (patternType) {
- case 'diagonalLines': {
- contentMarkup = [
- createLineElement(
- -tileSize,
- tileSize,
- tileSize,
- -tileSize,
- foregroundColor,
- strokeWidth,
- opacity,
- ),
- createLineElement(0, tileSize, tileSize, 0, foregroundColor, strokeWidth, opacity),
- createLineElement(0, tileSize * 2, tileSize * 2, 0, foregroundColor, strokeWidth, opacity),
- ].join('')
- break
- }
-
- case 'verticalLines': {
- const positions = [0, gap + strokeWidth, (gap + strokeWidth) * 2]
- contentMarkup = positions
- .map(x => createLineElement(x, 0, x, tileSize, foregroundColor, strokeWidth, opacity))
- .join('')
- break
- }
-
- case 'horizontalLines': {
- const positions = [0, gap + strokeWidth, (gap + strokeWidth) * 2]
- contentMarkup = positions
- .map(y => createLineElement(0, y, tileSize, y, foregroundColor, strokeWidth, opacity))
- .join('')
- break
- }
-
- case 'crosshatch': {
- contentMarkup = [
- createLineElement(
- 0,
- tileSize / 2,
- tileSize,
- tileSize / 2,
- foregroundColor,
- strokeWidth,
- opacity,
- ),
- createLineElement(
- tileSize / 2,
- 0,
- tileSize / 2,
- tileSize,
- foregroundColor,
- strokeWidth,
- opacity,
- ),
- createLineElement(0, 0, tileSize, tileSize, foregroundColor, strokeWidth * 0.75, opacity),
- createLineElement(tileSize, 0, 0, tileSize, foregroundColor, strokeWidth * 0.75, opacity),
- ].join('')
- break
- }
-
- case 'dots': {
- const radius = Math.max(1, tileSize / 12)
- contentMarkup = [
- createCircleElement(tileSize / 4, tileSize / 4, radius, foregroundColor, opacity),
- createCircleElement((tileSize * 3) / 4, tileSize / 4, radius, foregroundColor, opacity),
- createCircleElement(tileSize / 4, (tileSize * 3) / 4, radius, foregroundColor, opacity),
- createCircleElement(
- (tileSize * 3) / 4,
- (tileSize * 3) / 4,
- radius,
- foregroundColor,
- opacity,
- ),
- ].join('')
- break
- }
-
- case 'grid': {
- contentMarkup = [
- createLineElement(0, 0, tileSize, 0, foregroundColor, strokeWidth, opacity),
- createLineElement(0, 0, 0, tileSize, foregroundColor, strokeWidth, opacity),
- createLineElement(
- 0,
- tileSize / 2,
- tileSize,
- tileSize / 2,
- foregroundColor,
- strokeWidth * 0.8,
- opacity,
- ),
- createLineElement(
- tileSize / 2,
- 0,
- tileSize / 2,
- tileSize,
- foregroundColor,
- strokeWidth * 0.8,
- opacity,
- ),
- ].join('')
- break
- }
-
- case 'zigzag': {
- const midPoint = tileSize / 2
- const pathData = `M 0 ${midPoint} L ${tileSize / 4} 0 L ${tileSize / 2} ${midPoint} L ${(tileSize * 3) / 4} ${tileSize} L ${tileSize} ${midPoint}`
- contentMarkup = createPathElement(pathData, 'none', foregroundColor, strokeWidth, opacity)
- break
- }
- }
-
- if (backgroundColor !== 'transparent') {
- const safeBackgroundColor = escapeSvgAttribute(backgroundColor)
- contentMarkup = `${contentMarkup}`
- }
-
- return {
- width: tileSize,
- height: tileSize,
- rotation,
- patternType,
- contentMarkup,
- }
-}
-
-export type ChartPatternSlotProps = {
- id: string
- seed: string | number
- color?: string
- foregroundColor: string
- fallbackColor: string
- maxSize: number
- minSize: number
-}
-
-// Equivalent of the PatternSlot.vue component, to be used inside tooltip.customFormat in chart configs
-export function createChartPatternSlotMarkup({
- id,
- seed,
- color,
- foregroundColor,
- fallbackColor,
- maxSize,
- minSize,
-}: ChartPatternSlotProps) {
- const pattern = createSeededSvgPattern(seed, {
- foregroundColor,
- backgroundColor: color ?? fallbackColor,
- minimumSize: minSize,
- maximumSize: maxSize,
- })
-
- return `
-
- ${pattern.contentMarkup}
-
- `
+export const CHART_PATTERN_CONFIG = {
+ disambiguator: 1,
+ minSize: 16,
+ maxSize: 24,
}
diff --git a/app/utils/install-command.ts b/app/utils/install-command.ts
index 857804cafa..3b656a74ce 100644
--- a/app/utils/install-command.ts
+++ b/app/utils/install-command.ts
@@ -47,7 +47,7 @@ export const packageManagers = [
action: 'add',
executeLocal: 'deno run',
executeRemote: 'deno run',
- create: 'deno run',
+ create: 'deno create',
icon: 'i-simple-icons:deno',
},
{
@@ -125,6 +125,24 @@ export interface ExecuteCommandOptions extends InstallCommandOptions {
isCreatePackage?: boolean
}
+function getCreatePackageSpecifier(options: ExecuteCommandOptions): string | null {
+ if (!options.isCreatePackage) {
+ return null
+ }
+
+ const shortName = getCreateShortName(options.packageName)
+ if (shortName === options.packageName) {
+ return null
+ }
+
+ if (options.packageManager === 'deno') {
+ // npm compatibility: npm:package-name
+ return `npm:${shortName}`
+ }
+
+ return shortName
+}
+
export function getExecuteCommand(options: ExecuteCommandOptions): string {
return getExecuteCommandParts(options).join(' ')
}
@@ -133,12 +151,10 @@ export function getExecuteCommandParts(options: ExecuteCommandOptions): string[]
const pm = packageManagers.find(p => p.id === options.packageManager)
if (!pm) return []
- // For create-* packages, use the shorthand create command
- if (options.isCreatePackage) {
- const shortName = getCreateShortName(options.packageName)
- if (shortName !== options.packageName) {
- return [...pm.create.split(' '), shortName]
- }
+ // For create-* packages, use the shorthand create command.
+ const createSpecifier = getCreatePackageSpecifier(options)
+ if (createSpecifier) {
+ return [...pm.create.split(' '), createSpecifier]
}
// Choose remote or local execute based on package type
diff --git a/app/utils/router.ts b/app/utils/router.ts
index 0c22d92860..0c9bed9884 100644
--- a/app/utils/router.ts
+++ b/app/utils/router.ts
@@ -29,6 +29,12 @@ export function packageRoute(
}
}
+/** Full version history page (`/package/.../versions`) */
+export function packageVersionsRoute(packageName: string): RouteLocationRaw {
+ const [org, name = ''] = packageName.startsWith('@') ? packageName.split('/') : ['', packageName]
+ return { name: 'package-versions', params: { org, name } }
+}
+
export function diffRoute(
packageName: string,
fromVersion: string,
diff --git a/chromatic.config.json b/chromatic.config.json
index cb44a68276..7e58430015 100644
--- a/chromatic.config.json
+++ b/chromatic.config.json
@@ -3,5 +3,5 @@
"onlyChanged": true,
"autoAcceptChanges": "main",
"exitZeroOnChanges": false,
- "externals": [".storybook/**", "uno.config.ts"]
+ "externals": [".storybook/**", "uno.config.ts", "uno.theme.ts"]
}
diff --git a/cli/package.json b/cli/package.json
index 455fd222d8..c205f7d4c9 100644
--- a/cli/package.json
+++ b/cli/package.json
@@ -46,6 +46,6 @@
"typescript": "6.0.2"
},
"engines": {
- "node": ">=24"
+ "node": ">=24.4.0"
}
}
diff --git a/cli/src/cli.ts b/cli/src/cli.ts
index e122cec9f2..fda9049f50 100644
--- a/cli/src/cli.ts
+++ b/cli/src/cli.ts
@@ -8,26 +8,27 @@ import { serve } from 'srvx'
import { createConnectorApp, generateToken, CONNECTOR_VERSION } from './server.ts'
import { getNpmUser, NPM_REGISTRY_URL } from './npm-client.ts'
import { initLogger, showToken, logInfo, logWarning, logError } from './logger.ts'
+import { resolveNpmProcessCommand } from './npm-process.ts'
const DEFAULT_PORT = 31415
const DEFAULT_FRONTEND_URL = 'https://npmx.dev/'
const DEV_FRONTEND_URL = 'http://127.0.0.1:3000/'
async function runNpmLogin(): Promise {
- return new Promise(resolve => {
- const child = spawn('npm', ['login', `--registry=${NPM_REGISTRY_URL}`], {
- stdio: 'inherit',
- shell: true,
- })
+ const { command, args } = resolveNpmProcessCommand(['login', `--registry=${NPM_REGISTRY_URL}`])
+ const child = spawn(command, args, { stdio: 'inherit' })
- child.on('close', code => {
- resolve(code === 0)
- })
+ const { promise, resolve } = Promise.withResolvers()
- child.on('error', () => {
- resolve(false)
- })
+ child.on('close', code => {
+ resolve(code === 0)
})
+
+ child.on('error', () => {
+ resolve(false)
+ })
+
+ return promise
}
const main = defineCommand({
diff --git a/cli/src/npm-client.ts b/cli/src/npm-client.ts
index 8448413b52..e5a28edc89 100644
--- a/cli/src/npm-client.ts
+++ b/cli/src/npm-client.ts
@@ -2,12 +2,13 @@ import crypto from 'node:crypto'
import process from 'node:process'
import { execFile } from 'node:child_process'
import { promisify } from 'node:util'
-import { mkdtemp, writeFile, rm } from 'node:fs/promises'
+import { mkdtempDisposable, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import * as v from 'valibot'
import { PackageNameSchema, UsernameSchema, OrgNameSchema, ScopeTeamSchema } from './schemas.ts'
import { logCommand, logSuccess, logError, logDebug } from './logger.ts'
+import { resolveNpmProcessCommand } from './npm-process.ts'
const execFileAsync = promisify(execFile)
export const NPM_REGISTRY_URL = 'https://registry.npmjs.org/'
@@ -179,139 +180,140 @@ async function execNpmInteractive(
options: ExecNpmOptions = {},
): Promise {
const openUrls = options.openUrls === true
+ const { promise, resolve } = Promise.withResolvers()
// Lazy-load node-pty so the native addon is only required when interactive mode is actually used.
const pty = await import('@lydell/node-pty')
- return new Promise(resolve => {
- const npmArgs = options.otp ? [...args, '--otp', options.otp] : args
+ const npmArgs = options.otp ? [...args, '--otp', options.otp] : args
- if (!options.silent) {
- const displayCmd = options.otp
- ? ['npm', ...args, '--otp', '******'].join(' ')
- : ['npm', ...args].join(' ')
- logCommand(`${displayCmd} (interactive/pty)`)
- }
+ if (!options.silent) {
+ const displayCmd = options.otp
+ ? ['npm', ...args, '--otp', '******'].join(' ')
+ : ['npm', ...args].join(' ')
+ logCommand(`${displayCmd} (interactive/pty)`)
+ }
- let output = ''
- let resolved = false
- let otpPromptSeen = false
- let authUrlSeen = false
- let enterSent = false
- let authUrlTimeout: ReturnType | null = null
- let authUrlTimedOut = false
+ let output = ''
+ let resolved = false
+ let otpPromptSeen = false
+ let authUrlSeen = false
+ let enterSent = false
+ let authUrlTimeout: ReturnType | null = null
+ let authUrlTimedOut = false
- const env = createNpmEnv()
+ const env = createNpmEnv()
- // When openUrls is false, tell npm not to open the browser.
- // npm still prints the auth URL and polls doneUrl
- if (!openUrls) {
- env.npm_config_browser = 'false'
- }
+ // When openUrls is false, tell npm not to open the browser.
+ // npm still prints the auth URL and polls doneUrl
+ if (!openUrls) {
+ env.npm_config_browser = 'false'
+ }
- const child = pty.spawn('npm', npmArgs, {
- name: 'xterm-256color',
- cols: 120,
- rows: 30,
- env,
- })
+ const child = pty.spawn('npm', npmArgs, {
+ name: 'xterm-256color',
+ cols: 120,
+ rows: 30,
+ env,
+ })
- // General timeout: 5 minutes (covers non-auth interactive commands)
- const timeout = setTimeout(() => {
- if (resolved) return
- logDebug('Interactive command timed out', { output })
- child.kill()
- }, 300000)
-
- child.onData((data: string) => {
- output += data
- const clean = stripAnsi(data)
- logDebug('pty data:', { text: clean.trim() })
-
- const cleanAll = stripAnsi(output)
-
- // Detect auth URL in output and notify the caller.
- if (!authUrlSeen) {
- const urlMatch = cleanAll.match(AUTH_URL_TITLE_RE)
-
- if (urlMatch && urlMatch[1]) {
- authUrlSeen = true
- const authUrl = urlMatch[1].replace(/[.,;:!?)]+$/, '')
- logDebug('Auth URL detected:', { authUrl, openUrls })
- options.onAuthUrl?.(authUrl)
-
- authUrlTimeout = setTimeout(() => {
- if (resolved) return
- authUrlTimedOut = true
- logDebug('Auth URL timeout (90s) โ killing process')
- logError('Authentication timed out after 90 seconds')
- child.kill()
- }, AUTH_URL_TIMEOUT_MS)
- }
+ // General timeout: 5 minutes (covers non-auth interactive commands)
+ const timeout = setTimeout(() => {
+ if (resolved) return
+ logDebug('Interactive command timed out', { output })
+ child.kill()
+ }, 300000)
+
+ child.onData((data: string) => {
+ output += data
+ const clean = stripAnsi(data)
+ logDebug('pty data:', { text: clean.trim() })
+
+ const cleanAll = stripAnsi(output)
+
+ // Detect auth URL in output and notify the caller.
+ if (!authUrlSeen) {
+ const urlMatch = cleanAll.match(AUTH_URL_TITLE_RE)
+
+ if (urlMatch && urlMatch[1]) {
+ authUrlSeen = true
+ const authUrl = urlMatch[1].replace(/[.,;:!?)]+$/, '')
+ logDebug('Auth URL detected:', { authUrl, openUrls })
+ options.onAuthUrl?.(authUrl)
+
+ authUrlTimeout = setTimeout(() => {
+ if (resolved) return
+ authUrlTimedOut = true
+ logDebug('Auth URL timeout (90s) โ killing process')
+ logError('Authentication timed out after 90 seconds')
+ child.kill()
+ }, AUTH_URL_TIMEOUT_MS)
}
+ }
- if (authUrlSeen && openUrls && !enterSent && AUTH_URL_PROMPT_RE.test(cleanAll)) {
- enterSent = true
- logDebug('Web auth prompt detected, pressing ENTER')
- child.write('\r')
- }
+ if (authUrlSeen && openUrls && !enterSent && AUTH_URL_PROMPT_RE.test(cleanAll)) {
+ enterSent = true
+ logDebug('Web auth prompt detected, pressing ENTER')
+ child.write('\r')
+ }
- if (!otpPromptSeen && OTP_PROMPT_RE.test(cleanAll)) {
- otpPromptSeen = true
- if (options.otp) {
- logDebug('OTP prompt detected, writing OTP')
- child.write(options.otp + '\r')
- } else {
- logDebug('OTP prompt detected but no OTP provided, killing process')
- child.kill()
- }
+ if (!otpPromptSeen && OTP_PROMPT_RE.test(cleanAll)) {
+ otpPromptSeen = true
+ if (options.otp) {
+ logDebug('OTP prompt detected, writing OTP')
+ child.write(options.otp + '\r')
+ } else {
+ logDebug('OTP prompt detected but no OTP provided, killing process')
+ child.kill()
}
- })
+ }
+ })
+
+ child.onExit(({ exitCode }) => {
+ if (resolved) return
+ resolved = true
+ clearTimeout(timeout)
+ if (authUrlTimeout) clearTimeout(authUrlTimeout)
+
+ const cleanOutput = stripAnsi(output)
+ logDebug('Interactive command exited:', { exitCode, output: cleanOutput })
- child.onExit(({ exitCode }) => {
- if (resolved) return
- resolved = true
- clearTimeout(timeout)
- if (authUrlTimeout) clearTimeout(authUrlTimeout)
-
- const cleanOutput = stripAnsi(output)
- logDebug('Interactive command exited:', { exitCode, output: cleanOutput })
-
- const requiresOtp =
- authUrlTimedOut || (otpPromptSeen && !options.otp) || detectOtpRequired(cleanOutput)
- const authFailure = detectAuthFailure(cleanOutput)
- const urls = extractUrls(cleanOutput)
-
- if (!options.silent) {
- if (exitCode === 0) {
- logSuccess('Done')
- } else if (requiresOtp) {
- logError('OTP required')
- } else if (authFailure) {
- logError('Authentication required - please run "npm login" and restart the connector')
- } else {
- const firstLine = filterNpmWarnings(cleanOutput).split('\n')[0] || 'Command failed'
- logError(firstLine)
- }
+ const requiresOtp =
+ authUrlTimedOut || (otpPromptSeen && !options.otp) || detectOtpRequired(cleanOutput)
+ const authFailure = detectAuthFailure(cleanOutput)
+ const urls = extractUrls(cleanOutput)
+
+ if (!options.silent) {
+ if (exitCode === 0) {
+ logSuccess('Done')
+ } else if (requiresOtp) {
+ logError('OTP required')
+ } else if (authFailure) {
+ logError('Authentication required - please run "npm login" and restart the connector')
+ } else {
+ const firstLine = filterNpmWarnings(cleanOutput).split('\n')[0] || 'Command failed'
+ logError(firstLine)
}
+ }
- // If auth URL timed out, force a non-zero exit code so it's marked as failed
- const finalExitCode = authUrlTimedOut ? 1 : exitCode
-
- resolve({
- stdout: cleanOutput.trim(),
- stderr: requiresOtp
- ? 'This operation requires a one-time password (OTP).'
- : authFailure
- ? 'Authentication failed. Please run "npm login" and restart the connector.'
- : filterNpmWarnings(cleanOutput),
- exitCode: finalExitCode,
- requiresOtp,
- authFailure,
- urls: urls.length > 0 ? urls : undefined,
- })
+ // If auth URL timed out, force a non-zero exit code so it's marked as failed
+ const finalExitCode = authUrlTimedOut ? 1 : exitCode
+
+ resolve({
+ stdout: cleanOutput.trim(),
+ stderr: requiresOtp
+ ? 'This operation requires a one-time password (OTP).'
+ : authFailure
+ ? 'Authentication failed. Please run "npm login" and restart the connector.'
+ : filterNpmWarnings(cleanOutput),
+ exitCode: finalExitCode,
+ requiresOtp,
+ authFailure,
+ urls: urls.length > 0 ? urls : undefined,
})
})
+
+ return promise
}
async function execNpm(args: string[], options: ExecNpmOptions = {}): Promise {
@@ -332,13 +334,10 @@ async function execNpm(args: string[], options: ExecNpmOptions = {}): Promise {
validatePackageName(name)
- // Create a temporary directory
- const tempDir = await mkdtemp(join(tmpdir(), 'npmx-init-'))
-
- try {
- // Determine access type based on whether it's a scoped package
- const isScoped = name.startsWith('@')
- const access = isScoped ? 'public' : undefined
-
- // Create minimal package.json
- const packageJson = {
- name,
- version: '0.0.0',
- description: `Placeholder for ${name}`,
- main: 'index.js',
- scripts: {},
- keywords: [],
- author: author ? `${author} (https://www.npmjs.com/~${author})` : '',
- license: 'UNLICENSED',
- private: false,
- ...(access && { publishConfig: { access } }),
- }
+ // Let Node clean up the temp directory automatically when this scope exits.
+ await using tempDir = await mkdtempDisposable(join(tmpdir(), 'npmx-init-'))
+
+ // Determine access type based on whether it's a scoped package
+ const isScoped = name.startsWith('@')
+ const access = isScoped ? 'public' : undefined
+
+ // Create minimal package.json
+ const packageJson = {
+ name,
+ version: '0.0.0',
+ description: `Placeholder for ${name}`,
+ main: 'index.js',
+ scripts: {},
+ keywords: [],
+ author: author ? `${author} (https://www.npmjs.com/~${author})` : '',
+ license: 'UNLICENSED',
+ private: false,
+ ...(access && { publishConfig: { access } }),
+ }
- await writeFile(join(tempDir, 'package.json'), JSON.stringify(packageJson, null, 2))
+ await writeFile(join(tempDir.path, 'package.json'), JSON.stringify(packageJson, null, 2))
- // Create empty index.js
- await writeFile(join(tempDir, 'index.js'), '// Placeholder\n')
+ // Create empty index.js
+ await writeFile(join(tempDir.path, 'index.js'), '// Placeholder\n')
- // Build npm publish args
- const args = ['publish']
- if (access) {
- args.push('--access', access)
- }
+ // Build npm publish args
+ const args = ['publish']
+ if (access) {
+ args.push('--access', access)
+ }
- // Run npm publish from the temp directory
- const npmArgs = otp ? [...args, '--otp', otp] : args
+ // Run npm publish from the temp directory
+ const npmArgs = otp ? [...args, '--otp', otp] : args
- // Log the command being run (hide OTP value for security)
- const displayCmd = otp ? `npm ${args.join(' ')} --otp ******` : `npm ${args.join(' ')}`
- logCommand(`${displayCmd} (in temp dir for ${name})`)
+ // Log the command being run (hide OTP value for security)
+ const displayCmd = otp ? `npm ${args.join(' ')} --otp ******` : `npm ${args.join(' ')}`
+ logCommand(`${displayCmd} (in temp dir for ${name})`)
- try {
- const { stdout, stderr } = await execFileAsync('npm', npmArgs, {
- timeout: 60000,
- cwd: tempDir,
- env: createNpmEnv(),
- shell: process.platform === 'win32',
- })
+ try {
+ const { command, args: processArgs } = resolveNpmProcessCommand(npmArgs)
+ const { stdout, stderr } = await execFileAsync(command, processArgs, {
+ timeout: 60000,
+ cwd: tempDir.path,
+ env: createNpmEnv(),
+ })
- logSuccess(`Published ${name}@0.0.0`)
+ logSuccess(`Published ${name}@0.0.0`)
- return {
- stdout: stdout.trim(),
- stderr: filterNpmWarnings(stderr),
- exitCode: 0,
- }
- } catch (error) {
- const err = error as { stdout?: string; stderr?: string; code?: number }
- const stderr = err.stderr?.trim() ?? String(error)
- const requiresOtp = detectOtpRequired(stderr)
- const authFailure = detectAuthFailure(stderr)
+ return {
+ stdout: stdout.trim(),
+ stderr: filterNpmWarnings(stderr),
+ exitCode: 0,
+ }
+ } catch (error) {
+ const err = error as { stdout?: string; stderr?: string; code?: number }
+ const stderr = err.stderr?.trim() ?? String(error)
+ const requiresOtp = detectOtpRequired(stderr)
+ const authFailure = detectAuthFailure(stderr)
- if (requiresOtp) {
- logError('OTP required')
- } else if (authFailure) {
- logError('Authentication required - please run "npm login" and restart the connector')
- } else {
- logError(filterNpmWarnings(stderr).split('\n')[0] || 'Command failed')
- }
+ if (requiresOtp) {
+ logError('OTP required')
+ } else if (authFailure) {
+ logError('Authentication required - please run "npm login" and restart the connector')
+ } else {
+ logError(filterNpmWarnings(stderr).split('\n')[0] || 'Command failed')
+ }
- return {
- stdout: err.stdout?.trim() ?? '',
- stderr: requiresOtp
- ? 'This operation requires a one-time password (OTP).'
- : authFailure
- ? 'Authentication failed. Please run "npm login" and restart the connector.'
- : filterNpmWarnings(stderr),
- exitCode: err.code ?? 1,
- requiresOtp,
- authFailure,
- }
+ return {
+ stdout: err.stdout?.trim() ?? '',
+ stderr: requiresOtp
+ ? 'This operation requires a one-time password (OTP).'
+ : authFailure
+ ? 'Authentication failed. Please run "npm login" and restart the connector.'
+ : filterNpmWarnings(stderr),
+ exitCode: err.code ?? 1,
+ requiresOtp,
+ authFailure,
}
- } finally {
- // Clean up temp directory
- await rm(tempDir, { recursive: true, force: true }).catch(() => {
- // Ignore cleanup errors
- })
}
}
diff --git a/cli/src/npm-process.ts b/cli/src/npm-process.ts
new file mode 100644
index 0000000000..44cb6ebfb8
--- /dev/null
+++ b/cli/src/npm-process.ts
@@ -0,0 +1,24 @@
+import process from 'node:process'
+
+interface NpmProcessCommand {
+ command: string
+ args: string[]
+}
+
+export function resolveNpmProcessCommand(
+ npmArgs: string[],
+ platform = process.platform,
+ comSpec = process.env.ComSpec,
+): NpmProcessCommand {
+ if (platform === 'win32') {
+ return {
+ command: comSpec || 'cmd.exe',
+ args: ['/d', '/s', '/c', 'npm', ...npmArgs],
+ }
+ }
+
+ return {
+ command: 'npm',
+ args: npmArgs,
+ }
+}
diff --git a/config/i18n.ts b/config/i18n.ts
index e775400e7c..316a7c6525 100644
--- a/config/i18n.ts
+++ b/config/i18n.ts
@@ -359,6 +359,19 @@ const locales: (LocaleObjectData | (Omit & { code: str
file: 'nb-NO.json',
name: 'Norsk (Bokmรฅl)',
},
+ {
+ code: 'sr-Latn-RS',
+ file: 'sr-Latn-RS.json',
+ name: 'Srpski (Latinica)',
+ pluralRule: createPluralRule('sr-Latn-RS', {
+ zero: 2,
+ one: 0,
+ two: 1,
+ few: 1,
+ many: 2,
+ other: 2,
+ }),
+ },
]
function buildLocales() {
diff --git a/docs/public/favicon.ico b/docs/public/favicon.ico
new file mode 100644
index 0000000000..462aaa3841
Binary files /dev/null and b/docs/public/favicon.ico differ
diff --git a/i18n/locales/ar-EG.json b/i18n/locales/ar-EG.json
index 17d1cb6a35..18682843b5 100644
--- a/i18n/locales/ar-EG.json
+++ b/i18n/locales/ar-EG.json
@@ -161,8 +161,6 @@
},
"page_title": "ุฅุตุฏุงุฑุงุช {name} โ npmx",
"current_tags": "ุงููุณูู
ุงูุญุงููุฉ",
- "version_filter_placeholder": "ุชุตููุฉ ุงูุฅุตุฏุงุฑุงุชโฆ",
- "version_filter_label": "ุชุตููุฉ ุงูุฅุตุฏุงุฑุงุช",
"no_match_filter": "ูุง ุชูุฌุฏ ุฅุตุฏุงุฑุงุช ู
ุทุงุจูุฉ"
},
"dependencies": {
diff --git a/i18n/locales/ar.json b/i18n/locales/ar.json
index 0edd42dcad..131d42deca 100644
--- a/i18n/locales/ar.json
+++ b/i18n/locales/ar.json
@@ -651,12 +651,10 @@
"code": {
"files_label": "ุงูู
ููุงุช",
"no_files": "ูุง ุชูุฌุฏ ู
ููุงุช ูู ูุฐุง ุงูู
ุฌูุฏ",
- "root": "ุงูุฌุฐุฑ",
"lines": "{count} ุณุทุฑ",
"toggle_tree": "ุฅุธูุงุฑ/ุฅุฎูุงุก ุดุฌุฑุฉ ุงูู
ููุงุช",
"close_tree": "ุฅุบูุงู ุดุฌุฑุฉ ุงูู
ููุงุช",
"copy_link": "ูุณุฎ ุงูุฑุงุจุท",
- "raw": "ุฎุงู
(Raw)",
"view_raw": "ุนุฑุถ ุงูู
ูู ุงูุฎุงู
(Raw)",
"file_too_large": "ุงูู
ูู ูุจูุฑ ุฌุฏูุง ููู
ุนุงููุฉ",
"file_size_warning": "{size} ูุชุฌุงูุฒ ุญุฏ 500KB ููุชุธููู ุงููุญูู (syntax highlighting)",
diff --git a/i18n/locales/az-AZ.json b/i18n/locales/az-AZ.json
index 85894165eb..48856ad81b 100644
--- a/i18n/locales/az-AZ.json
+++ b/i18n/locales/az-AZ.json
@@ -755,12 +755,10 @@
"code": {
"files_label": "Fayllar",
"no_files": "Bu qovluqda fayl yoxdur",
- "root": "kรถk",
"lines": "{count} sษtir",
"toggle_tree": "Fayl aฤacฤฑnฤฑ keรงir",
"close_tree": "Fayl aฤacฤฑnฤฑ baฤla",
"copy_link": "Linki kopyala",
- "raw": "Xam",
"view_raw": "Xam faylฤฑ gรถstษr",
"file_too_large": "Fayl รถnbaxฤฑล รผรงรผn รงox bรถyรผkdรผr",
"file_size_warning": "{size} sintaksis vurฤulama รผรงรผn 500KB limitini keรงir",
diff --git a/i18n/locales/bg-BG.json b/i18n/locales/bg-BG.json
index 032d82a6e5..41053f59bb 100644
--- a/i18n/locales/bg-BG.json
+++ b/i18n/locales/bg-BG.json
@@ -716,12 +716,10 @@
"code": {
"files_label": "ะคะฐะนะปะพะฒะต",
"no_files": "ะัะผะฐ ัะฐะนะปะพะฒะต ะฒ ัะฐะทะธ ะดะธัะตะบัะพัะธั",
- "root": "root",
"lines": "{count} ัะตะด | {count} ัะตะดะฐ",
"toggle_tree": "ะัะตะฒะบะปััะฒะฐะฝะต ะฝะฐ ะดััะฒะพัะพ ั ัะฐะนะปะพะฒะต",
"close_tree": "ะะฐัะฒะฐััะฝะต ะฝะฐ ะดััะฒะพัะพ ั ัะฐะนะปะพะฒะต",
"copy_link": "ะะพะฟะธัะฐะฝะต ะฝะฐ ะฒััะทะบะฐ",
- "raw": "Raw",
"view_raw": "ะัะตะณะปะตะด ะฝะฐ raw ัะฐะนะป",
"file_too_large": "ะคะฐะนะปัั ะต ัะฒััะดะต ะณะพะปัะผ ะทะฐ ะฟัะตะณะปะตะด",
"file_size_warning": "{size} ะฝะฐะดะฒะธัะฐะฒะฐ ะปะธะผะธัะฐ ะพั 500KB ะทะฐ ัะธะฝัะฐะบัะธัะฝะพ ะพัะฒะตััะฒะฐะฝะต",
diff --git a/i18n/locales/bn-IN.json b/i18n/locales/bn-IN.json
index 39d19eec65..ff7cf7ee7f 100644
--- a/i18n/locales/bn-IN.json
+++ b/i18n/locales/bn-IN.json
@@ -545,12 +545,10 @@
"code": {
"files_label": "เฆซเฆพเฆเฆฒเฆเงเฆฒเฆฟ",
"no_files": "เฆเฆ เฆกเฆพเฆเฆฐเงเฆเงเฆเฆฐเฆฟเฆคเง เฆเงเฆจเง เฆซเฆพเฆเฆฒ เฆจเงเฆ",
- "root": "เฆฐเงเฆ",
"lines": "{count}เฆเฆฟ เฆฒเฆพเฆเฆจ",
"toggle_tree": "เฆซเฆพเฆเฆฒ เฆเงเฆฐเฆฟ เฆเฆเฆฒ เฆเฆฐเงเฆจ",
"close_tree": "เฆซเฆพเฆเฆฒ เฆเงเฆฐเฆฟ เฆฌเฆจเงเฆง เฆเฆฐเงเฆจ",
"copy_link": "เฆฒเฆฟเฆเงเฆ เฆเฆชเฆฟ เฆเฆฐเงเฆจ",
- "raw": "เฆฐเฆ",
"view_raw": "เฆฐเฆ เฆซเฆพเฆเฆฒ เฆฆเงเฆเงเฆจ",
"file_too_large": "เฆชเงเฆฐเฆฟเฆญเฆฟเฆ-เฆฐ เฆเฆจเงเฆฏ เฆซเฆพเฆเฆฒ เฆเงเฆฌ เฆฌเฆกเฆผ",
"file_size_warning": "{size} เฆธเฆฟเฆจเฆเงเฆฏเฆพเฆเงเฆธ เฆนเฆพเฆเฆฒเฆพเฆเฆเฆฟเฆ-เฆเฆฐ เฆเฆจเงเฆฏ 500KB เฆธเงเฆฎเฆพเฆฐ เฆเงเฆฏเฆผเง เฆฌเงเฆถเฆฟ",
diff --git a/i18n/locales/cs-CZ.json b/i18n/locales/cs-CZ.json
index 638904c4fb..5aececf416 100644
--- a/i18n/locales/cs-CZ.json
+++ b/i18n/locales/cs-CZ.json
@@ -19,7 +19,8 @@
"social": "sociรกlnรญ sรญtฤ",
"chat": "chat",
"builders_chat": "stavitelรฉ",
- "keyboard_shortcuts": "klรกvesovรฉ zkratky"
+ "keyboard_shortcuts": "klรกvesovรฉ zkratky",
+ "brand": "znaฤka"
},
"shortcuts": {
"section": {
@@ -36,7 +37,9 @@
"go_to_result": "Pลejรญt na vรฝsledek",
"open_code_view": "Otevลรญt zobrazenรญ kรณdu",
"open_docs": "Otevลรญt dokumentaci",
- "disable_shortcuts": "Klรกvesovรฉ zkratky mลฏลพete zakรกzat v {settings}."
+ "disable_shortcuts": "Klรกvesovรฉ zkratky mลฏลพete zakรกzat v {settings}.",
+ "open_main": "Otevลรญt hlavnรญ informace",
+ "open_diff": "Otevลรญt rozdรญly verzรญ"
},
"search": {
"label": "Hledat npm balรญฤky",
@@ -94,6 +97,7 @@
},
"draft_badge": "Nรกvrh",
"draft_banner": "Toto je nepublikovanรฝ nรกvrh. Mลฏลพe bรฝt neรบplnรฝ nebo obsahovat nepลesnosti.",
+ "no_posts": "Nebyly nalezeny ลพรกdnรฉ pลรญspฤvky.",
"atproto": {
"view_on_bluesky": "Zobrazit na Bluesky",
"reply_on_bluesky": "Odpovฤdฤt na Bluesky",
@@ -136,19 +140,33 @@
"include_types_description": "Pลidat balรญฤek {'@'}types do instalaฤnรญch pลรญkazลฏ pro balรญฤky bez integrovanรฝch typลฏ",
"hide_platform_packages": "Skrรฝt platformnฤ specifickรฉ balรญฤky ve vyhledรกvรกnรญ",
"hide_platform_packages_description": "Skrรฝt nativnรญ binรกrnรญ balรญฤky jako {'@'}esbuild/linux-x64 z vรฝsledkลฏ",
+ "enable_graph_pulse_loop": "Povolit smyฤku efektu pulzovรกnรญ na mini grafu",
+ "enable_graph_pulse_loop_description": "Aktivovat kontinuรกlnรญ animaci pulzu na grafu tรฝdennรญch staลพenรญ. Tato animace mลฏลพe bรฝt pro nฤkterรฉ uลพivatele ruลกivรก.",
"theme": "Tรฉma",
"theme_light": "Svฤtlรฉ",
"theme_dark": "Tmavรฉ",
"theme_system": "Systรฉmovรฉ",
"language": "Jazyk",
"help_translate": "Pomozte pลeloลพit npmx",
+ "translation_status": "Zkontrolovat globรกlnรญ stav pลekladu",
"accent_colors": {
- "label": "Barvy akcentu"
+ "label": "Barvy akcentu",
+ "sky": "Obloha",
+ "coral": "Korรกl",
+ "amber": "Jantar",
+ "emerald": "Smaragd",
+ "violet": "Fialovรก",
+ "magenta": "Magenta"
},
"clear_accent": "Vymazat barvu akcentu",
"translation_progress": "Pokrok pลekladu",
"background_themes": {
- "label": "Odstรญn pozadรญ"
+ "label": "Odstรญn pozadรญ",
+ "neutral": "Neutrรกlnรญ",
+ "stone": "Kรกmen",
+ "zinc": "Zinek",
+ "slate": "Bลidlice",
+ "black": "ฤernรก"
},
"keyboard_shortcuts_enabled": "Povolit klรกvesovรฉ zkratky",
"keyboard_shortcuts_enabled_description": "Klรกvesovรฉ zkratky lze zakรกzat, pokud se stลetรกvajรญ s jinรฝmi zkratkami prohlรญลพeฤe nebo systรฉmu"
@@ -207,7 +225,9 @@
"radicle": "Zobrazit na Radicle",
"sourcehut": "Zobrazit na SourceHutu",
"tangled": "Zobrazit na Tangled"
- }
+ },
+ "collapse": "Sbalit",
+ "expand": "Rozbalit"
},
"profile": {
"display_name": "Zobrazovanรฉ jmรฉno",
@@ -286,9 +306,11 @@
"refs": "{count} odkaz | {count} odkazy | {count} odkazลฏ",
"assets": "{count} zdroj | {count} zdroje | {count} zdrojลฏ"
},
- "view_source": "Zobrazit zdroj"
+ "view_source": "Zobrazit zdroj",
+ "skills_cli": "CLI dovednosti"
},
"links": {
+ "main": "domลฏ",
"repo": "repozitรกล",
"homepage": "domovskรก strรกnka",
"issues": "รบkoly",
@@ -296,15 +318,23 @@
"code": "kรณd",
"docs": "dokumentace",
"fund": "financovat",
- "compare": "porovnat"
+ "compare": "porovnat",
+ "compare_this_package": "porovnat tento balรญฤek"
},
"likes": {
"like": "Lรญbรญ se mi tento balรญฤek",
"unlike": "Nelรญbรญ se mi tento balรญฤek"
},
"docs": {
+ "contents": "Obsah",
+ "default_not_available": "Dokumentace tรฉto verze nenรญ k dispozici.",
"not_available": "Dokumentace nenรญ k dispozici",
- "not_available_detail": "Nepodaลilo se nรกm vygenerovat dokumentaci pro tuto verzi."
+ "not_available_detail": "Nepodaลilo se nรกm vygenerovat dokumentaci pro tuto verzi.",
+ "page_title": "API dokumentace - npmx",
+ "page_title_name": "Dokumentace {name} - npmx",
+ "page_title_version": "Dokumentace {name} - npmx",
+ "og_title": "{name} - Dokumentace",
+ "view_package": "Zobrazit balรญฤek"
},
"get_started": {
"title": "Zaฤรญnรกme",
@@ -364,7 +394,9 @@
"published": "Publikovรกno",
"weekly_downloads": "Tรฝdennรญ staลพenรญ",
"keywords": "Klรญฤovรก slova",
- "license": "Licence"
+ "license": "Licence",
+ "select": "Vybrat balรญฤek",
+ "select_maximum": "Maximรกlnฤ lze vybrat {count} balรญฤkลฏ"
},
"versions": {
"title": "Verze",
@@ -379,6 +411,7 @@
"all_covered": "Vลกechny verze jsou pokryty vรฝลกe uvedenรฝmi tagy",
"deprecated_title": "{version} (zastaralรก)",
"view_all": "Zobrazit {count} verzi | Zobrazit {count} verze | Zobrazit {count} verzรญ",
+ "view_all_versions": "Zobrazit vลกechny verze",
"distribution_title": "Skupina Semver",
"distribution_modal_title": "Verze",
"distribution_range_date_same_year": "od {from} do {to}, {endYear}",
@@ -386,10 +419,13 @@
"grouping_major": "Hlavnรญ",
"grouping_minor": "Vedlejลกรญ",
"grouping_versions_title": "Verze",
+ "grouping_versions_about": "O seskupovรกnรญ verzรญ",
"grouping_versions_all": "Vลกechny",
"grouping_versions_only_recent": "Pouze nedรกvnรฉ",
"grouping_usage_title": "Pouลพitรญ",
+ "grouping_usage_about": "O seskupovรกnรญ uลพitรญ",
"grouping_usage_all": "Vลกechno",
+ "grouping_usage_most_used": "Nejฤastฤji pouลพรญvanรฉ",
"recent_versions_only_tooltip": "Zobrazit pouze verze zveลejnฤnรฉ v poslednรญm roce.",
"show_low_usage_tooltip": "Zahrnout skupiny verzรญ s mรฉnฤ neลพ 1 % celkovรฝch staลพenรญ.",
"y_axis_label": "Staลพenรญ",
@@ -402,7 +438,10 @@
"copy_alt": {
"per_version_analysis": "Verze {version} byla staลพena {downloads} krรกt",
"general_description": "Sloupcovรฝ graf zobrazujรญcรญ staลพenรญ podle verzรญ pro {versions_count} {semver_grouping_mode} verze balรญฤku {package_name}, {date_range_label} od verze {first_version} do verze {last_version}. Nejvรญce staลพenรก verze je {max_downloaded_version} s {max_version_downloads} staลพenรญmi. {per_version_analysis}. {watermark}."
- }
+ },
+ "page_title": "Historie verzรญ",
+ "current_tags": "Aktuรกlnรญ znaฤky",
+ "no_match_filter": "ลฝรกdnรฉ verze neodpovรญdajรญ {filter}"
},
"dependencies": {
"title": "Zรกvislosti ({count})",
@@ -413,7 +452,8 @@
"outdated_major": "o {count} hlavnรญ verzi pozadu (nejnovฤjลกรญ: {latest}) | o {count} hlavnรญ verze pozadu (nejnovฤjลกรญ: {latest}) | o {count} hlavnรญch verzรญch pozadu (nejnovฤjลกรญ: {latest})",
"outdated_minor": "o {count} vedlejลกรญ verzi pozadu (nejnovฤjลกรญ: {latest}) | o {count} vedlejลกรญ verze pozadu (nejnovฤjลกรญ: {latest}) | o {count} vedlejลกรญch verzรญch pozadu (nejnovฤjลกรญ: {latest})",
"outdated_patch": "Aktualizace zรกplaty dostupnรก (nejnovฤjลกรญ: {latest})",
- "has_replacement": "Tato zรกvislost mรก navrhovanรฉ nรกhrady"
+ "has_replacement": "Tato zรกvislost mรก navrhovanรฉ nรกhrady",
+ "vulnerabilities_count": "{count} zranitelnost | {count} zranitelnosti | {count} zranitelnostรญ"
},
"peer_dependencies": {
"title": "Vzรกjemnรฉ zรกvislosti ({count})",
@@ -437,9 +477,19 @@
"cancel_add": "Zruลกit pลidรกnรญ vlastnรญka",
"add_owner": "+ Pลidat vlastnรญka",
"show_more": "(zobrazit {count} dalลกรญho) | (zobrazit {count} dalลกรญ) | (zobrazit {count} dalลกรญch)",
- "show_less": "(zobrazit mรฉnฤ)"
+ "show_less": "(zobrazit mรฉnฤ)",
+ "maintainer_template": "{avatar} {char126}{name}"
},
"trends": {
+ "chart_assistive_text": {
+ "keyboard_navigation_horizontal": "Pouลพijte klรกvesy se ลกipkami vlevo a vpravo pro prochรกzenรญ datovรฝmi body.",
+ "keyboard_navigation_vertical": "Pouลพijte klรกvesy se ลกipkami nahoru a dolลฏ pro prochรกzenรญ datovรฝmi body.",
+ "table_available": "Tabulka dat pro tento graf je k dispozici nรญลพe.",
+ "table_caption": "Tabulka dat grafu"
+ },
+ "chart_view_toggle": "Pลepnout typ grafu",
+ "chart_view_combined": "Kombinovanรฝ pohled",
+ "chart_view_split": "Rozdฤlenรฝ pohled",
"granularity": "Rozliลกenรญ",
"granularity_daily": "Dennฤ",
"granularity_weekly": "Tรฝdnฤ",
@@ -469,6 +519,7 @@
"data_correction": "Oprava dat",
"average_window": "Okno prลฏmฤru",
"smoothing": "Vyhlazovรกnรญ",
+ "prediction": "Predikce",
"known_anomalies": "Znรกmรฉ anomรกlie",
"known_anomalies_description": "Interpoluje pลes znรกmรฉ ลกpiฤky staลพenรญ zpลฏsobenรฉ boty nebo problรฉmy s CI.",
"known_anomalies_ranges": "Rozsahy anomรกliรญ",
@@ -497,7 +548,8 @@
"downloads": {
"title": "Tรฝdennรญ staลพenรญ",
"community_distribution": "Zobrazit rozloลพenรญ adopce v komunitฤ",
- "subtitle": "Napลรญฤ vลกemi verzemi"
+ "subtitle": "Napลรญฤ vลกemi verzemi",
+ "sparkline_nav_hint": "Pouลพijte โ โ"
},
"install_scripts": {
"title": "Instalaฤnรญ skripty",
@@ -513,6 +565,7 @@
"esm": "ES Moduly podporovรกny",
"cjs": "CommonJS podporovรกno",
"no_esm": "Bez podpory ES Modulลฏ",
+ "wasm": "Obsahuje WebAssembly",
"types_label": "Typy",
"types_included": "Typy zahrnuty",
"types_available": "Typy dostupnรฉ pลes {package}",
@@ -587,7 +640,10 @@
"kb": "{size} kB",
"mb": "{size} MB"
},
- "download": {}
+ "download": {
+ "button": "Stรกhnout",
+ "tarball": "Stรกhnout Tarball jako .tar.gz"
+ }
},
"connector": {
"modal": {
@@ -767,13 +823,15 @@
"code": {
"files_label": "Soubory",
"no_files": "ลฝรกdnรฉ soubory v tรฉto sloลพce",
- "root": "koลen",
"lines": "{count} ลรกdkลฏ",
"toggle_tree": "Pลepnout strom souborลฏ",
"close_tree": "Zavลรญt strom souborลฏ",
+ "copy_content": "Zkopรญrovat obsah souboru",
"copy_link": "Kopรญrovat odkaz",
- "raw": "Raw",
"view_raw": "Zobrazit raw soubor",
+ "toggle_container": "Pลepnout ลกรญลku kontejneru kรณdu",
+ "open_raw_file": "Otevลรญt soubor jako kรณd",
+ "open_path_dropdown": "Otevลรญt rozbalovacรญ seznam segmentลฏ cesty",
"file_too_large": "Soubor je pลรญliลก velkรฝ pro nรกhled",
"file_size_warning": "{size} pลekraฤuje limit 500KB pro zvรฝraznฤnรญ syntaxe",
"failed_to_load": "Nepodaลilo se naฤรญst soubor",
@@ -791,7 +849,9 @@
"preview": "nรกhled",
"code": "kรณd"
},
- "file_path": "Cesta k souboru"
+ "file_path": "Cesta k souboru",
+ "binary_file": "Binรกrnรญ soubor",
+ "binary_rendering_warning": "Nรกhled pro typy souborลฏ \"{contentType}\" nenรญ k dispozici."
},
"badges": {
"provenance": {
@@ -853,6 +913,8 @@
"secure": "Bez varovรกnรญ",
"insecure": "S varovรกnรญmi"
},
+ "view_selected": "Zobrazit vybranรฉ",
+ "clear_selected_label": "Vyฤistit vybranรฉ",
"sort": {
"label": "Seลadit podle",
"toggle_direction": "Pลepnout smฤr ลazenรญ",
@@ -878,7 +940,8 @@
"published": "Naposledy publikovรกno",
"maintainers": "Sprรกvci",
"keywords": "Klรญฤovรก slova",
- "security": "Bezpeฤnost"
+ "security": "Bezpeฤnost",
+ "selection": "Vybrat balรญฤek"
},
"view_mode": {
"label": "Reลพim zobrazenรญ",
@@ -1025,7 +1088,8 @@
"error": "Nepodaลilo se naฤรญst organizace",
"empty": "Nebyly nalezeny ลพรกdnรฉ organizace",
"view_all": "Zobrazit vลกe"
- }
+ },
+ "pr": "Otevลรญt GitHub PR #{prNumber}"
},
"compare": {
"packages": {
@@ -1044,7 +1108,10 @@
"empty_title": "Vyberte balรญฤky k porovnรกnรญ",
"empty_description": "Vyhledejte a pลidejte alespoล 2 balรญฤky vรฝลกe, abyste vidฤli porovnรกnรญ jejich metrik vedle sebe.",
"table_view": "Tabulka",
- "charts_view": "Grafy"
+ "charts_view": "Grafy",
+ "no_chartable_data": "Pro vybranรฉ kategorie nejsou k dispozici ลพรกdnรก data pro graf.",
+ "bar_chart_nav_hint": "Pouลพijte โ โ",
+ "line_chart_nav_hint": "Pouลพijte โ โ"
},
"selector": {
"search_label": "Vyhledat balรญฤky",
@@ -1067,6 +1134,10 @@
"facets": {
"all": "Vลกe",
"none": "ลฝรกdnรฉ",
+ "select_all_category_facets": "Vybrat vลกechny vlastnosti kategorie {category}",
+ "deselect_all_category_facets": "Zruลกit vรฝbฤr vลกech vlastnostรญ kategorie {category}",
+ "selected_all_category_facets": "Vybranรฉ vลกechny vlastnosti kategorie {category}",
+ "deselected_all_category_facets": "Zruลกen vรฝbฤr vลกech vlastnostรญ kategorie {category}",
"coming_soon": "Brzy k dispozici",
"select_all": "Vybrat vลกechny vlastnosti",
"deselect_all": "Zruลกit vรฝbฤr vลกech vlastnostรญ",
@@ -1153,7 +1224,15 @@
"file_size_warning": "{size} pลekraฤuje limit 250KB pro porovnรกnรญ",
"compare_versions": "porovnat",
"compare_versions_title": "Porovnat s nejnovฤjลกรญ verzรญ",
- "version_invalid_url_format": {},
+ "comparing_versions_label": "Porovnรกnรญ verzรญ...",
+ "version_back_to_package": "Zpฤt na balรญฤek",
+ "version_error_message": "Nepodaลilo se porovnat verze.",
+ "version_invalid_url_format": {
+ "hint": "Chybnรก URL pro porovnรกnรญ. Pouลพijte formรกt: {0}",
+ "from_version": "od",
+ "to_version": "do"
+ },
+ "version_selector_title": "Porovnat s verzรญ",
"summary": "Souhrn",
"deps_count": "{count} zรกvislostรญ",
"dependencies": "Zรกvislosti",
@@ -1179,7 +1258,18 @@
"files_button": "Soubory",
"select_file_prompt": "Vyberte soubor z postrannรญho panelu pro zobrazenรญ jeho rozdรญlลฏ",
"close_files_panel": "Zavลรญt panel souborลฏ",
- "filter_files_label": "Filtrovat soubory podle typu zmฤny"
+ "filter_files_label": "Filtrovat soubory podle typu zmฤny",
+ "change_ratio": "Pomฤr zmฤn",
+ "char_edits": "Zmฤny znakลฏ",
+ "diff_distance": "Vzdรกlenost rozdรญlลฏ",
+ "loading_diff": "Naฤรญtรกnรญ rozdรญlลฏ...",
+ "loading_diff_error": "Nepodaลilo se naฤรญst rozdรญly",
+ "merge_modified_lines": "Slouฤit upravenรฉ ลรกdky",
+ "no_content_changes": "Nebyly zjiลกtฤny ลพรกdnรฉ zmฤny obsahu",
+ "options": "Moลพnosti",
+ "view_file": "Zobrazit soubor",
+ "view_in_code_browser": "Zobrazit v prohlรญลพeฤi kรณdu",
+ "word_wrap": "Zalomenรญ slov"
},
"pds": {
"title": "npmx.social",
@@ -1320,7 +1410,117 @@
}
},
"translation_status": {
- "table": {}
+ "title": "stav pลekladu",
+ "generated_at": "Vygenerovรกno: {date}",
+ "welcome": "Pokud mรกte zรกjem pomoci nรกm pลeloลพit {npmx} do jednoho z nรญลพe uvedenรฝch jazykลฏ, jste na sprรกvnรฉm mรญstฤ! Tato strรกnka se automaticky aktualizuje a vลพdy zobrazuje veลกkerรฝ obsah, kterรฝ prรกvฤ potลebuje vaลกi pomoc.",
+ "p1": "Jako vรฝchozรญ jazyk pouลพรญvรกme {lang}, s celkovรฝm poฤtem {count}. Pokud chcete pomoci s pลidรกvรกnรญm pลekladลฏ, najdฤte jazyk v {bylang} a rozbalte podrobnosti.",
+ "p1_lang": "americkou angliฤtinu (en-US)",
+ "p1_count": "1 text | {count} texty | {count} textลฏ",
+ "p2": "Neลพ zaฤnete, pลeฤtฤte si prosรญm naลกeho {guide}, abyste se seznรกmili s naลกรญm procesem pลekladu a zjistili, jak se mลฏลพete zapojit.",
+ "guide": "prลฏvodce lokalizacรญ (i18n)",
+ "by_locale": "Pokrok pลekladu podle jazyka",
+ "by_file": "Pokrok pลekladu podle souboru",
+ "complete_text": "Tento pลeklad je dokonฤen, skvฤlรก prรกce!",
+ "missing_text": "chybรญ",
+ "missing_keys": "{count} chybฤjรญcรญ pลeklad | {count} chybฤjรญcรญ pลeklady | {count} chybฤjรญcรญch pลekladลฏ",
+ "progress_label": "Pokrok pลekladu do jazyka {locale}",
+ "table": {
+ "file": "Soubor",
+ "status": "Stav",
+ "error": "Chyba pลi naฤรญtรกnรญ seznamu souborลฏ.",
+ "empty": "ลฝรกdnรฉ soubory nebyly nalezeny",
+ "file_link": "Upravit {file} ({lang}) na GitHubu"
+ }
+ },
+ "vacations": {
+ "title": "na dovolenรฉ",
+ "meta_description": "Tรฝm npmx si odpoฤinul. Discord se po tรฝdnu znovu otevลel.",
+ "heading": "dobรญjรญme se",
+ "subtitle": "Budovali jsme npmx tempem, kterรฉ {some} stรกlo spรกnek. Nechtฤli jsme, aby se to stalo normou! Tak jsme si vzali na tรฝden volno. Spoleฤnฤ.",
+ "illustration_alt": "ลada hezkรฝch ikonek",
+ "poke_log": "ล ลฅouchnout do ohniลกtฤ",
+ "what": {
+ "title": "co se stalo",
+ "p1": "discord byl uzavลen {dates}.",
+ "dates": "14. โ 21. รบnora",
+ "p2": "vลกechny pozvรกnky byly uzavลeny a kanรกly byly uzamฤeny โ kromฤ {garden}, kterรฝ zลฏstal otevลenรฝ pro ty, kteลรญ se chtฤli dรกl bavit.",
+ "garden": "#garden"
+ },
+ "meantime": {
+ "title": "mezitรญm",
+ "p1": "{site} a {repo} zลฏstaly otevลenรฉ โ lidรฉ se stรกle zapojovali, vรฝtvรกลeli dalลกรญ รบkoly, otevรญrali nฤkolik PR, ale hlavnฤ vลกichni trรกvili ฤas nฤkde poblรญลพ รบtulnรฉho krbu.",
+ "repo_link": "repozitรกล"
+ },
+ "return": {
+ "title": "jsme zpฤt!",
+ "p1": "vrรกtili jsme se odpoฤatรญ a pลipraveni na poslednรญ pลรญpravy pลed 3. bลeznem. {social}.",
+ "social_link": "sledujte nรกs na Bluesky"
+ },
+ "stats": {
+ "contributors": "Pลispฤvatelรฉ",
+ "commits": "Commity",
+ "pr": "Mergnutรก PR",
+ "subtitle": {
+ "some": "pรกr z nรกs",
+ "all": "nรกs vลกechny"
+ }
+ }
+ },
+ "action_bar": {
+ "title": "panel akcรญ",
+ "selection": "vybrรกn {count} | vybrรกny {count} | vybrรกno {count}",
+ "shortcut": "Stisknฤte \"{key}\" pro zamฤลenรญ akcรญ",
+ "button_close_aria_label": "Zavลรญt panel akcรญ"
+ },
+ "logo_menu": {
+ "copy_svg": "Zkopรญrovat logo jako SVG",
+ "copied": "Zkopรญrovรกno!",
+ "browse_brand": "Prochรกzet sadu znaฤky"
+ },
+ "brand": {
+ "title": "Znaฤka",
+ "heading": "znaฤka",
+ "meta_description": "Pokyny k znaฤce npmx, loga, barvy a typografie pro pouลพitรญ v tisku a mรฉdiรญch.",
+ "intro": "Zdroje a pokyny pro pouลพรญvรกnรญ znaฤky npmx ve vaลกich projektech, ฤlรกncรญch a mรฉdiรญch.",
+ "logos": {
+ "title": "loga",
+ "description": "Stรกhnฤte si loga npmx ve formรกtech SVG a PNG. Pouลพijte vhodnou variantu pro vaลกe pozadรญ.",
+ "wordmark": "PLNร LOGO",
+ "wordmark_alt": "Celรฉ npmx logo s nรกzvem, teฤkou a lomรญtkem na tmavรฉm pozadรญ",
+ "wordmark_light_alt": "Celรฉ npmx logo s nรกzvem, teฤkou a lomรญtkem na svฤtlรฉm pozadรญ",
+ "mark": "KRรTKร LOGO",
+ "mark_alt": "Logo npmx pouze s teฤkou a lomรญtkem na tmavรฉm pozadรญ",
+ "mark_light_alt": "Logo npmx pouze s teฤkou a lomรญtkem na svฤtlรฉm pozadรญ",
+ "on_dark": "na tmavรฉm pozadรญ",
+ "on_light": "na svฤtlรฉm pozadรญ",
+ "download_svg": "SVG",
+ "download_png": "PNG",
+ "download_svg_aria": "Stรกhnout {name} jako SVG",
+ "download_png_aria": "Stรกhnout {name} jako PNG"
+ },
+ "customize": {
+ "title": "pลizpลฏsobte si svรฉ logo",
+ "description": "Nรกhled loga npmx s vรกmi vybranou akcentnรญ barvou a pozadรญm. Nรกhled odrรกลพรญ vaลกe aktuรกlnรญ nastavenรญ โ vyberte barvu, pozadรญ a stรกhnฤte.",
+ "accent_label": "akcent",
+ "bg_label": "pozadรญ",
+ "download_svg_aria": "Stรกhnout pลizpลฏsobenรฉ logo jako SVG",
+ "download_png_aria": "Stรกhnout pลizpลฏsobenรฉ logo jako PNG"
+ },
+ "typography": {
+ "title": "typografie",
+ "description": "npmx pouลพรญvรก rodinu pรญsem Geist od Vercelu pro texty rozhranรญ i kรณd.",
+ "sans": "Geist Sans",
+ "sans_desc": "Pouลพรญvรก se pro texty tฤla a prvky uลพivatelskรฉho rozhranรญ.",
+ "mono": "Geist Mono",
+ "mono_desc": "Pouลพรญvรก se pro kรณd, nadpisy a technickรฝ obsah.",
+ "pangram": "Pลรญliลก ลพluลฅouฤkรฝ kลฏล รบpฤl ฤรกbelskรฉ รณdy",
+ "numbers": "0123456789"
+ },
+ "guidelines": {
+ "title": "jen maliฤkost",
+ "message": "Pลรญstupnost je pro nรกs dลฏleลพitรก a rรกdi bychom, abyste se k nรกm pลipojili v tรฉto vizi. Pลi pouลพรญvรกnรญ zmรญnฤnรฝch mรฉdiรญ zajistฤte dostateฤnรฝ kontrast vลฏฤi pozadรญ a nepouลพรญvejte velikost menลกรญ neลพ 24px. Pokud potลebujete dalลกรญ zdroje nebo dalลกรญ informace o projektu, nevรกhejte nรกs kontaktovat na {link}.",
+ "discord_link_text": "chat.npmx.dev"
+ }
},
- "action_bar": {}
+ "alt_logo_kawaii": "Roztomilรก, zaoblenรก a barevnรก verze loga npmx."
}
diff --git a/i18n/locales/de.json b/i18n/locales/de.json
index 4a17bed86d..42c71738f8 100644
--- a/i18n/locales/de.json
+++ b/i18n/locales/de.json
@@ -440,8 +440,6 @@
},
"page_title": "Versionshistorie",
"current_tags": "Aktuelle Tags",
- "version_filter_placeholder": "Versionen filternโฆ",
- "version_filter_label": "Versionen filtern",
"no_match_filter": "Keine Versionen entsprechen {filter}"
},
"dependencies": {
@@ -821,12 +819,10 @@
"code": {
"files_label": "Dateien",
"no_files": "Keine Dateien in diesem Verzeichnis",
- "root": "Wurzel",
"lines": "{count} Zeile | {count} Zeilen",
"toggle_tree": "Dateibaum umschalten",
"close_tree": "Dateibaum schlieรen",
"copy_link": "Link kopieren",
- "raw": "Roh",
"view_raw": "Rohdatei anzeigen",
"file_too_large": "Datei zu groร fรผr Vorschau",
"file_size_warning": "{size} รผberschreitet das 500KB-Limit fรผr Syntax-Highlighting",
@@ -1462,5 +1458,12 @@
"selection": "0 ausgewรคhlt | 1 ausgewรคhlt | {count} ausgewรคhlt",
"shortcut": "Drรผcke โ{key}โ, um Aktionen zu fokussieren",
"button_close_aria_label": "Aktionsleiste schlieรen"
+ },
+ "logo_menu": {},
+ "brand": {
+ "logos": {},
+ "customize": {},
+ "typography": {},
+ "guidelines": {}
}
}
diff --git a/i18n/locales/en.json b/i18n/locales/en.json
index 16c891ae47..c073827c3f 100644
--- a/i18n/locales/en.json
+++ b/i18n/locales/en.json
@@ -441,8 +441,6 @@
},
"page_title": "Version History",
"current_tags": "Current Tags",
- "version_filter_placeholder": "Filter versionsโฆ",
- "version_filter_label": "Filter versions",
"no_match_filter": "No versions match {filter}"
},
"dependencies": {
@@ -825,13 +823,15 @@
"code": {
"files_label": "Files",
"no_files": "No files in this directory",
- "root": "root",
"lines": "{count} line | {count} lines",
"toggle_tree": "Toggle file tree",
"close_tree": "Close file tree",
+ "copy_content": "Copy file content",
"copy_link": "Copy link",
- "raw": "Raw",
"view_raw": "View raw file",
+ "toggle_container": "Toggle code container width",
+ "open_raw_file": "Open raw file",
+ "open_path_dropdown": "Open path segments dropdown",
"file_too_large": "File too large to preview",
"file_size_warning": "{size} exceeds the 500KB limit for syntax highlighting",
"failed_to_load": "Failed to load file",
@@ -846,8 +846,8 @@
"size": "Size"
},
"markdown_view_mode": {
- "preview": "preview",
- "code": "code"
+ "preview": "Preview",
+ "code": "Code"
},
"file_path": "File path",
"binary_file": "Binary file",
diff --git a/i18n/locales/es.json b/i18n/locales/es.json
index 3fe046fe23..7955c16958 100644
--- a/i18n/locales/es.json
+++ b/i18n/locales/es.json
@@ -19,7 +19,8 @@
"social": "social",
"chat": "chat",
"builders_chat": "builders",
- "keyboard_shortcuts": "atajos de teclado"
+ "keyboard_shortcuts": "atajos de teclado",
+ "brand": "marca"
},
"shortcuts": {
"section": {
@@ -96,6 +97,7 @@
},
"draft_badge": "Borrador",
"draft_banner": "Este es un borrador no publicado. Puede estar incompleto o contener inexactitudes.",
+ "no_posts": "No se encontraron publicaciones.",
"atproto": {
"view_on_bluesky": "Ver en Bluesky",
"reply_on_bluesky": "Responder en Bluesky",
@@ -138,19 +140,33 @@
"include_types_description": "Aรฑadir paquete {'@'}types a los comandos de instalaciรณn para paquetes sin tipos",
"hide_platform_packages": "Ocultar paquetes especรญficos de plataforma en la bรบsqueda",
"hide_platform_packages_description": "Ocultar paquetes binarios nativos como {'@'}esbuild/linux-x64 de los resultados",
+ "enable_graph_pulse_loop": "Activar bucle del efecto de pulsaciรณn en el mini grรกfico",
+ "enable_graph_pulse_loop_description": "Activar una animaciรณn de pulso continua en el grรกfico de descargas semanales. Esta animaciรณn puede distraer a algunos usuarios.",
"theme": "Tema",
"theme_light": "Claro",
"theme_dark": "Oscuro",
"theme_system": "Sistema",
"language": "Idioma",
"help_translate": "Ayuda a traducir npmx",
+ "translation_status": "Comprueba el estado global de las traducciones",
"accent_colors": {
- "label": "Colores de acento"
+ "label": "Colores de acento",
+ "sky": "Cielo",
+ "coral": "Coral",
+ "amber": "รmbar",
+ "emerald": "Esmeralda",
+ "violet": "Violeta",
+ "magenta": "Magenta"
},
"clear_accent": "Limpiar color de acento",
"translation_progress": "Progreso de traducciรณn",
"background_themes": {
- "label": "Tema de fondo"
+ "label": "Tema de fondo",
+ "neutral": "Neutral",
+ "stone": "Piedra",
+ "zinc": "Cinc",
+ "slate": "Pizarra",
+ "black": "Negro"
},
"keyboard_shortcuts_enabled": "Activar atajos de teclado",
"keyboard_shortcuts_enabled_description": "Los atajos de teclado pueden desactivarse si entran en conflicto con otros atajos del navegador o del sistema"
@@ -209,7 +225,9 @@
"radicle": "Ver en Radicle",
"sourcehut": "Ver en SourceHut",
"tangled": "Ver en Tangled"
- }
+ },
+ "collapse": "Contraer",
+ "expand": "Expandir"
},
"profile": {
"display_name": "Nombre visible",
@@ -288,7 +306,8 @@
"refs": "{count} referencia | {count} referencias",
"assets": "{count} recurso | {count} recursos"
},
- "view_source": "Ver fuente"
+ "view_source": "Ver fuente",
+ "skills_cli": "CLI de habilidades"
},
"links": {
"main": "principal",
@@ -299,15 +318,23 @@
"code": "cรณdigo",
"docs": "documentaciรณn",
"fund": "financiar",
- "compare": "comparar"
+ "compare": "comparar",
+ "compare_this_package": "comparar este paquete"
},
"likes": {
"like": "Me gusta este paquete",
"unlike": "Ya no me gusta este paquete"
},
"docs": {
+ "contents": "Contenido",
+ "default_not_available": "La documentaciรณn no estรก disponible para esta versiรณn.",
"not_available": "Documentaciรณn no disponible",
- "not_available_detail": "No pudimos generar documentaciรณn para esta versiรณn."
+ "not_available_detail": "No pudimos generar documentaciรณn para esta versiรณn.",
+ "page_title": "Documentaciรณn de la API - npmx",
+ "page_title_name": "Documentaciรณn de {name} - npmx",
+ "page_title_version": "Documentaciรณn de {name} - npmx",
+ "og_title": "{name} - Documentaciรณn",
+ "view_package": "Ver paquete"
},
"get_started": {
"title": "Empezar",
@@ -367,21 +394,24 @@
"published": "Publicado",
"weekly_downloads": "Descargas semanales",
"keywords": "Palabras clave",
- "license": "Licencia"
+ "license": "Licencia",
+ "select": "Seleccionar paquete",
+ "select_maximum": "Se pueden seleccionar como mรกximo {count} paquetes"
},
"versions": {
"title": "Versiones",
- "collapse": "Colapsar {tag}",
+ "collapse": "Contraer {tag}",
"expand": "Expandir {tag}",
- "collapse_other": "Colapsar otras versiones",
+ "collapse_other": "Contraer otras versiones",
"expand_other": "Expandir otras versiones",
- "collapse_major": "Colapsar mayor {major}",
+ "collapse_major": "Contraer mayor {major}",
"expand_major": "Expandir mayor {major}",
"other_versions": "Otras versiones",
"more_tagged": "{count} mรกs etiquetada | {count} mรกs etiquetadas",
"all_covered": "Todas las versiones estรกn cubiertas por las etiquetas anteriores",
"deprecated_title": "{version} (obsoleto)",
- "view_all": "Ver {count} versiรณn | Ver todas las {count} versiones",
+ "view_all": "Ver {count} versiรณn | Ver las {count} versiones",
+ "view_all_versions": "Ver todas las versiones",
"distribution_title": "Grupo Semver",
"distribution_modal_title": "Versiones",
"distribution_range_date_same_year": "de {from} a {to}, {endYear}",
@@ -389,9 +419,11 @@
"grouping_major": "Mayor",
"grouping_minor": "Menor",
"grouping_versions_title": "Versiones",
+ "grouping_versions_about": "Acerca del agrupamiento de versiones",
"grouping_versions_all": "Todas",
"grouping_versions_only_recent": "Solo recientes",
"grouping_usage_title": "Uso",
+ "grouping_usage_about": "Acerca del agrupamiento por uso",
"grouping_usage_all": "Todo",
"grouping_usage_most_used": "Mรกs usadas",
"recent_versions_only_tooltip": "Mostrar solo versiones publicadas en el รบltimo aรฑo.",
@@ -406,7 +438,10 @@
"copy_alt": {
"per_version_analysis": "La versiรณn {version} se descargรณ {downloads} veces",
"general_description": "Grรกfico de barras que muestra las descargas por versiรณn para {versions_count} versiones {semver_grouping_mode} del paquete {package_name}, {date_range_label} desde la versiรณn {first_version} hasta la versiรณn {last_version}. La versiรณn mรกs descargada es {max_downloaded_version} con {max_version_downloads} descargas. {per_version_analysis}. {watermark}."
- }
+ },
+ "page_title": "Historial de versiones",
+ "current_tags": "Etiquetas actuales",
+ "no_match_filter": "Ninguna versiรณn coincide con {filter}"
},
"dependencies": {
"title": "Dependencias ({count})",
@@ -417,7 +452,8 @@
"outdated_major": "{count} versiรณn mayor por detrรกs (รบltima: {latest}) | {count} versiones mayores por detrรกs (รบltima: {latest})",
"outdated_minor": "{count} versiรณn menor por detrรกs (รบltima: {latest}) | {count} versiones menores por detrรกs (รบltima: {latest})",
"outdated_patch": "Actualizaciรณn de parche disponible (รบltima: {latest})",
- "has_replacement": "Existen sugerencias para reemplazar esta dependencia"
+ "has_replacement": "Existen sugerencias para reemplazar esta dependencia",
+ "vulnerabilities_count": "{count} vulnerabilidad | {count} vulnerabilidades"
},
"peer_dependencies": {
"title": "Dependencias Peer ({count})",
@@ -441,9 +477,19 @@
"cancel_add": "Cancelar aรฑadir propietario",
"add_owner": "+ Aรฑadir propietario",
"show_more": "(mostrar {count} mรกs)",
- "show_less": "(mostrar menos)"
+ "show_less": "(mostrar menos)",
+ "maintainer_template": "{avatar} {char126}{name}"
},
"trends": {
+ "chart_assistive_text": {
+ "keyboard_navigation_horizontal": "Usa las teclas de flecha izquierda y derecha para recorrer los puntos de datos.",
+ "keyboard_navigation_vertical": "Usa las teclas de flecha arriba y abajo para recorrer los puntos de datos.",
+ "table_available": "Una tabla de datos para este grรกfico estรก disponible a continuaciรณn.",
+ "table_caption": "Tabla de datos del grรกfico"
+ },
+ "chart_view_toggle": "Alternar vista",
+ "chart_view_combined": "Vista combinada",
+ "chart_view_split": "Vista dividida",
"granularity": "Granularidad",
"granularity_daily": "Diaria",
"granularity_weekly": "Semanal",
@@ -502,7 +548,8 @@
"downloads": {
"title": "Descargas Semanales",
"community_distribution": "Ver distribuciรณn de adopciรณn comunitaria",
- "subtitle": "En todas las versiones"
+ "subtitle": "En todas las versiones",
+ "sparkline_nav_hint": "Usa โ โ"
},
"install_scripts": {
"title": "Scripts de Instalaciรณn",
@@ -518,6 +565,7 @@
"esm": "Mรณdulos ES soportados",
"cjs": "CommonJS soportado",
"no_esm": "Sin soporte de Mรณdulos ES",
+ "wasm": "Incluye WebAssembly",
"types_label": "Tipos",
"types_included": "Tipos incluidos",
"types_available": "Tipos disponibles vรญa {package}",
@@ -592,7 +640,10 @@
"kb": "{size} kB",
"mb": "{size} MB"
},
- "download": {}
+ "download": {
+ "button": "Descargar",
+ "tarball": "Descargar Tarball como .tar.gz"
+ }
},
"connector": {
"modal": {
@@ -772,12 +823,10 @@
"code": {
"files_label": "Archivos",
"no_files": "No hay archivos en este directorio",
- "root": "raรญz",
"lines": "{count} lรญneas",
"toggle_tree": "Alternar รกrbol de archivos",
"close_tree": "Cerrar รกrbol de archivos",
"copy_link": "Copiar enlace",
- "raw": "Crudo",
"view_raw": "Ver archivo crudo",
"file_too_large": "Archivo demasiado grande para previsualizar",
"file_size_warning": "{size} excede el lรญmite de 500KB para resaltado de sintaxis",
@@ -860,6 +909,8 @@
"secure": "Sin advertencias",
"insecure": "Con advertencias"
},
+ "view_selected": "Ver seleccionados",
+ "clear_selected_label": "Limpiar seleccionados",
"sort": {
"label": "Ordenar paquetes",
"toggle_direction": "Alternar direcciรณn de ordenamiento",
@@ -885,7 +936,8 @@
"published": "รltima publicaciรณn",
"maintainers": "Mantenedores",
"keywords": "Palabras clave",
- "security": "Seguridad"
+ "security": "Seguridad",
+ "selection": "Seleccionar paquete"
},
"view_mode": {
"label": "Modo de vista",
@@ -1032,7 +1084,8 @@
"error": "Error al cargar organizaciones",
"empty": "No se encontraron organizaciones",
"view_all": "Ver todo"
- }
+ },
+ "pr": "Abrir pull request #{prNumber} en GitHub"
},
"compare": {
"packages": {
@@ -1051,7 +1104,10 @@
"empty_title": "Selecciona paquetes para comparar",
"empty_description": "Busca y aรฑade al menos 2 paquetes arriba para ver una comparaciรณn lado a lado de sus mรฉtricas.",
"table_view": "Tabla",
- "charts_view": "Grรกficos"
+ "charts_view": "Grรกficos",
+ "no_chartable_data": "No hay datos disponibles para las facetas seleccionadas.",
+ "bar_chart_nav_hint": "Usa โ โ",
+ "line_chart_nav_hint": "Usa โ โ"
},
"selector": {
"search_label": "Buscar paquetes",
@@ -1074,6 +1130,10 @@
"facets": {
"all": "todas",
"none": "ninguna",
+ "select_all_category_facets": "Seleccionar todas las facetas de {category}",
+ "deselect_all_category_facets": "Deseleccionar todas las facetas de {category}",
+ "selected_all_category_facets": "Todas las facetas de {category} seleccionadas",
+ "deselected_all_category_facets": "Todas las facetas de {category} deseleccionadas",
"coming_soon": "Prรณximamente",
"select_all": "Seleccionar todas las facetas",
"deselect_all": "Deseleccionar todas las facetas",
@@ -1160,7 +1220,14 @@
"file_size_warning": "{size} excede el lรญmite de 250KB para la comparaciรณn",
"compare_versions": "diferencia",
"compare_versions_title": "Comparar con la รบltima versiรณn",
- "version_invalid_url_format": {},
+ "comparing_versions_label": "Comparando versiones...",
+ "version_back_to_package": "Volver al paquete",
+ "version_error_message": "Error al comparar versiones.",
+ "version_invalid_url_format": {
+ "hint": "URL de comparaciรณn invรกlida. Usa el formato: {0}",
+ "from_version": "desde",
+ "to_version": "hasta"
+ },
"version_selector_title": "Comparar con la versiรณn",
"summary": "Resumen",
"deps_count": "{count} dependencias",
@@ -1187,7 +1254,18 @@
"files_button": "Archivos",
"select_file_prompt": "Selecciona un archivo de la barra lateral para ver sus diferencias",
"close_files_panel": "Cerrar panel de archivos",
- "filter_files_label": "Filtrar archivos por tipo de cambio"
+ "filter_files_label": "Filtrar archivos por tipo de cambio",
+ "change_ratio": "Proporciรณn de cambios",
+ "char_edits": "Modificaciones de caracteres",
+ "diff_distance": "Distancia de diferencias",
+ "loading_diff": "Cargando diferencias...",
+ "loading_diff_error": "Error al cargar diferencias",
+ "merge_modified_lines": "Combinar lรญneas modificadas",
+ "no_content_changes": "No se detectaron cambios en el contenido",
+ "options": "Opciones",
+ "view_file": "Ver archivo",
+ "view_in_code_browser": "Ver en el navegador de cรณdigo",
+ "word_wrap": "Ajuste de lรญnea"
},
"pds": {
"title": "npmx.social",
@@ -1328,7 +1406,116 @@
}
},
"translation_status": {
- "table": {}
+ "title": "estado de traducciรณn",
+ "generated_at": "Fecha de generaciรณn: {date}",
+ "welcome": "Si estรกs interesado en ayudarnos a traducir {npmx} a uno de los idiomas listados a continuaciรณn, ยกhas llegado al lugar correcto! Esta pรกgina de actualizaciรณn automรกtica siempre muestra todo el contenido con el que nos pudieras ayudar en este momento",
+ "p1": "Usamos {lang} como el idioma predeterminado, con un total de {count}. Si deseas ayudar a agregar traducciones, localiza el idioma en {bylang} y expande los detalles.",
+ "p1_lang": "Inglรฉs de Estados Unidos (en-US)",
+ "p1_count": "0 mensajes | 1 mensaje |{count} mensajes",
+ "p2": "Antes de comenzar, por favor lee nuestra {guide} para aprender sobre nuestro proceso de traducciรณn y cรณmo puedes participar.",
+ "guide": "guรญa de localizaciรณn (i18n)",
+ "by_locale": "Progreso de traducciรณn por idioma",
+ "by_file": "Progreso de traducciรณn por archivo",
+ "complete_text": "Esta traducciรณn estรก completa, ยกgran trabajo!",
+ "missing_text": "faltante",
+ "missing_keys": "No hay traducciones faltantes | Traducciรณn faltante | Traducciones faltantes",
+ "progress_label": "Estado de progreso para {locale}",
+ "table": {
+ "file": "Archivo",
+ "status": "Estado",
+ "error": "Error al cargar la lista de archivos.",
+ "empty": "No se encontraron archivos",
+ "file_link": "Editar {file} ({lang}) en GitHub"
+ }
+ },
+ "vacations": {
+ "title": "de vacaciones",
+ "meta_description": "El equipo de npmx estaba recargando energรญas. El Discord se reabriรณ tras una semana.",
+ "heading": "recargando",
+ "subtitle": "estรกbamos construyendo npmx a un ritmo que no nos dejaba descansar. ยกno querรญamos que esa fuera la norma! asรญ que nos tomamos una semana de vacaciones. todos juntos.",
+ "illustration_alt": "una fila de iconos acogedores",
+ "poke_log": "Toca la fogata",
+ "what": {
+ "title": "quรฉ pasรณ",
+ "p1": "el Discord estuvo cerrado entre {dates}.",
+ "dates": "14 โ 21 de febrero",
+ "p2": "todos los enlaces de invitaciรณn desaparecieron y los canales fueron bloqueados, excepto {garden}, que permaneciรณ abierto para quienes querรญan seguir interactuando.",
+ "garden": "#garden"
+ },
+ "meantime": {
+ "title": "mientras tanto",
+ "p1": "{site} y {repo} permanecieron abiertos: la gente siguiรณ participando, reportando algunos problemas, abriendo algunos PRs, pero principalmente todos pasaron tiempo cerca de una chimenea acogedora.",
+ "repo_link": "el repositorio"
+ },
+ "return": {
+ "title": "ยกregresamos!",
+ "p1": "volvimos recargados y listos para el empujรณn final hacia el 3 de marzo. {social} para actualizaciones.",
+ "social_link": "sรญguenos en Bluesky"
+ },
+ "stats": {
+ "contributors": "Colaboradores",
+ "commits": "Commits",
+ "pr": "PRs aceptados",
+ "subtitle": {
+ "some": "algunos",
+ "all": "todos"
+ }
+ }
+ },
+ "action_bar": {
+ "title": "barra de acciones",
+ "selection": "0 seleccionados | 1 seleccionado | {count} seleccionados",
+ "shortcut": "Presiona \"{key}\" para enfocar acciones",
+ "button_close_aria_label": "Cerrar barra de acciones"
},
- "action_bar": {}
+ "logo_menu": {
+ "copy_svg": "Copiar logo como SVG",
+ "copied": "ยกCopiado!",
+ "browse_brand": "Explorar kit de marca"
+ },
+ "brand": {
+ "title": "Marca",
+ "heading": "marca",
+ "meta_description": "Directrices de la marca npmx, logotipos, colores y tipografรญa para uso en prensa y medios.",
+ "intro": "Recursos y directrices para usar la marca npmx en tus proyectos, artรญculos y medios.",
+ "logos": {
+ "title": "Logotipos",
+ "description": "Descarga los logotipos de npmx en formatos SVG y PNG. Usa la variante adecuada para tu fondo.",
+ "wordmark": "LOGOTIPO TEXTUAL",
+ "wordmark_alt": "logotipo textual de npmx con barra azul sobre fondo oscuro",
+ "wordmark_light_alt": "logotipo textual de npmx con barra de acento sobre fondo claro",
+ "mark": "LOGOTIPO",
+ "mark_alt": "logotipo de npmx con punto y barra sobre fondo oscuro",
+ "mark_light_alt": "logotipo de npmx con punto y barra sobre fondo claro",
+ "on_dark": "sobre fondo oscuro",
+ "on_light": "sobre fondo claro",
+ "download_svg": "SVG",
+ "download_png": "PNG",
+ "download_svg_aria": "Descargar {name} como SVG",
+ "download_png_aria": "Descargar {name} como PNG"
+ },
+ "customize": {
+ "title": "personalizar tu logo",
+ "description": "Previsualiza el logotipo de npmx con tu color de acento y fondo. La vista previa refleja tus configuraciones actuales: elige un color, cambia el fondo y descarga.",
+ "accent_label": "acento",
+ "bg_label": "fondo",
+ "download_svg_aria": "Descargar logotipo personalizado como SVG",
+ "download_png_aria": "Descargar logotipo personalizado como PNG"
+ },
+ "typography": {
+ "title": "tipografรญa",
+ "description": "npmx utiliza la familia de fuentes Geist de Vercel tanto para el texto de la interfaz como para el cรณdigo.",
+ "sans": "Geist Sans",
+ "sans_desc": "Usado para el texto del cuerpo y los elementos de la interfaz.",
+ "mono": "Geist Mono",
+ "mono_desc": "Usado para cรณdigo, encabezados y contenido tรฉcnico.",
+ "pangram": "El veloz murciรฉlago hindรบ comรญa feliz cardillo y kiwi",
+ "numbers": "0123456789"
+ },
+ "guidelines": {
+ "title": "una nota",
+ "message": "La accesibilidad es importante para nosotros, y nos encantarรญa que nos acompaรฑaras en esta visiรณn. Cuando uses los medios mencionados, asegรบrate de que haya suficiente contraste con el fondo, y no uses un tamaรฑo mรกs pequeรฑo que 24px. Si necesitas algรบn otro recurso o informaciรณn adicional sobre el proyecto, no dudes en contactarnos a travรฉs de {link}.",
+ "discord_link_text": "chat.npmx.dev"
+ }
+ }
}
diff --git a/i18n/locales/fr-FR.json b/i18n/locales/fr-FR.json
index f6c17d5b9c..8f34c94f0d 100644
--- a/i18n/locales/fr-FR.json
+++ b/i18n/locales/fr-FR.json
@@ -437,8 +437,6 @@
"no_matches": "Aucune version ne correspond ร cette plage",
"page_title": "Historique des versions",
"current_tags": "Tags actuels",
- "version_filter_placeholder": "Filtrer les versions...",
- "version_filter_label": "Filtrer les versions",
"no_match_filter": "Aucune version ne correspond ร {filter}",
"copy_alt": {
"per_version_analysis": "La version {version} a รฉtรฉ tรฉlรฉchargรฉe {downloads} fois",
@@ -825,12 +823,10 @@
"code": {
"files_label": "Fichiers",
"no_files": "Aucun fichier dans ce rรฉpertoire",
- "root": "racine",
"lines": "{count} lignes",
"toggle_tree": "Basculer l'arborescence",
"close_tree": "Fermer l'arborescence",
"copy_link": "Copier le lien",
- "raw": "Brut",
"view_raw": "Voir le fichier brut",
"file_too_large": "Fichier trop volumineux pour l'aperรงu",
"file_size_warning": "{size} dรฉpasse la limite de 500 Ko pour la coloration syntaxique",
@@ -1487,5 +1483,6 @@
"message": "Pour un usage commercial, veuillez nous contacter.",
"discord_link_text": "Discussion Discord"
}
- }
+ },
+ "alt_logo_kawaii": "Une version mignonne, arrondie et colorรฉe du logo npmx."
}
diff --git a/i18n/locales/hi-IN.json b/i18n/locales/hi-IN.json
index 56873fa206..8091162535 100644
--- a/i18n/locales/hi-IN.json
+++ b/i18n/locales/hi-IN.json
@@ -13,11 +13,11 @@
"trademark_disclaimer": "npm, npm, Inc. เคเคพ เคชเคเคเฅเคเฅเคค เคเฅเคฐเฅเคกเคฎเคพเคฐเฅเค เคนเฅเฅค เคฏเคน เคธเคพเคเค npm, Inc. เคธเฅ เคธเคเคฌเคฆเฅเคง เคจเคนเฅเค เคนเฅเฅค",
"footer": {
"about": "เคนเคฎเคพเคฐเฅ เคฌเคพเคฐเฅ เคฎเฅเค เคเคพเคจเคเคพเคฐเฅ",
+ "blog": "เคฌเฅเคฒเฅเค",
"docs": "เคฆเคธเฅเคคเคพเคตเฅเคเคผ",
"source": "เคธเฅเคฐเฅเคค",
"social": "เคธเฅเคถเคฒ",
"chat": "เคเฅเค",
- "blog": "เคฌเฅเคฒเฅเค",
"builders_chat": "เคฌเคฟเคฒเฅเคกเคฐเฅเคธ",
"keyboard_shortcuts": "เคเฅเคฌเฅเคฐเฅเคก เคถเฅเคฐเฅเคเคเค"
},
@@ -46,13 +46,21 @@
"button": "เคเฅเคเฅเค",
"searching": "เคเฅเค เคฐเคนเฅ เคนเฅเค...",
"found_packages": "เคเฅเค เคชเฅเคเฅเค เคจเคนเฅเค เคฎเคฟเคฒเคพ | 1 เคชเฅเคเฅเค เคฎเคฟเคฒเคพ | {count} เคชเฅเคเฅเค เคฎเคฟเคฒเฅ",
+ "found_packages_sorted": "เคเฅเค เคชเคฐเคฟเคฃเคพเคฎ เคจเคนเฅเค เคฎเคฟเคฒเคพ | เคถเฅเคฐเฅเคท {count} เคชเคฐเคฟเคฃเคพเคฎ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฟเคฏเคพ เคเคพ เคฐเคนเคพ เคนเฅ | เคถเฅเคฐเฅเคท {count} เคชเคฐเคฟเคฃเคพเคฎ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฟเค เคเคพ เคฐเคนเฅ เคนเฅเค",
"updating": "(เค
เคฆเฅเคฏเคคเคจ เคนเฅ เคฐเคนเคพ เคนเฅ...)",
"no_results": "\"{query}\" เคเฅ เคฒเคฟเค เคเฅเค เคชเฅเคเฅเค เคจเคนเฅเค เคฎเคฟเคฒเคพ",
+ "rate_limited": "npm เคเฅ rate limit เคฒเค เคเค เคนเฅ, เคเฅเค เคฆเฅเคฐ เคฌเคพเคฆ เคซเคฟเคฐ เคชเฅเคฐเคฏเคพเคธ เคเคฐเฅเค",
+ "title": "เคเฅเค",
+ "title_search": "เคเฅเค: {search}",
+ "title_packages": "เคชเฅเคเฅเค เคเฅเคเฅเค",
+ "meta_description": "'{search}' เคเฅ เคฒเคฟเค เคเฅเค เคชเคฐเคฟเคฃเคพเคฎ",
+ "meta_description_packages": "npm เคชเฅเคเฅเค เคเฅเคเฅเค",
"not_taken": "{name} เคเคชเคฒเคฌเฅเคง เคนเฅ",
"claim_prompt": "npm เคชเคฐ เคเคธ เคชเฅเคเฅเค เคจเคพเคฎ เคเฅ เคฆเคพเคตเคพ เคเคฐเฅเค",
"claim_button": "\"{name}\" เคฆเคพเคตเคพ เคเคฐเฅเค",
"want_to_claim": "เคเคธ เคชเฅเคเฅเค เคจเคพเคฎ เคเฅ เคฆเคพเคตเคพ เคเคฐเคจเคพ เคเคพเคนเคคเฅ เคนเฅเค?",
"start_typing": "เคชเฅเคเฅเค เคเฅเคเคจเฅ เคเฅ เคฒเคฟเค เคเคพเคเคช เคเคฐเคจเคพ เคถเฅเคฐเฅ เคเคฐเฅเค",
+ "algolia_disclaimer": "Algolia เคฆเฅเคตเคพเคฐเคพ เคธเคเคเคพเคฒเคฟเคค",
"exact_match": "เคธเคเฅเค",
"suggestion": {
"user": "เคเคชเคญเฅเคเฅเคคเคพ",
@@ -60,14 +68,6 @@
"view_user_packages": "เคเคธ เคเคชเคญเฅเคเฅเคคเคพ เคเฅ เคชเฅเคเฅเค เคฆเฅเคเฅเค",
"view_org_packages": "เคเคธ เคธเคเคเค เคจ เคเฅ เคชเฅเคเฅเค เคฆเฅเคเฅเค"
},
- "found_packages_sorted": "เคเฅเค เคชเคฐเคฟเคฃเคพเคฎ เคจเคนเฅเค เคฎเคฟเคฒเคพ | เคถเฅเคฐเฅเคท {count} เคชเคฐเคฟเคฃเคพเคฎ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฟเคฏเคพ เคเคพ เคฐเคนเคพ เคนเฅ | เคถเฅเคฐเฅเคท {count} เคชเคฐเคฟเคฃเคพเคฎ เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฟเค เคเคพ เคฐเคนเฅ เคนเฅเค",
- "rate_limited": "npm เคเฅ rate limit เคฒเค เคเค เคนเฅ, เคเฅเค เคฆเฅเคฐ เคฌเคพเคฆ เคซเคฟเคฐ เคชเฅเคฐเคฏเคพเคธ เคเคฐเฅเค",
- "title": "เคเฅเค",
- "title_search": "เคเฅเค: {search}",
- "title_packages": "เคชเฅเคเฅเค เคเฅเคเฅเค",
- "meta_description": "'{search}' เคเฅ เคฒเคฟเค เคเฅเค เคชเคฐเคฟเคฃเคพเคฎ",
- "meta_description_packages": "npm เคชเฅเคเฅเค เคเฅเคเฅเค",
- "algolia_disclaimer": "Algolia เคฆเฅเคตเคพเคฐเคพ เคธเคเคเคพเคฒเคฟเคค",
"instant_search": "เคคเฅเคฐเคเคค เคเฅเค",
"instant_search_on": "เคเคพเคฒเฅ",
"instant_search_off": "เคฌเคเคฆ",
@@ -88,9 +88,15 @@
"tap_to_search": "เคเฅเคเคจเฅ เคเฅ เคฒเคฟเค เคเฅเคช เคเคฐเฅเค"
},
"blog": {
+ "title": "เคฌเฅเคฒเฅเค",
+ "heading": "เคฌเฅเคฒเฅเค",
+ "meta_description": "npmx เคธเคฎเฅเคฆเคพเคฏ เคธเฅ เค
เคเคคเคฐเฅเคฆเฅเคทเฅเคเคฟ เคเคฐ เค
เคชเคกเฅเค",
"author": {
"view_profile": "Bluesky เคชเคฐ {name} เคเฅ เคชเฅเคฐเฅเคซเคผเคพเคเคฒ เคฆเฅเคเฅเค"
},
+ "draft_badge": "เคฎเคธเฅเคฆเคพ",
+ "draft_banner": "เคฏเคน เคเค เค
เคชเฅเคฐเคเคพเคถเคฟเคค เคฎเคธเฅเคฆเคพ เคนเฅเฅค เคฏเคน เค
เคงเฅเคฐเคพ เคนเฅ เคธเคเคคเคพ เคนเฅ เคฏเคพ เคเคธเคฎเฅเค เค
เคถเฅเคฆเฅเคงเคฟเคฏเคพเค เคนเฅ เคธเคเคคเฅ เคนเฅเคเฅค",
+ "no_posts": "เคเฅเค เคชเฅเคธเฅเค เคจเคนเฅเค เคฎเคฟเคฒเฅเฅค",
"atproto": {
"view_on_bluesky": "Bluesky เคชเคฐ เคฆเฅเคเฅเค",
"reply_on_bluesky": "Bluesky เคชเคฐ เคเคตเคพเคฌ เคฆเฅเค",
@@ -105,13 +111,7 @@
"like_count": "{count} เคฒเคพเคเค | {count} เคฒเคพเคเคเฅเคธ",
"repost_count": "{count} เคฐเคฟเคชเฅเคธเฅเค | {count} เคฐเคฟเคชเฅเคธเฅเค",
"more_replies": "{count} เคเคฐ เคเคตเคพเคฌ... | {count} เคเคฐ เคเคตเคพเคฌ..."
- },
- "title": "เคฌเฅเคฒเฅเค",
- "heading": "เคฌเฅเคฒเฅเค",
- "meta_description": "npmx เคธเคฎเฅเคฆเคพเคฏ เคธเฅ เค
เคเคคเคฐเฅเคฆเฅเคทเฅเคเคฟ เคเคฐ เค
เคชเคกเฅเค",
- "draft_badge": "เคฎเคธเฅเคฆเคพ",
- "draft_banner": "เคฏเคน เคเค เค
เคชเฅเคฐเคเคพเคถเคฟเคค เคฎเคธเฅเคฆเคพ เคนเฅเฅค เคฏเคน เค
เคงเฅเคฐเคพ เคนเฅ เคธเคเคคเคพ เคนเฅ เคฏเคพ เคเคธเคฎเฅเค เค
เคถเฅเคฆเฅเคงเคฟเคฏเคพเค เคนเฅ เคธเคเคคเฅ เคนเฅเคเฅค",
- "no_posts": "เคเฅเค เคชเฅเคธเฅเค เคจเคนเฅเค เคฎเคฟเคฒเฅเฅค"
+ }
},
"settings": {
"title": "เคธเฅเคเคฟเคเคเฅเคธ",
@@ -120,8 +120,8 @@
"sections": {
"appearance": "เคธเฅเคตเคฐเฅเคช",
"display": "เคชเฅเคฐเคฆเคฐเฅเคถเคจ",
- "language": "เคญเคพเคทเคพ",
"search": "เคเฅเค เคธเฅเคตเคฟเคงเคพเคเค",
+ "language": "เคญเคพเคทเคพ",
"keyboard_shortcuts": "เคเฅเคฌเฅเคฐเฅเคก เคถเฅเคฐเฅเคเคเค"
},
"data_source": {
@@ -132,17 +132,22 @@
"algolia": "Algolia",
"algolia_description": "เคคเฅเคเคผ เคเฅเค, org เคเคฐ user เคชเฅเคเฅเค เคเฅ เคฒเคฟเค Algolia เคเคพ เคเคชเคฏเฅเค เคเคฐเคคเคพ เคนเฅเฅค"
},
+ "instant_search": "เคคเฅเคฐเคเคค เคเฅเค",
+ "instant_search_description": "เคเฅเค เคชเฅเค เคชเคฐ เคฒเฅ เคเคพเคคเคพ เคนเฅ เคเคฐ เคเคชเคเฅ เคเคพเคเคช เคเคฐเคคเฅ เคนเฅ เคชเคฐเคฟเคฃเคพเคฎ เค
เคชเคกเฅเค เคเคฐเคคเคพ เคนเฅเฅค",
"relative_dates": "เคธเคพเคชเฅเคเฅเคท เคคเคฟเคฅเคฟเคฏเคพเค",
"include_types": "เคเคเคธเฅเคเฅเคฒ เคฎเฅเค {'@'}types เคถเคพเคฎเคฟเคฒ เคเคฐเฅเค",
"include_types_description": "เค
เคจเคเคพเคเคชเฅเคก เคชเฅเคเฅเค เคเฅ เคฒเคฟเค เคเคเคธเฅเคเฅเคฒ เคเคฎเคพเคเคก เคฎเฅเค {'@'}types เคชเฅเคเฅเค เคเฅเคกเคผเฅเค",
"hide_platform_packages": "เคเฅเค เคฎเฅเค เคชเฅเคฒเฅเคเคซเคผเฅเคฐเฅเคฎ-เคตเคฟเคถเคฟเคทเฅเค เคชเฅเคเฅเค เคเคฟเคชเคพเคเค",
"hide_platform_packages_description": "เคชเคฐเคฟเคฃเคพเคฎเฅเค เคธเฅ {'@'}esbuild/linux-x64 เคเฅเคธเฅ เคจเฅเคเคฟเคต เคฌเคพเคเคจเคฐเฅ เคชเฅเคเฅเค เคเคฟเคชเคพเคเค",
+ "enable_graph_pulse_loop": "เคฎเคฟเคจเฅ เคเฅเคฐเคพเคซเคผ เคชเคฐ pulse เคชเฅเคฐเคญเคพเคต เคเคพ เคฒเฅเคชเคฟเคเค เคธเคเฅเคทเคฎ เคเคฐเฅเค",
+ "enable_graph_pulse_loop_description": "เคธเคพเคชเฅเคคเคพเคนเคฟเค เคกเคพเคเคจเคฒเฅเคก เคเฅเคฐเคพเคซเคผ เคชเคฐ เคฒเคเคพเคคเคพเคฐ pulse animation เคธเคเฅเคฐเคฟเคฏ เคเคฐเฅเคเฅค เคฏเคน animation เคเฅเค เคเคชเคฏเฅเคเคเคฐเฅเคคเคพเคเค เคเฅ เคฒเคฟเค เคตเคฟเคเคฒเคฟเคค เคเคฐเคจเฅ เคตเคพเคฒเคพ เคนเฅ เคธเคเคคเคพ เคนเฅเฅค",
"theme": "เคฅเฅเคฎ",
"theme_light": "เคฒเคพเคเค",
"theme_dark": "เคกเคพเคฐเฅเค",
"theme_system": "เคธเคฟเคธเฅเคเคฎ",
"language": "เคญเคพเคทเคพ",
"help_translate": "npmx เคเคพ เค
เคจเฅเคตเคพเคฆ เคเคฐเคจเฅ เคฎเฅเค เคฎเคฆเคฆ เคเคฐเฅเค",
+ "translation_status": "เคตเฅเคถเฅเคตเคฟเค เค
เคจเฅเคตเคพเคฆ เคธเฅเคฅเคฟเคคเคฟ เคฆเฅเคเฅเค",
"accent_colors": {
"label": "เคเคเฅเคธเฅเคเค เคฐเคเค",
"sky": "เคเคธเคฎเคพเคจเฅ",
@@ -162,11 +167,6 @@
"slate": "เคธเฅเคฒเฅเค",
"black": "เคเคพเคฒเคพ"
},
- "instant_search": "เคคเฅเคฐเคเคค เคเฅเค",
- "instant_search_description": "เคเฅเค เคชเฅเค เคชเคฐ เคฒเฅ เคเคพเคคเคพ เคนเฅ เคเคฐ เคเคชเคเฅ เคเคพเคเคช เคเคฐเคคเฅ เคนเฅ เคชเคฐเคฟเคฃเคพเคฎ เค
เคชเคกเฅเค เคเคฐเคคเคพ เคนเฅเฅค",
- "enable_graph_pulse_loop": "เคฎเคฟเคจเฅ เคเฅเคฐเคพเคซเคผ เคชเคฐ pulse เคชเฅเคฐเคญเคพเคต เคเคพ เคฒเฅเคชเคฟเคเค เคธเคเฅเคทเคฎ เคเคฐเฅเค",
- "enable_graph_pulse_loop_description": "เคธเคพเคชเฅเคคเคพเคนเคฟเค เคกเคพเคเคจเคฒเฅเคก เคเฅเคฐเคพเคซเคผ เคชเคฐ เคฒเคเคพเคคเคพเคฐ pulse animation เคธเคเฅเคฐเคฟเคฏ เคเคฐเฅเคเฅค เคฏเคน animation เคเฅเค เคเคชเคฏเฅเคเคเคฐเฅเคคเคพเคเค เคเฅ เคฒเคฟเค เคตเคฟเคเคฒเคฟเคค เคเคฐเคจเฅ เคตเคพเคฒเคพ เคนเฅ เคธเคเคคเคพ เคนเฅเฅค",
- "translation_status": "เคตเฅเคถเฅเคตเคฟเค เค
เคจเฅเคตเคพเคฆ เคธเฅเคฅเคฟเคคเคฟ เคฆเฅเคเฅเค",
"keyboard_shortcuts_enabled": "เคเฅเคฌเฅเคฐเฅเคก เคถเฅเคฐเฅเคเคเค เคธเคเฅเคทเคฎ เคเคฐเฅเค",
"keyboard_shortcuts_enabled_description": "เคฏเคฆเคฟ เคเฅเคฌเฅเคฐเฅเคก เคถเฅเคฐเฅเคเคเค เค
เคจเฅเคฏ เคฌเฅเคฐเคพเคเคเคผเคฐ เคฏเคพ เคธเคฟเคธเฅเคเคฎ เคถเฅเคฐเฅเคเคเค เคธเฅ เคเคเคฐเคพเคคเฅ เคนเฅเค, เคคเฅ เคเคจเฅเคนเฅเค เคฌเคเคฆ เคเคฟเคฏเคพ เคเคพ เคธเคเคคเคพ เคนเฅ"
},
@@ -192,6 +192,7 @@
"end_of_results": "เคชเคฐเคฟเคฃเคพเคฎ เคธเคฎเคพเคชเฅเคค",
"try_again": "เคชเฅเคจเค เคชเฅเคฐเคฏเคพเคธ เคเคฐเฅเค",
"close": "เคฌเคเคฆ เคเคฐเฅเค",
+ "or": "เคฏเคพ",
"retry": "เคชเฅเคจเค เคชเฅเคฐเคฏเคพเคธ",
"copy": "เคเฅเคชเฅ เคเคฐเฅเค",
"copied": "เคเฅเคชเฅ เคนเฅ เคเคฏเคพ!",
@@ -206,6 +207,10 @@
"members": "เคธเคฆเคธเฅเคฏ"
},
"scroll_to_top": "เคถเฅเคฐเฅเคท เคชเคฐ เคธเฅเคเฅเคฐเฅเคฒ เคเคฐเฅเค",
+ "cancel": "เคฐเคฆเฅเคฆ เคเคฐเฅเค",
+ "save": "เคธเคนเฅเคเฅเค",
+ "edit": "เคธเคเคชเคพเคฆเคฟเคค เคเคฐเฅเค",
+ "error": "เคคเฅเคฐเฅเคเคฟ",
"view_on": {
"npm": "npm เคชเคฐ เคฆเฅเคเฅเค",
"github": "GitHub เคชเคฐ เคฆเฅเคเฅเค",
@@ -220,30 +225,11 @@
"sourcehut": "SourceHut เคชเคฐ เคฆเฅเคเฅเค",
"tangled": "Tangled เคชเคฐ เคฆเฅเคเฅเค"
},
- "or": "เคฏเคพ",
- "cancel": "เคฐเคฆเฅเคฆ เคเคฐเฅเค",
- "save": "เคธเคนเฅเคเฅเค",
- "edit": "เคธเคเคชเคพเคฆเคฟเคค เคเคฐเฅเค",
- "error": "เคคเฅเคฐเฅเคเคฟ",
"collapse": "เคธเคเคเฅเคทเคฟเคชเฅเคค เคเคฐเฅเค",
"expand": "เคตเคฟเคธเฅเคคเฅเคค เคเคฐเฅเค"
},
"profile": {
- "invite": {
- "message": "เคเคธเคพ เคจเคนเฅเค เคฒเคเคคเคพ เคเคฟ เคตเฅ เค
เคญเฅ npmx เคเคพ เคเคชเคฏเฅเค เคเคฐ เคฐเคนเฅ เคนเฅเคเฅค เคเฅเคฏเคพ เคเคช เคเคจเฅเคนเฅเค เคเคธเคเฅ เคฌเคพเคฐเฅ เคฎเฅเค เคฌเคคเคพเคจเคพ เคเคพเคนเคคเฅ เคนเฅเค?",
- "share_button": "Bluesky เคชเคฐ เคธเคพเคเคพ เคเคฐเฅเค",
- "compose_text": "Hey {'@'}{handle}! Have you checked out npmx.dev yet? It's a browser for the npm registry that's fast, modern, and open-source.\nhttps://npmx.dev"
- },
- "display_name": "เคชเฅเคฐเคฆเคฐเฅเคถเคฟเคค เคจเคพเคฎ",
- "description": "เคตเคฟเคตเคฐเคฃ",
- "no_description": "เคเฅเค เคตเคฟเคตเคฐเคฃ เคจเคนเฅเค",
- "website": "เคตเฅเคฌเคธเคพเคเค",
- "website_placeholder": "https://example.com",
- "likes": "เคฒเคพเคเคเฅเคธ",
- "seo_title": "{handle} - npmx",
- "seo_description": "{handle} เคฆเฅเคตเคพเคฐเคพ npmx เคชเฅเคฐเฅเคซเคผเคพเคเคฒ",
- "not_found": "เคชเฅเคฐเฅเคซเคผเคพเคเคฒ เคจเคนเฅเค เคฎเคฟเคฒเฅ",
- "not_found_message": "{handle} เคเฅ เคชเฅเคฐเฅเคซเคผเคพเคเคฒ เคจเคนเฅเค เคฎเคฟเคฒ เคธเคเฅเฅค"
+ "invite": {}
},
"package": {
"not_found": "เคชเฅเคเฅเค เคจเคนเฅเค เคฎเคฟเคฒเคพ",
@@ -271,9 +257,9 @@
"documented": "{community} เคจเฅ เคเคธ เคชเฅเคเฅเค เคเฅ เค
เคงเคฟเค เคชเฅเคฐเคฆเคฐเฅเคถเคจเคเคพเคฐเฅ เคตเคฟเคเคฒเฅเคชเฅเค เคเฅ เคฐเฅเคช เคฎเฅเค เคซเคผเฅเคฒเฅเค เคเคฟเคฏเคพ เคนเฅเฅค",
"none": "เคฏเคน เคชเฅเคเฅเค เค
เคฌ เคเคตเคถเฅเคฏเค เคจเคนเฅเค เคนเฅเคจเฅ เคเฅ เคฐเฅเคช เคฎเฅเค เคซเคผเฅเคฒเฅเค เคเคฟเคฏเคพ เคเคฏเคพ เคนเฅ, เคเคฐ เคเคธเคเฅ เคเคพเคฐเฅเคฏเคเฅเคทเคฎเคคเคพ เคธเคญเฅ เคเคเคเคจเฅเค เคฎเฅเค เคจเฅเคเคฟเคตเคฒเฅ เคเคชเคฒเคฌเฅเคง เคนเฅเคจเฅ เคเฅ เคธเคเคญเคพเคตเคจเคพ เคนเฅเฅค",
"learn_more": "เคเคฐ เคเคพเคจเฅเค",
+ "learn_more_above": "เคเคชเคฐ เคเคฐ เคเคพเคจเฅเคเฅค",
"mdn": "MDN",
"community": "เคธเคฎเฅเคฆเคพเคฏ",
- "learn_more_above": "เคเคชเคฐ เคเคฐ เคเคพเคจเฅเคเฅค",
"consider_no_dep": "+ เคฌเคฟเคจเคพ เคจเคฟเคฐเฅเคญเคฐเคคเคพ เคชเคฐ เคตเคฟเคเคพเคฐ เคเคฐเฅเค?"
},
"stats": {
@@ -281,14 +267,14 @@
"deps": "เคจเคฟเคฐเฅเคญเคฐเคคเคพ",
"install_size": "เคเคเคธเฅเคเฅเคฒ เคธเคพเคเคเคผ",
"vulns": "เคเคฎเคเฅเคฐเคฟเคฏเคพเค",
+ "published": "เคชเฅเคฐเคเคพเคถเคฟเคค",
+ "published_tooltip": "{package}{'@'}{version} เคเฅ เคชเฅเคฐเคเคพเคถเคฟเคค เคนเฅเคจเฅ เคเฅ เคคเคฟเคฅเคฟ",
"view_dependency_graph": "เคจเคฟเคฐเฅเคญเคฐเคคเคพ เคเฅเคฐเคพเคซเคผ เคฆเฅเคเฅเค",
"inspect_dependency_tree": "เคจเคฟเคฐเฅเคญเคฐเคคเคพ เคเฅเคฐเฅ เคเคพ เคจเคฟเคฐเฅเคเฅเคทเคฃ เคเคฐเฅเค",
"size_tooltip": {
"unpacked": "{size} เค
เคจเคชเฅเคเฅเคก เคธเคพเคเคเคผ (เคฏเคน เคชเฅเคเฅเค)",
"total": "{size} เคเฅเคฒ เค
เคจเคชเฅเคเฅเคก เคธเคพเคเคเคผ (linux-x64 เคเฅ เคฒเคฟเค เคธเคญเฅ {count} เคจเคฟเคฐเฅเคญเคฐเคคเคพ เคธเคนเคฟเคค)"
- },
- "published": "เคชเฅเคฐเคเคพเคถเคฟเคค",
- "published_tooltip": "{package}{'@'}{version} เคเฅ เคชเฅเคฐเคเคพเคถเคฟเคค เคนเฅเคจเฅ เคเฅ เคคเคฟเคฅเคฟ"
+ }
},
"skills": {
"title": "เคเคเฅเคเค เคธเฅเคเคฟเคฒเฅเคธ",
@@ -309,6 +295,7 @@
"skills_cli": "skills CLI"
},
"links": {
+ "main": "เคฎเฅเคเฅเคฏ",
"repo": "เคฐเคฟเคชเฅ",
"homepage": "เคฎเฅเคเคชเฅเคทเฅเค ",
"issues": "เคฎเคธเคฒเฅ",
@@ -317,7 +304,6 @@
"docs": "เคฆเคธเฅเคคเคพเคตเฅเคเคผ",
"fund": "เคฆเคพเคจ เคเคฐเฅเค",
"compare": "เคคเฅเคฒเคจเคพ เคเคฐเฅเค",
- "main": "เคฎเฅเคเฅเคฏ",
"compare_this_package": "เคเคธ เคชเฅเคเฅเค เคเฅ เคคเฅเคฒเคจเคพ เคเคฐเฅเค"
},
"likes": {
@@ -325,10 +311,10 @@
"unlike": "เคเคธ เคชเฅเคเฅเค เคเฅ เค
เคจเคฒเคพเคเค เคเคฐเฅเค"
},
"docs": {
- "not_available": "เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคเคชเคฒเคฌเฅเคง เคจเคนเฅเค",
- "not_available_detail": "เคนเคฎ เคเคธ เคธเคเคธเฅเคเคฐเคฃ เคเฅ เคฒเคฟเค เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคเฅเคจเคฐเฅเค เคจเคนเฅเค เคเคฐ เคธเคเฅเฅค",
"contents": "เคธเคพเคฎเคเฅเคฐเฅ",
"default_not_available": "เคเคธ เคธเคเคธเฅเคเคฐเคฃ เคเฅ เคฒเคฟเค เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคเคชเคฒเคฌเฅเคง เคจเคนเฅเค เคนเฅเคเฅค",
+ "not_available": "เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคเคชเคฒเคฌเฅเคง เคจเคนเฅเค",
+ "not_available_detail": "เคนเคฎ เคเคธ เคธเคเคธเฅเคเคฐเคฃ เคเฅ เคฒเคฟเค เคฆเคธเฅเคคเคพเคตเฅเคเคผ เคเฅเคจเคฐเฅเค เคจเคนเฅเค เคเคฐ เคธเคเฅเฅค",
"page_title": "API Docs - npmx",
"page_title_name": "{name} docs - npmx",
"page_title_version": "{name} docs - npmx",
@@ -339,9 +325,9 @@
"title": "เคถเฅเคฐเฅ เคเคฐเฅเค",
"pm_label": "เคชเฅเคเฅเค เคฎเฅเคจเฅเคเคฐ",
"copy_command": "เคเคเคธเฅเคเฅเคฒ เคเคฎเคพเคเคก เคเฅเคชเฅ เคเคฐเฅเค",
- "view_types": "{package} เคฆเฅเคเฅเค",
"copy_dev_command": "dev เคเคเคธเฅเคเฅเคฒ เคเคฎเคพเคเคก เคเฅเคชเฅ เคเคฐเฅเค",
- "dev_dependency_hint": "เคเคฎเคคเฅเคฐ เคชเคฐ dev dependency เคเฅ เคฐเฅเคช เคฎเฅเค เคเคเคธเฅเคเฅเคฒ เคเคฟเคฏเคพ เคเคพเคคเคพ เคนเฅ"
+ "dev_dependency_hint": "เคเคฎเคคเฅเคฐ เคชเคฐ dev dependency เคเฅ เคฐเฅเคช เคฎเฅเค เคเคเคธเฅเคเฅเคฒ เคเคฟเคฏเคพ เคเคพเคคเคพ เคนเฅ",
+ "view_types": "{package} เคฆเฅเคเฅเค"
},
"create": {
"title": "เคจเคฏเคพ เคชเฅเคฐเฅเคเฅเคเฅเค เคฌเคจเคพเคเค",
@@ -355,6 +341,7 @@
"readme": {
"title": "เคฐเฅเคกเคฎเฅ",
"no_readme": "เคเฅเค README เคเคชเคฒเคฌเฅเคง เคจเคนเฅเค เคนเฅเฅค",
+ "toc_title": "เคฐเฅเคชเคฐเฅเคเคพ",
"callout": {
"note": "เคจเฅเค",
"tip": "เคธเฅเคเคพเคต",
@@ -362,7 +349,6 @@
"warning": "เคเฅเคคเคพเคตเคจเฅ",
"caution": "เคธเคพเคตเคงเคพเคจเฅ"
},
- "toc_title": "เคฐเฅเคชเคฐเฅเคเคพ",
"copy_as_markdown": "README เคเฅ Markdown เคเฅ เคฐเฅเคช เคฎเฅเค เคเฅเคชเฅ เคเคฐเฅเค"
},
"provenance_section": {
@@ -390,10 +376,10 @@
"compatibility": "เคธเคเคเคคเคคเคพ",
"card": {
"publisher": "เคชเฅเคฐเคเคพเคถเค",
+ "published": "เคชเฅเคฐเคเคพเคถเคฟเคค",
"weekly_downloads": "เคธเคพเคชเฅเคคเคพเคนเคฟเค เคกเคพเคเคจเคฒเฅเคกเฅเคธ",
"keywords": "เคเฅเคตเคฐเฅเคกเฅเคธ",
"license": "เค
เคจเฅเคเฅเคเคชเฅเคคเคฟ",
- "published": "เคชเฅเคฐเคเคพเคถเคฟเคค",
"select": "เคชเฅเคเฅเค เคเฅเคจเฅเค",
"select_maximum": "เค
เคงเคฟเคเคคเคฎ {count} เคชเฅเคเฅเค เคเฅเคจเฅ เคเคพ เคธเคเคคเฅ เคนเฅเค"
},
@@ -410,10 +396,6 @@
"all_covered": "เคธเคญเฅ เคธเคเคธเฅเคเคฐเคฃ เคเคชเคฐ เคเฅ เคเฅเคเฅเคธ เคฆเฅเคตเคพเคฐเคพ เคเคตเคฐ เคเคฟเค เคเค เคนเฅเค",
"deprecated_title": "{version} (เคกเฅเคชเฅเคฐเฅเคเฅเคเฅเคก)",
"view_all": "{count} เคธเคเคธเฅเคเคฐเคฃ เคฆเฅเคเฅเค | เคธเคญเฅ {count} เคธเคเคธเฅเคเคฐเคฃ เคฆเฅเคเฅเค",
- "copy_alt": {
- "per_version_analysis": "{version} เคธเคเคธเฅเคเคฐเคฃ {downloads} เคฌเคพเคฐ เคกเคพเคเคจเคฒเฅเคก เคเคฟเคฏเคพ เคเคฏเคพ เคฅเคพ",
- "general_description": "เคฌเคพเคฐ เคเคพเคฐเฅเค {package_name} เคชเฅเคเฅเค เคเฅ {versions_count} {semver_grouping_mode} เคธเคเคธเฅเคเคฐเคฃเฅเค เคเฅ เคชเฅเคฐเคคเคฟ-เคธเคเคธเฅเคเคฐเคฃ เคกเคพเคเคจเคฒเฅเคก เคฆเคฟเคเคพเคคเคพ เคนเฅ, {date_range_label} {first_version} เคธเคเคธเฅเคเคฐเคฃ เคธเฅ {last_version} เคธเคเคธเฅเคเคฐเคฃ เคคเคเฅค เคธเคฌเคธเฅ เค
เคงเคฟเค เคกเคพเคเคจเคฒเฅเคก เคเคฟเคฏเคพ เคเคฏเคพ เคธเคเคธเฅเคเคฐเคฃ {max_downloaded_version} เคนเฅ, เคเคฟเคธเคเฅ {max_version_downloads} เคกเคพเคเคจเคฒเฅเคก เคนเฅเคเฅค {per_version_analysis}. {watermark}."
- },
"view_all_versions": "เคธเคญเฅ เคธเคเคธเฅเคเคฐเคฃ เคฆเฅเคเฅเค",
"distribution_title": "Semver เคธเคฎเฅเคน",
"distribution_modal_title": "เคธเคเคธเฅเคเคฐเคฃ",
@@ -438,10 +420,12 @@
"filter_tooltip": "{link} เคเคพ เคเคชเคฏเฅเค เคเคฐเคเฅ เคธเคเคธเฅเคเคฐเคฃ เคซเคผเคฟเคฒเฅเคเคฐ เคเคฐเฅเคเฅค เคเคฆเคพเคนเคฐเคฃ เคเฅ เคฒเคฟเค, ^3.0.0 เคธเคญเฅ 3.x เคธเคเคธเฅเคเคฐเคฃ เคฆเคฟเคเคพเคคเคพ เคนเฅเฅค",
"filter_tooltip_link": "semver range",
"no_matches": "เคเคธ range เคธเฅ เคเฅเค เคธเคเคธเฅเคเคฐเคฃ เคฎเฅเคฒ เคจเคนเฅเค เคเคพเคคเคพ",
+ "copy_alt": {
+ "per_version_analysis": "{version} เคธเคเคธเฅเคเคฐเคฃ {downloads} เคฌเคพเคฐ เคกเคพเคเคจเคฒเฅเคก เคเคฟเคฏเคพ เคเคฏเคพ เคฅเคพ",
+ "general_description": "เคฌเคพเคฐ เคเคพเคฐเฅเค {package_name} เคชเฅเคเฅเค เคเฅ {versions_count} {semver_grouping_mode} เคธเคเคธเฅเคเคฐเคฃเฅเค เคเฅ เคชเฅเคฐเคคเคฟ-เคธเคเคธเฅเคเคฐเคฃ เคกเคพเคเคจเคฒเฅเคก เคฆเคฟเคเคพเคคเคพ เคนเฅ, {date_range_label} {first_version} เคธเคเคธเฅเคเคฐเคฃ เคธเฅ {last_version} เคธเคเคธเฅเคเคฐเคฃ เคคเคเฅค เคธเคฌเคธเฅ เค
เคงเคฟเค เคกเคพเคเคจเคฒเฅเคก เคเคฟเคฏเคพ เคเคฏเคพ เคธเคเคธเฅเคเคฐเคฃ {max_downloaded_version} เคนเฅ, เคเคฟเคธเคเฅ {max_version_downloads} เคกเคพเคเคจเคฒเฅเคก เคนเฅเคเฅค {per_version_analysis}. {watermark}."
+ },
"page_title": "เคธเคเคธเฅเคเคฐเคฃ เคเคคเคฟเคนเคพเคธ",
"current_tags": "เคตเคฐเฅเคคเคฎเคพเคจ เคเฅเคเฅเคธ",
- "version_filter_placeholder": "เคธเคเคธเฅเคเคฐเคฃ เคซเคผเคฟเคฒเฅเคเคฐ เคเคฐเฅเคโฆ",
- "version_filter_label": "เคธเคเคธเฅเคเคฐเคฃ เคซเคผเคฟเคฒเฅเคเคฐ เคเคฐเฅเค",
"no_match_filter": "เคเฅเค เคธเคเคธเฅเคเคฐเคฃ {filter} เคธเฅ เคฎเฅเคฒ เคจเคนเฅเค เคเคพเคคเคพ"
},
"dependencies": {
@@ -482,6 +466,12 @@
"maintainer_template": "{avatar} {char126}{name}"
},
"trends": {
+ "chart_assistive_text": {
+ "keyboard_navigation_horizontal": "เคกเฅเคเคพ เคฌเคฟเคเคฆเฅเคเค เคเฅ เคฌเฅเค เคเคพเคจเฅ เคเฅ เคฒเคฟเค เคฌเคพเคเค เคเคฐ เคฆเคพเคเค เคคเฅเคฐ เคเฅเคเคเคฟเคฏเฅเค เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเคเฅค",
+ "keyboard_navigation_vertical": "เคกเฅเคเคพ เคฌเคฟเคเคฆเฅเคเค เคเฅ เคฌเฅเค เคเคพเคจเฅ เคเฅ เคฒเคฟเค เคเคชเคฐ เคเคฐ เคจเฅเคเฅ เคคเฅเคฐ เคเฅเคเคเคฟเคฏเฅเค เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเคเฅค",
+ "table_available": "เคเคธ เคเคพเคฐเฅเค เคเฅ เคฒเคฟเค เคจเฅเคเฅ เคเค เคกเฅเคเคพ เคคเคพเคฒเคฟเคเคพ เคเคชเคฒเคฌเฅเคง เคนเฅเฅค",
+ "table_caption": "เคเคพเคฐเฅเค เคกเฅเคเคพ เคคเคพเคฒเคฟเคเคพ"
+ },
"granularity": "เคเฅเคฐเฅเคจเฅเคฏเฅเคฒเฅเคฐเคฟเคเฅ",
"granularity_daily": "เคฆเฅเคจเคฟเค",
"granularity_weekly": "เคธเคพเคชเฅเคคเคพเคนเคฟเค",
@@ -494,33 +484,6 @@
"date_range_multiline": "{start}\nเคธเฅ {end}",
"download_file": "{fileType} เคกเคพเคเคจเคฒเฅเคก เคเคฐเฅเค",
"toggle_annotator": "เคเคจเฅเคเฅเคเคฐ เคเฅเคเคฒ เคเคฐเฅเค",
- "items": {
- "downloads": "เคกเคพเคเคจเคฒเฅเคกเฅเคธ",
- "likes": "เคฒเคพเคเคเฅเคธ",
- "contributors": "เคฏเฅเคเคฆเคพเคจเคเคฐเฅเคคเคพ"
- },
- "copy_alt": {
- "trend_none": "เคฒเคเคญเค เคธเฅเคฅเคฟเคฐ",
- "trend_strong": "เคฎเคเคผเคฌเฅเคค",
- "trend_weak": "เคเคฎเคเคผเฅเคฐ",
- "trend_undefined": "เค
เคชเคฐเคฟเคญเคพเคทเคฟเคค (เคชเคฐเฅเคฏเคพเคชเฅเคค เคกเฅเคเคพ เคจเคนเฅเค)",
- "button_label": "เคตเฅเคเคฒเฅเคชเคฟเค เคชเคพเค เคเฅเคชเฅ เคเคฐเฅเค",
- "watermark": "เคจเฅเคเฅ เคเฅ เคเคฐ เคเค เคตเฅเคเคฐเคฎเคพเคฐเฅเค เคฒเคฟเคเคพ เคนเฅ \"./npmx a fast, modern browser for the npm registry\"",
- "analysis": "{package_name} {start_value} เคธเฅ เคถเฅเคฐเฅ เคนเฅเคคเคพ เคนเฅ เคเคฐ {end_value} เคชเคฐ เคธเคฎเคพเคชเฅเคค เคนเฅเคคเคพ เคนเฅ, เคเฅ เคชเฅเคฐเคคเคฟ เคธเคฎเคฏ เค
เคเคคเคฐเคพเคฒ {downloads_slope} เคกเคพเคเคจเคฒเฅเคก เคเฅ เคขเคฒเคพเคจ เคเฅ เคธเคพเคฅ {trend} เคฐเฅเคเคพเคจ เคฆเคฟเคเคพเคคเคพ เคนเฅ",
- "estimation": "เค
เคเคคเคฟเคฎ เคฎเคพเคจ เคตเคฐเฅเคคเคฎเคพเคจ เค
เคตเคงเคฟ เคเฅ เคเคเคถเคฟเค เคกเฅเคเคพ เคชเคฐ เคเคงเคพเคฐเคฟเคค เคเค เค
เคจเฅเคฎเคพเคจ เคนเฅเฅค",
- "estimations": "เค
เคเคคเคฟเคฎ เคฎเคพเคจ เคตเคฐเฅเคคเคฎเคพเคจ เค
เคตเคงเคฟ เคเฅ เคเคเคถเคฟเค เคกเฅเคเคพ เคชเคฐ เคเคงเคพเคฐเคฟเคค เค
เคจเฅเคฎเคพเคจ เคนเฅเคเฅค",
- "compare": "เคเคจเคเฅ เคฒเคฟเค เคชเฅเคเฅเค เคกเคพเคเคจเคฒเฅเคก เคคเฅเคฒเคจเคพ เคฐเฅเคเคพ เคเคพเคฐเฅเค: {packages}เฅค",
- "single_package": "{package} เคชเฅเคเฅเค เคเฅ เคฒเคฟเค เคกเคพเคเคจเคฒเฅเคก เคฐเฅเคเคพ เคเคพเคฐเฅเคเฅค",
- "general_description": "Y เค
เคเฅเคท เคกเคพเคเคจเคฒเฅเคก เคเฅ เคธเคเคเฅเคฏเคพ เคฆเคฐเฅเคถเคพเคคเคพ เคนเฅเฅค X เค
เคเฅเคท {start_date} เคธเฅ {end_date} เคคเค เคเฅ เคคเคพเคฐเฅเค เคธเฅเคฎเคพ เคฆเคฐเฅเคถเคพเคคเคพ เคนเฅ, เคเคฟเคธเคฎเฅเค {granularity} เคธเคฎเคฏ เค
เคตเคงเคฟ เคนเฅเฅค{estimation_notice} {packages_analysis}. {watermark}.",
- "facet_bar_general_description": "เคเคจเคเฅ เคฒเคฟเค เคเฅเคทเฅเคคเคฟเค เคฌเคพเคฐ เคเคพเคฐเฅเค: {packages}, {facet} เคเฅ เคคเฅเคฒเคจเคพ เคเคฐเคคเฅ เคนเฅเค ({description})เฅค {facet_analysis} {watermark}.",
- "facet_bar_analysis": "{package_name} เคเคพ เคฎเคพเคจ {value} เคนเฅเฅค"
- },
- "chart_assistive_text": {
- "keyboard_navigation_horizontal": "เคกเฅเคเคพ เคฌเคฟเคเคฆเฅเคเค เคเฅ เคฌเฅเค เคเคพเคจเฅ เคเฅ เคฒเคฟเค เคฌเคพเคเค เคเคฐ เคฆเคพเคเค เคคเฅเคฐ เคเฅเคเคเคฟเคฏเฅเค เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเคเฅค",
- "keyboard_navigation_vertical": "เคกเฅเคเคพ เคฌเคฟเคเคฆเฅเคเค เคเฅ เคฌเฅเค เคเคพเคจเฅ เคเฅ เคฒเคฟเค เคเคชเคฐ เคเคฐ เคจเฅเคเฅ เคคเฅเคฐ เคเฅเคเคเคฟเคฏเฅเค เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเคเฅค",
- "table_available": "เคเคธ เคเคพเคฐเฅเค เคเฅ เคฒเคฟเค เคจเฅเคเฅ เคเค เคกเฅเคเคพ เคคเคพเคฒเคฟเคเคพ เคเคชเคฒเคฌเฅเคง เคนเฅเฅค",
- "table_caption": "เคเคพเคฐเฅเค เคกเฅเคเคพ เคคเคพเคฒเคฟเคเคพ"
- },
"toggle_stack_mode": "เคธเฅเคเฅเค เคฎเฅเคก เคเฅเคเคฒ เคเคฐเฅเค",
"open_options": "เคตเคฟเคเคฒเฅเคช เคเฅเคฒเฅเค",
"close_options": "เคตเคฟเคเคฒเฅเคช เคฌเคเคฆ เคเคฐเฅเค",
@@ -530,6 +493,11 @@
"facet": "เคซเฅเคธเฅเค",
"title": "เคฐเฅเคเคพเคจ",
"contributors_skip": "Contributors เคฎเฅเค เคจเคนเฅเค เคฆเคฟเคเคพเคฏเคพ เคเคฏเคพ (เคเฅเค GitHub repo เคจเคนเฅเค):",
+ "items": {
+ "downloads": "เคกเคพเคเคจเคฒเฅเคกเฅเคธ",
+ "likes": "เคฒเคพเคเคเฅเคธ",
+ "contributors": "เคฏเฅเคเคฆเคพเคจเคเคฐเฅเคคเคพ"
+ },
"data_correction": "เคกเฅเคเคพ เคธเฅเคงเคพเคฐ",
"average_window": "เคเคธเคค เคตเคฟเคเคกเฅ",
"smoothing": "เคธเฅเคฎเฅเคฆเคฟเคเค",
@@ -541,7 +509,23 @@
"known_anomalies_range_named": "{packageName}: {start} เคธเฅ {end} เคคเค",
"known_anomalies_none": "เคเคธ เคชเฅเคเฅเค เคเฅ เคฒเคฟเค เคเฅเค เคเฅเคเคพเคค เคตเคฟเคธเคเคเคคเคฟ เคจเคนเฅเคเฅค | เคเคจ เคชเฅเคเฅเคเฅเค เคเฅ เคฒเคฟเค เคเฅเค เคเฅเคเคพเคค เคตเคฟเคธเคเคเคคเคฟ เคจเคนเฅเคเฅค",
"known_anomalies_contribute": "เคตเคฟเคธเคเคเคคเคฟ เคกเฅเคเคพ เคฎเฅเค เคฏเฅเคเคฆเคพเคจ เคฆเฅเค",
- "apply_correction": "เคธเฅเคงเคพเคฐ เคฒเคพเคเฅ เคเคฐเฅเค"
+ "apply_correction": "เคธเฅเคงเคพเคฐ เคฒเคพเคเฅ เคเคฐเฅเค",
+ "copy_alt": {
+ "trend_none": "เคฒเคเคญเค เคธเฅเคฅเคฟเคฐ",
+ "trend_strong": "เคฎเคเคผเคฌเฅเคค",
+ "trend_weak": "เคเคฎเคเคผเฅเคฐ",
+ "trend_undefined": "เค
เคชเคฐเคฟเคญเคพเคทเคฟเคค (เคชเคฐเฅเคฏเคพเคชเฅเคค เคกเฅเคเคพ เคจเคนเฅเค)",
+ "button_label": "เคตเฅเคเคฒเฅเคชเคฟเค เคชเคพเค เคเฅเคชเฅ เคเคฐเฅเค",
+ "watermark": "เคจเฅเคเฅ เคเฅ เคเคฐ เคเค เคตเฅเคเคฐเคฎเคพเคฐเฅเค เคฒเคฟเคเคพ เคนเฅ \"./npmx a fast, modern browser for the npm registry\"",
+ "analysis": "{package_name} {start_value} เคธเฅ เคถเฅเคฐเฅ เคนเฅเคคเคพ เคนเฅ เคเคฐ {end_value} เคชเคฐ เคธเคฎเคพเคชเฅเคค เคนเฅเคคเคพ เคนเฅ, เคเฅ เคชเฅเคฐเคคเคฟ เคธเคฎเคฏ เค
เคเคคเคฐเคพเคฒ {downloads_slope} เคกเคพเคเคจเคฒเฅเคก เคเฅ เคขเคฒเคพเคจ เคเฅ เคธเคพเคฅ {trend} เคฐเฅเคเคพเคจ เคฆเคฟเคเคพเคคเคพ เคนเฅ",
+ "estimation": "เค
เคเคคเคฟเคฎ เคฎเคพเคจ เคตเคฐเฅเคคเคฎเคพเคจ เค
เคตเคงเคฟ เคเฅ เคเคเคถเคฟเค เคกเฅเคเคพ เคชเคฐ เคเคงเคพเคฐเคฟเคค เคเค เค
เคจเฅเคฎเคพเคจ เคนเฅเฅค",
+ "estimations": "เค
เคเคคเคฟเคฎ เคฎเคพเคจ เคตเคฐเฅเคคเคฎเคพเคจ เค
เคตเคงเคฟ เคเฅ เคเคเคถเคฟเค เคกเฅเคเคพ เคชเคฐ เคเคงเคพเคฐเคฟเคค เค
เคจเฅเคฎเคพเคจ เคนเฅเคเฅค",
+ "compare": "เคเคจเคเฅ เคฒเคฟเค เคชเฅเคเฅเค เคกเคพเคเคจเคฒเฅเคก เคคเฅเคฒเคจเคพ เคฐเฅเคเคพ เคเคพเคฐเฅเค: {packages}เฅค",
+ "single_package": "{package} เคชเฅเคเฅเค เคเฅ เคฒเคฟเค เคกเคพเคเคจเคฒเฅเคก เคฐเฅเคเคพ เคเคพเคฐเฅเคเฅค",
+ "general_description": "Y เค
เคเฅเคท เคกเคพเคเคจเคฒเฅเคก เคเฅ เคธเคเคเฅเคฏเคพ เคฆเคฐเฅเคถเคพเคคเคพ เคนเฅเฅค X เค
เคเฅเคท {start_date} เคธเฅ {end_date} เคคเค เคเฅ เคคเคพเคฐเฅเค เคธเฅเคฎเคพ เคฆเคฐเฅเคถเคพเคคเคพ เคนเฅ, เคเคฟเคธเคฎเฅเค {granularity} เคธเคฎเคฏ เค
เคตเคงเคฟ เคนเฅเฅค{estimation_notice} {packages_analysis}. {watermark}.",
+ "facet_bar_general_description": "เคเคจเคเฅ เคฒเคฟเค เคเฅเคทเฅเคคเคฟเค เคฌเคพเคฐ เคเคพเคฐเฅเค: {packages}, {facet} เคเฅ เคคเฅเคฒเคจเคพ เคเคฐเคคเฅ เคนเฅเค ({description})เฅค {facet_analysis} {watermark}.",
+ "facet_bar_analysis": "{package_name} เคเคพ เคฎเคพเคจ {value} เคนเฅเฅค"
+ }
},
"downloads": {
"title": "เคธเคพเคชเฅเคคเคพเคนเคฟเค เคกเคพเคเคจเคฒเฅเคกเฅเคธ",
@@ -563,11 +547,11 @@
"esm": "ES Modules เคธเคฎเคฐเฅเคฅเคฟเคค",
"cjs": "CommonJS เคธเคฎเคฐเฅเคฅเคฟเคค",
"no_esm": "ES Modules เคธเคฎเคฐเฅเคฅเคจ เคจเคนเฅเค",
+ "wasm": "WebAssembly เคนเฅ",
"types_label": "เคเคพเคเคชเฅเคธ",
"types_included": "เคเคพเคเคชเฅเคธ เคถเคพเคฎเคฟเคฒ เคนเฅเค",
"types_available": "เคเคพเคเคชเฅเคธ {package} เคเฅ เคฎเคพเคงเฅเคฏเคฎ เคธเฅ เคเคชเคฒเคฌเฅเคง",
- "no_types": "เคเฅเค TypeScript เคเคพเคเคชเฅเคธ เคจเคนเฅเค",
- "wasm": "WebAssembly เคนเฅ"
+ "no_types": "เคเฅเค TypeScript เคเคพเคเคชเฅเคธ เคจเคนเฅเค"
},
"license": {
"view_spdx": "SPDX เคชเคฐ เค
เคจเฅเคเฅเคเคชเฅเคคเคฟ เคเฅเคเฅเคธเฅเค เคฆเฅเคเฅเค",
@@ -629,9 +613,9 @@
},
"sort": {
"downloads": "เคธเคฌเคธเฅ เค
เคงเคฟเค เคกเคพเคเคจเคฒเฅเคก เคเคฟเค เคเค",
+ "published": "เคนเคพเคฒ เคนเฅ เคฎเฅเค เคชเฅเคฐเคเคพเคถเคฟเคค",
"name_asc": "เคจเคพเคฎ (A-Z)",
- "name_desc": "เคจเคพเคฎ (Z-A)",
- "published": "เคนเคพเคฒ เคนเฅ เคฎเฅเค เคชเฅเคฐเคเคพเคถเคฟเคค"
+ "name_desc": "เคจเคพเคฎ (Z-A)"
},
"size": {
"b": "{size} B",
@@ -678,7 +662,9 @@
"otp_placeholder": "OTP เคเฅเคก เคฆเคฐเฅเค เคเคฐเฅเค...",
"otp_label": "เคตเคจ-เคเคพเคเคฎ เคชเคพเคธเคตเคฐเฅเคก",
"retry_otp": "OTP เคเฅ เคธเคพเคฅ เคชเฅเคจเค เคชเฅเคฐเคฏเคพเคธ เคเคฐเฅเค",
+ "retry_web_auth": "เคตเฅเคฌ เคชเฅเคฐเคฎเคพเคฃเฅเคเคฐเคฃ เคเฅ เคธเคพเคฅ เคชเฅเคจเค เคชเฅเคฐเคฏเคพเคธ เคเคฐเฅเค",
"retrying": "เคชเฅเคจเค เคชเฅเคฐเคฏเคพเคธ เคเคฐ เคฐเคนเฅ เคนเฅเค...",
+ "open_web_auth": "เคตเฅเคฌ เคชเฅเคฐเคฎเคพเคฃเฅเคเคฐเคฃ เคฒเคฟเคเค เคเฅเคฒเฅเค",
"approve_operation": "เคเคชเคฐเฅเคถเคจ เคธเฅเคตเฅเคเฅเคค เคเคฐเฅเค",
"remove_operation": "เคเคชเคฐเฅเคถเคจ เคนเคเคพเคเค",
"approve_all": "เคธเคญเฅ เคธเฅเคตเฅเคเฅเคค เคเคฐเฅเค",
@@ -686,9 +672,7 @@
"executing": "เคจเคฟเคทเฅเคชเคพเคฆเคฟเคค เคนเฅ เคฐเคนเคพ เคนเฅ...",
"log": "เคฒเฅเค",
"log_label": "เคชเฅเคฐเฅเคฃ เคเคชเคฐเฅเคถเคจเฅเคธ เคฒเฅเค",
- "remove_from_log": "เคฒเฅเค เคธเฅ เคนเคเคพเคเค",
- "retry_web_auth": "เคตเฅเคฌ เคชเฅเคฐเคฎเคพเคฃเฅเคเคฐเคฃ เคเฅ เคธเคพเคฅ เคชเฅเคจเค เคชเฅเคฐเคฏเคพเคธ เคเคฐเฅเค",
- "open_web_auth": "เคตเฅเคฌ เคชเฅเคฐเคฎเคพเคฃเฅเคเคฐเคฃ เคฒเคฟเคเค เคเฅเคฒเฅเค"
+ "remove_from_log": "เคฒเฅเค เคธเฅ เคนเคเคพเคเค"
}
},
"org": {
@@ -802,6 +786,7 @@
"invalid_name": "เค
เคฎเคพเคจเฅเคฏ เคชเฅเคเฅเค เคจเคพเคฎ:",
"available": "เคฏเคน เคจเคพเคฎ เคเคชเคฒเคฌเฅเคง เคนเฅ!",
"taken": "เคฏเคน เคจเคพเคฎ เคชเคนเคฒเฅ เคธเฅ เคฒเคฟเคฏเคพ เคเคพ เคเฅเคเคพ เคนเฅเฅค",
+ "missing_permission": "เคเคชเคเฅ เคชเคพเคธ scope {'@'}{scope} เคฎเฅเค เคชเฅเคเฅเค เคเฅเคกเคผเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคจเคนเฅเค เคนเฅเฅค",
"similar_warning": "เคธเคฎเคพเคจ เคชเฅเคเฅเค เคฎเฅเคเฅเคฆ เคนเฅเค - npm เคเคธ เคจเคพเคฎ เคเฅ เค
เคธเฅเคตเฅเคเคพเคฐ เคเคฐ เคธเคเคคเคพ เคนเฅ:",
"related": "เคธเคเคฌเคเคงเคฟเคค เคชเฅเคเฅเค:",
"scope_warning_title": "เคเคธเคเฅ เคฌเคเคพเคฏ เคธเฅเคเฅเคชเฅเคก เคชเฅเคเฅเค เคเคพ เคเคชเคฏเฅเค เคเคฐเคจเฅ เคชเคฐ เคตเคฟเคเคพเคฐ เคเคฐเฅเค",
@@ -814,19 +799,16 @@
"publishing": "เคชเฅเคฐเคเคพเคถเคฟเคค เคนเฅ เคฐเคนเคพ เคนเฅ...",
"checking": "เคเคชเคฒเคฌเฅเคงเคคเคพ เคเคพเคเค เคฐเคนเฅ เคนเฅเค...",
"failed_to_check": "เคจเคพเคฎ เคเคชเคฒเคฌเฅเคงเคคเคพ เคเคพเคเคเคจเฅ เคฎเฅเค เคตเคฟเคซเคฒ",
- "failed_to_claim": "เคชเฅเคเฅเค เคฆเคพเคตเคพ เคเคฐเคจเฅ เคฎเฅเค เคตเคฟเคซเคฒ",
- "missing_permission": "เคเคชเคเฅ เคชเคพเคธ scope {'@'}{scope} เคฎเฅเค เคชเฅเคเฅเค เคเฅเคกเคผเคจเฅ เคเฅ เค
เคจเฅเคฎเคคเคฟ เคจเคนเฅเค เคนเฅเฅค"
+ "failed_to_claim": "เคชเฅเคเฅเค เคฆเคพเคตเคพ เคเคฐเคจเฅ เคฎเฅเค เคตเคฟเคซเคฒ"
}
},
"code": {
"files_label": "เคซเคผเคพเคเคฒเฅเค",
"no_files": "เคเคธ เคกเคพเคฏเคฐเฅเคเฅเคเคฐเฅ เคฎเฅเค เคเฅเค เคซเคผเคพเคเคฒเฅเค เคจเคนเฅเค",
- "root": "เคฐเฅเค",
"lines": "{count} เคชเคเคเฅเคคเคฟเคฏเคพเค",
"toggle_tree": "เคซเคผเคพเคเคฒ เคเฅเคฐเฅ เคเฅเคเคฒ เคเคฐเฅเค",
"close_tree": "เคซเคผเคพเคเคฒ เคเฅเคฐเฅ เคฌเคเคฆ เคเคฐเฅเค",
"copy_link": "เคฒเคฟเคเค เคเฅเคชเฅ เคเคฐเฅเค",
- "raw": "เคฐเฅ",
"view_raw": "เคฐเฅ เคซเคผเคพเคเคฒ เคฆเฅเคเฅเค",
"file_too_large": "เคซเคผเคพเคเคฒ เคชเฅเคฐเฅเคตเคพเคตเคฒเฅเคเคจ เคเฅ เคฒเคฟเค เคฌเคนเฅเคค เคฌเคกเคผเฅ เคนเฅ",
"file_size_warning": "{size} เคธเคฟเคเคเฅเคเฅเคธ เคนเคพเคเคฒเคพเคเคเคฟเคเค เคเฅ เคฒเคฟเค 500KB เคธเฅเคฎเคพ เคธเฅ เค
เคงเคฟเค เคนเฅ",
@@ -909,6 +891,8 @@
"secure": "เคเฅเคคเคพเคตเคจเคฟเคฏเฅเค เคเฅ เคฌเคฟเคจเคพ",
"insecure": "เคเฅเคคเคพเคตเคจเคฟเคฏเฅเค เคเฅ เคธเคพเคฅ"
},
+ "view_selected": "เคเคฏเคจเคฟเคค เคฆเฅเคเฅเค",
+ "clear_selected_label": "เคเคฏเคจ เคธเคพเคซเคผ เคเคฐเฅเค",
"sort": {
"label": "เคชเฅเคเฅเค เคเฅเคฐเคฎเคฌเคฆเฅเคง เคเคฐเฅเค",
"toggle_direction": "เคเฅเคฐเคฎเคฌเคฆเฅเคง เคฆเคฟเคถเคพ เคเฅเคเคฒ เคเคฐเฅเค",
@@ -919,8 +903,8 @@
"downloads_day": "เคกเคพเคเคจเคฒเฅเคกเฅเคธ/เคฆเคฟเคจ",
"downloads_month": "เคกเคพเคเคจเคฒเฅเคกเฅเคธ/เคฎเคนเฅเคจเคพ",
"downloads_year": "เคกเคพเคเคจเคฒเฅเคกเฅเคธ/เคตเคฐเฅเคท",
- "name": "เคจเคพเคฎ",
- "published": "เค
เคเคคเคฟเคฎ เคชเฅเคฐเคเคพเคถเคจ"
+ "published": "เค
เคเคคเคฟเคฎ เคชเฅเคฐเคเคพเคถเคจ",
+ "name": "เคจเคพเคฎ"
},
"columns": {
"title": "เคเฅเคฒเคฎเฅเคธ",
@@ -931,10 +915,10 @@
"version": "เคธเคเคธเฅเคเคฐเคฃ",
"description": "เคตเคฟเคตเคฐเคฃ",
"downloads": "เคกเคพเคเคจเคฒเฅเคกเฅเคธ/เคธเคชเฅเคคเคพเคน",
+ "published": "เค
เคเคคเคฟเคฎ เคชเฅเคฐเคเคพเคถเคจ",
"maintainers": "เค
เคจเฅเคฐเคเฅเคทเค",
"keywords": "เคเฅเคตเคฐเฅเคกเฅเคธ",
"security": "เคธเฅเคฐเคเฅเคทเคพ",
- "published": "เค
เคเคคเคฟเคฎ เคชเฅเคฐเคเคพเคถเคจ",
"selection": "เคชเฅเคเฅเค เคเฅเคจเฅเค"
},
"view_mode": {
@@ -962,9 +946,7 @@
"security_warning": "เคธเฅเคฐเคเฅเคทเคพ เคเฅเคคเคพเคตเคจเฅ",
"secure": "เคธเฅเคฐเคเฅเคทเคฟเคค",
"no_packages": "เคเฅเค เคชเฅเคเฅเค เคจเคนเฅเค เคฎเคฟเคฒเฅ"
- },
- "view_selected": "เคเคฏเคจเคฟเคค เคฆเฅเคเฅเค",
- "clear_selected_label": "เคเคฏเคจ เคธเคพเคซเคผ เคเคฐเฅเค"
+ }
},
"about": {
"title": "เคนเคฎเคพเคฐเฅ เคฌเคพเคฐเฅ เคฎเฅเค เคเคพเคจเคเคพเคฐเฅ",
@@ -1098,11 +1080,11 @@
"section_packages": "เคชเฅเคเฅเค",
"section_facets": "เคซเฅเคธเฅเคเฅเคธ",
"section_comparison": "เคคเฅเคฒเคจเคพ",
+ "copy_as_markdown": "เคคเคพเคฒเคฟเคเคพ เคเฅเคชเฅ เคเคฐเฅเค",
"loading": "เคชเฅเคเฅเค เคกเฅเคเคพ เคฒเฅเคก เคนเฅ เคฐเคนเคพ เคนเฅ...",
"error": "เคชเฅเคเฅเค เคกเฅเคเคพ เคฒเฅเคก เคเคฐเคจเฅ เคฎเฅเค เคตเคฟเคซเคฒเฅค เคเฅเคชเคฏเคพ เคชเฅเคจเค เคชเฅเคฐเคฏเคพเคธ เคเคฐเฅเคเฅค",
"empty_title": "เคคเฅเคฒเคจเคพ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค เคชเฅเคเฅเค เคเฅเคจเฅเค",
"empty_description": "เคเคจเคเฅ เคฎเฅเคเฅเคฐเคฟเคเฅเคธ เคเฅ เคธเคพเคฅ-เคธเคพเคฅ เคคเฅเคฒเคจเคพ เคฆเฅเคเคจเฅ เคเฅ เคฒเคฟเค เคเคชเคฐ เคเคฎ เคธเฅ เคเคฎ 2 เคชเฅเคเฅเค เคเฅเคเฅเค เคเคฐ เคเฅเคกเคผเฅเคเฅค",
- "copy_as_markdown": "เคคเคพเคฒเคฟเคเคพ เคเฅเคชเฅ เคเคฐเฅเค",
"table_view": "เคคเคพเคฒเคฟเคเคพ",
"charts_view": "เคเคพเคฐเฅเคเฅเคธ",
"bar_chart_nav_hint": "โ โ เคเคพ เคเคชเคฏเฅเค เคเคฐเฅเค",
@@ -1132,6 +1114,7 @@
"coming_soon": "เคเคฒเฅเคฆ เค เคฐเคนเคพ เคนเฅ",
"select_all": "เคธเคญเฅ เคซเฅเคธเฅเคเฅเคธ เคเฅเคจเฅเค",
"deselect_all": "เคธเคญเฅ เคซเฅเคธเฅเคเฅเคธ เค
เคเคฏเคจเคฟเคค เคเคฐเฅเค",
+ "binary_only_tooltip": "เคฏเคน เคชเฅเคเฅเค binaries เคฆเคฟเคเคพเคคเคพ เคนเฅ เคเคฐ exports เคจเคนเฅเค",
"categories": {
"performance": "เคชเฅเคฐเคฆเคฐเฅเคถเคจ",
"health": "เคธเฅเคตเคพเคธเฅเคฅเฅเคฏ",
@@ -1205,24 +1188,7 @@
},
"trends": {
"title": "เคฐเฅเคเคพเคจเฅเค เคเฅ เคคเฅเคฒเคจเคพ เคเคฐเฅเค"
- },
- "binary_only_tooltip": "เคฏเคน เคชเฅเคเฅเค binaries เคฆเคฟเคเคพเคคเคพ เคนเฅ เคเคฐ exports เคจเคนเฅเค"
- },
- "version_invalid_url_format": {
- "hint": "เค
เคฎเคพเคจเฅเคฏ เคคเฅเคฒเคจเคพ URL. เคฏเคน เคชเฅเคฐเคพเคฐเฅเคช เคเคชเคฏเฅเค เคเคฐเฅเค: {0}",
- "from_version": "from",
- "to_version": "to"
- },
- "file_filter_option": {
- "all": "เคธเคญเฅ ({count})",
- "added": "เคเฅเคกเคผเฅ เคเค ({count})",
- "removed": "เคนเคเคพเค เคเค ({count})",
- "modified": "เคธเคเคถเฅเคงเคฟเคค ({count})"
- },
- "filter": {
- "added": "เคเฅเคกเคผเฅ เคเค",
- "removed": "เคนเคเคพเค เคเค",
- "modified": "เคธเคเคถเฅเคงเคฟเคค"
+ }
},
"file_changes": "เคซเคผเคพเคเคฒ เคชเคฐเคฟเคตเคฐเฅเคคเคจ",
"files_count": "{count} เคซเคผเคพเคเคฒ | {count} เคซเคผเคพเคเคฒเฅเค",
@@ -1234,6 +1200,11 @@
"comparing_versions_label": "เคธเคเคธเฅเคเคฐเคฃเฅเค เคเฅ เคคเฅเคฒเคจเคพ เคเฅ เคเคพ เคฐเคนเฅ เคนเฅ...",
"version_back_to_package": "เคชเฅเคเฅเค เคชเคฐ เคตเคพเคชเคธ เคเคพเคเค",
"version_error_message": "เคธเคเคธเฅเคเคฐเคฃเฅเค เคเฅ เคคเฅเคฒเคจเคพ เคเคฐเคจเฅ เคฎเฅเค เคตเคฟเคซเคฒเฅค",
+ "version_invalid_url_format": {
+ "hint": "เค
เคฎเคพเคจเฅเคฏ เคคเฅเคฒเคจเคพ URL. เคฏเคน เคชเฅเคฐเคพเคฐเฅเคช เคเคชเคฏเฅเค เคเคฐเฅเค: {0}",
+ "from_version": "from",
+ "to_version": "to"
+ },
"version_selector_title": "เคธเคเคธเฅเคเคฐเคฃ เคธเฅ เคคเฅเคฒเคจเคพ เคเคฐเฅเค",
"summary": "เคธเคพเคฐเคพเคเคถ",
"deps_count": "{count} เคจเคฟเคฐเฅเคญเคฐเคคเคพ | {count} เคจเคฟเคฐเฅเคญเคฐเคคเคพเคเค",
@@ -1242,10 +1213,21 @@
"peer_dependencies": "เคชเฅเคฏเคฐ เคจเคฟเคฐเฅเคญเคฐเคคเคพเคเค",
"optional_dependencies": "เคตเฅเคเคฒเฅเคชเคฟเค เคจเคฟเคฐเฅเคญเคฐเคคเคพเคเค",
"no_dependency_changes": "เคจเคฟเคฐเฅเคญเคฐเคคเคพ เคฎเฅเค เคเฅเค เคชเคฐเคฟเคตเคฐเฅเคคเคจ เคจเคนเฅเค",
+ "file_filter_option": {
+ "all": "เคธเคญเฅ ({count})",
+ "added": "เคเฅเคกเคผเฅ เคเค ({count})",
+ "removed": "เคนเคเคพเค เคเค ({count})",
+ "modified": "เคธเคเคถเฅเคงเคฟเคค ({count})"
+ },
"search_files_placeholder": "เคซเคผเคพเคเคฒเฅเค เคเฅเคเฅเค...",
"no_files_all": "เคเฅเค เคซเคผเคพเคเคฒ เคจเคนเฅเค",
"no_files_search": "\"{query}\" เคธเฅ เคฎเฅเคฒ เคเคพเคคเฅ เคเฅเค เคซเคผเคพเคเคฒ เคจเคนเฅเค",
"no_files_filtered": "เคเฅเค {filter} เคซเคผเคพเคเคฒ เคจเคนเฅเค",
+ "filter": {
+ "added": "เคเฅเคกเคผเฅ เคเค",
+ "removed": "เคนเคเคพเค เคเค",
+ "modified": "เคธเคเคถเฅเคงเคฟเคค"
+ },
"files_button": "เคซเคผเคพเคเคฒเฅเค",
"select_file_prompt": "เคเคธเคเคพ diff เคฆเฅเคเคจเฅ เคเฅ เคฒเคฟเค sidebar เคธเฅ เคเค เคซเคผเคพเคเคฒ เคเฅเคจเฅเค",
"close_files_panel": "เคซเคผเคพเคเคฒ เคชเฅเคจเคฒ เคฌเคเคฆ เคเคฐเฅเค",
@@ -1263,6 +1245,8 @@
"word_wrap": "เคตเคฐเฅเคก เคฐเฅเคช"
},
"pds": {
+ "title": "npmx.social",
+ "meta_description": "npmx เคธเคฎเฅเคฆเคพเคฏ เคเฅ เคฒเคฟเค เคเคงเคฟเคเคพเคฐเคฟเค AT Protocol Personal Data Server (PDS)เฅค",
"join": {
"title": "เคธเคฎเฅเคฆเคพเคฏ เคธเฅ เคเฅเคกเคผเฅเค",
"description": "เคเคพเคนเฅ เคเคช atmosphere เคชเคฐ เค
เคชเคจเคพ เคชเคนเคฒเคพ เคเคพเคคเคพ เคฌเคจเคพ เคฐเคนเฅ เคนเฅเค เคฏเคพ เคเคฟเคธเฅ เคฎเฅเคเฅเคฆเคพ เคเคพเคคเฅ เคเฅ migrate เคเคฐ เคฐเคนเฅ เคนเฅเค, เคเคชเคเคพ เคฏเคนเคพเค เคธเฅเคตเคพเคเคค เคนเฅเฅค เคเคช เค
เคชเคจเคพ handle, เคชเฅเคธเฅเค เคฏเคพ followers เคเฅเค เคฌเคฟเคจเคพ เค
เคชเคจเฅ เคตเคฐเฅเคคเคฎเคพเคจ เคเคพเคคเฅ เคเฅ migrate เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค",
@@ -1286,11 +1270,12 @@
"empty": "เคฆเคฟเคเคพเคจเฅ เคเฅ เคฒเคฟเค เคเฅเค เคธเคฎเฅเคฆเคพเคฏ เคธเคฆเคธเฅเคฏ เคจเคนเฅเค เคนเฅเฅค",
"view_profile": "{handle} เคเฅ เคชเฅเคฐเฅเคซเคผเคพเคเคฒ เคฆเฅเคเฅเค",
"new_accounts": "...เคเคฐ {count} เคเฅ atmosphere เคชเคฐ เคจเค เคนเฅเค"
- },
- "title": "npmx.social",
- "meta_description": "npmx เคธเคฎเฅเคฆเคพเคฏ เคเฅ เคฒเคฟเค เคเคงเคฟเคเคพเคฐเคฟเค AT Protocol Personal Data Server (PDS)เฅค"
+ }
},
"privacy_policy": {
+ "title": "เคเฅเคชเคจเฅเคฏเคคเคพ เคจเฅเคคเคฟ",
+ "last_updated": "เค
เคเคคเคฟเคฎ เค
เคฆเฅเคฏเคคเคจ: {date}",
+ "welcome": "{app} เคฎเฅเค เคเคชเคเคพ เคธเฅเคตเคพเคเคค เคนเฅเฅค เคนเคฎ เคเคชเคเฅ เคเฅเคชเคจเฅเคฏเคคเคพ เคเฅ เคฐเคเฅเคทเคพ เคเฅ เคฒเคฟเค เคชเฅเคฐเคคเคฟเคฌเคฆเฅเคง เคนเฅเคเฅค เคฏเคน เคจเฅเคคเคฟ เคฌเคคเคพเคคเฅ เคนเฅ เคเคฟ เคนเคฎ เคเฅเคจ-เคธเคพ เคกเฅเคเคพ เคเคเคคเฅเคฐ เคเคฐเคคเฅ เคนเฅเค, เคเคธเคเคพ เคเคชเคฏเฅเค เคเฅเคธเฅ เคเคฐเคคเฅ เคนเฅเค, เคเคฐ เคเคชเคเฅ เคเคพเคจเคเคพเคฐเฅ เคธเฅ เคเฅเคกเคผเฅ เคเคชเคเฅ เค
เคงเคฟเคเคพเคฐ เคเฅเคฏเคพ เคนเฅเคเฅค",
"cookies": {
"what_are": {
"title": "เคเฅเคเฅเคเคผ เคเฅเคฏเคพ เคนเฅเค?",
@@ -1365,12 +1350,12 @@
"changes": {
"title": "เคเคธ เคจเฅเคคเคฟ เคฎเฅเค เคฌเคฆเคฒเคพเคต",
"p1": "เคนเคฎ เคธเคฎเคฏ-เคธเคฎเคฏ เคชเคฐ เคเคธ เคเฅเคชเคจเฅเคฏเคคเคพ เคจเฅเคคเคฟ เคเฅ เค
เคชเคกเฅเค เคเคฐ เคธเคเคคเฅ เคนเฅเคเฅค เคเคฟเคธเฅ เคญเฅ เคฌเคฆเคฒเคพเคต เคเฅ เคเคธ เคชเฅเค เคชเคฐ เค
เคฆเฅเคฏเคคเคจ เคธเคเคถเฅเคงเคจ เคคเคฟเคฅเคฟ เคเฅ เคธเคพเคฅ เคชเฅเคฐเคเคพเคถเคฟเคค เคเคฟเคฏเคพ เคเคพเคเคเคพเฅค"
- },
- "title": "เคเฅเคชเคจเฅเคฏเคคเคพ เคจเฅเคคเคฟ",
- "last_updated": "เค
เคเคคเคฟเคฎ เค
เคฆเฅเคฏเคคเคจ: {date}",
- "welcome": "{app} เคฎเฅเค เคเคชเคเคพ เคธเฅเคตเคพเคเคค เคนเฅเฅค เคนเคฎ เคเคชเคเฅ เคเฅเคชเคจเฅเคฏเคคเคพ เคเฅ เคฐเคเฅเคทเคพ เคเฅ เคฒเคฟเค เคชเฅเคฐเคคเคฟเคฌเคฆเฅเคง เคนเฅเคเฅค เคฏเคน เคจเฅเคคเคฟ เคฌเคคเคพเคคเฅ เคนเฅ เคเคฟ เคนเคฎ เคเฅเคจ-เคธเคพ เคกเฅเคเคพ เคเคเคคเฅเคฐ เคเคฐเคคเฅ เคนเฅเค, เคเคธเคเคพ เคเคชเคฏเฅเค เคเฅเคธเฅ เคเคฐเคคเฅ เคนเฅเค, เคเคฐ เคเคชเคเฅ เคเคพเคจเคเคพเคฐเฅ เคธเฅ เคเฅเคกเคผเฅ เคเคชเคเฅ เค
เคงเคฟเคเคพเคฐ เคเฅเคฏเคพ เคนเฅเคเฅค"
+ }
},
"a11y": {
+ "title": "เคธเฅเคเคฎเฅเคฏเคคเคพ",
+ "footer_title": "a11y",
+ "welcome": "เคนเคฎ เคเคพเคนเคคเฅ เคนเฅเค เคเคฟ {app} เค
เคงเคฟเค เคธเฅ เค
เคงเคฟเค เคฒเฅเคเฅเค เคเฅ เคฒเคฟเค เคเคชเคฏเฅเคเฅ เคนเฅเฅค",
"approach": {
"title": "เคนเคฎเคพเคฐเคพ เคฆเฅเคทเฅเคเคฟเคเฅเคฃ",
"p1": "เคนเคฎ Web Content Accessibility Guidelines (WCAG) 2.2 เคเคพ เคชเคพเคฒเคจ เคเคฐเคจเฅ เคเคพ เคชเฅเคฐเคฏเคพเคธ เคเคฐเคคเฅ เคนเฅเค เคเคฐ เคธเฅเคตเคฟเคงเคพเคเค เคฌเคจเคพเคคเฅ เคธเคฎเคฏ เคเคจเฅเคนเฅเค เคธเคเคฆเคฐเฅเคญ เคเฅ เคฐเฅเคช เคฎเฅเค เคเคชเคฏเฅเค เคเคฐเคคเฅ เคนเฅเคเฅค เคนเคฎ WCAG เคเฅ เคเคฟเคธเฅ เคญเฅ เคธเฅเคคเคฐ เคเฅ เคชเฅเคฐเฅเคฃ เค
เคจเฅเคฐเฅเคช เคนเฅเคจเฅ เคเคพ เคฆเคพเคตเคพ เคจเคนเฅเค เคเคฐเคคเฅ โ เคธเฅเคเคฎเฅเคฏเคคเคพ เคเค เคธเคคเคค เคชเฅเคฐเคเฅเคฐเคฟเคฏเคพ เคนเฅ เคเคฐ เค
เคญเฅ เคญเฅ เคฌเคนเฅเคค เคเคพเคฎ เคฌเคพเคเฅ เคนเฅเฅค",
@@ -1395,19 +1380,9 @@
"title": "เคชเฅเคฐเคคเคฟเคเฅเคฐเคฟเคฏเคพ",
"p1": "เคฏเคฆเคฟ เคเคชเคเฅ {app} เคชเคฐ เคเฅเค accessibility เคฌเคพเคงเคพ เคฆเคฟเคเคพเค เคฆเฅ, เคคเฅ เคเฅเคชเคฏเคพ เคนเคฎเคพเคฐเฅ {link} เคชเคฐ issue เคเฅเคฒเคเคฐ เคนเคฎเฅเค เคฌเคคเคพเคเคเฅค เคนเคฎ เคเคธเฅ เคฐเคฟเคชเฅเคฐเฅเคเฅเค เคเฅ เคเคเคญเฅเคฐเคคเคพ เคธเฅ เคฒเฅเคคเฅ เคนเฅเค เคเคฐ เคเคจเฅเคนเฅเค เค เฅเค เคเคฐเคจเฅ เคเคพ เคชเฅเคฐเคพ เคชเฅเคฐเคฏเคพเคธ เคเคฐเฅเคเคเฅเฅค",
"link": "GitHub เคฐเคฟเคชเฅเคเคฟเคเคฐเฅ"
- },
- "title": "เคธเฅเคเคฎเฅเคฏเคคเคพ",
- "footer_title": "a11y",
- "welcome": "เคนเคฎ เคเคพเคนเคคเฅ เคนเฅเค เคเคฟ {app} เค
เคงเคฟเค เคธเฅ เค
เคงเคฟเค เคฒเฅเคเฅเค เคเฅ เคฒเคฟเค เคเคชเคฏเฅเคเฅ เคนเฅเฅค"
+ }
},
"translation_status": {
- "table": {
- "file": "เคซเคผเคพเคเคฒ",
- "status": "เคธเฅเคฅเคฟเคคเคฟ",
- "error": "เคซเคผเคพเคเคฒ เคธเฅเคเฅ เคฒเฅเคก เคเคฐเคคเฅ เคธเคฎเคฏ เคคเฅเคฐเฅเคเคฟเฅค",
- "empty": "เคเฅเค เคซเคผเคพเคเคฒ เคจเคนเฅเค เคฎเคฟเคฒเฅ",
- "file_link": "GitHub เคชเคฐ {file} ({lang}) เคธเคเคชเคพเคฆเคฟเคค เคเคฐเฅเค"
- },
"title": "เค
เคจเฅเคตเคพเคฆ เคธเฅเคฅเคฟเคคเคฟ",
"generated_at": "เคจเคฟเคฐเฅเคฎเคพเคฃ เคคเคฟเคฅเคฟ: {date}",
"welcome": "เคฏเคฆเคฟ เคเคช เคจเฅเคเฅ เคธเฅเคเฅเคฌเคฆเฅเคง เคญเคพเคทเคพเคเค เคฎเฅเค เคธเฅ เคเคฟเคธเฅ เคเค เคฎเฅเค {npmx} เคเคพ เค
เคจเฅเคตเคพเคฆ เคเคฐเคจเฅ เคฎเฅเค เคนเคฎเคพเคฐเฅ เคฎเคฆเคฆ เคเคฐเคจเคพ เคเคพเคนเคคเฅ เคนเฅเค, เคคเฅ เคเคช เคธเคนเฅ เคเคเคน เคชเคฐ เคนเฅเค! เคฏเคน เค
เคชเคจเฅ-เคเคช เค
เคชเคกเฅเค เคนเฅเคจเฅ เคตเคพเคฒเคพ เคชเฅเค เคนเคฎเฅเคถเคพ เคตเคน เคธเคพเคฐเฅ เคธเคพเคฎเคเฅเคฐเฅ เคฆเคฟเคเคพเคคเคพ เคนเฅ, เคเคฟเคธเคฎเฅเค เคเคธ เคธเคฎเคฏ เคเคชเคเฅ เคฎเคฆเคฆ เคเฅ เคเคผเคฐเฅเคฐเคค เคนเฅเฅค",
@@ -1421,13 +1396,14 @@
"complete_text": "เคฏเคน เค
เคจเฅเคตเคพเคฆ เคชเฅเคฐเคพ เคนเฅ เคเฅเคเคพ เคนเฅ, เคถเคพเคจเคฆเคพเคฐ เคเคพเคฎ!",
"missing_text": "เคเคพเคฏเคฌ",
"missing_keys": "เคเฅเค เค
เคจเฅเคตเคพเคฆ เคเคพเคฏเคฌ เคจเคนเฅเค เคนเฅ | เค
เคจเฅเคตเคพเคฆ เคเคพเคฏเคฌ เคนเฅ | เค
เคจเฅเคตเคพเคฆ เคเคพเคฏเคฌ เคนเฅเค",
- "progress_label": "{locale} เคเฅ เคฒเคฟเค เคชเฅเคฐเคเคคเคฟ เคธเฅเคฅเคฟเคคเคฟ"
- },
- "action_bar": {
- "title": "เคเคเฅเคถเคจ เคฌเคพเคฐ",
- "selection": "0 เคเคฏเคจเคฟเคค | 1 เคเคฏเคจเคฟเคค | {count} เคเคฏเคจเคฟเคค",
- "shortcut": "เคเฅเคฐเคฟเคฏเคพเคเค เคชเคฐ เคซเคผเฅเคเคธ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค \"{key}\" เคฆเคฌเคพเคเค",
- "button_close_aria_label": "เคเคเฅเคถเคจ เคฌเคพเคฐ เคฌเคเคฆ เคเคฐเฅเค"
+ "progress_label": "{locale} เคเฅ เคฒเคฟเค เคชเฅเคฐเคเคคเคฟ เคธเฅเคฅเคฟเคคเคฟ",
+ "table": {
+ "file": "เคซเคผเคพเคเคฒ",
+ "status": "เคธเฅเคฅเคฟเคคเคฟ",
+ "error": "เคซเคผเคพเคเคฒ เคธเฅเคเฅ เคฒเฅเคก เคเคฐเคคเฅ เคธเคฎเคฏ เคคเฅเคฐเฅเคเคฟเฅค",
+ "empty": "เคเฅเค เคซเคผเคพเคเคฒ เคจเคนเฅเค เคฎเคฟเคฒเฅ",
+ "file_link": "GitHub เคชเคฐ {file} ({lang}) เคธเคเคชเคพเคฆเคฟเคค เคเคฐเฅเค"
+ }
},
"vacations": {
"title": "เคเฅเคเฅเคเฅ เคชเคฐ",
@@ -1462,5 +1438,18 @@
"all": "เคธเคญเฅ"
}
}
+ },
+ "action_bar": {
+ "title": "เคเคเฅเคถเคจ เคฌเคพเคฐ",
+ "selection": "0 เคเคฏเคจเคฟเคค | 1 เคเคฏเคจเคฟเคค | {count} เคเคฏเคจเคฟเคค",
+ "shortcut": "เคเฅเคฐเคฟเคฏเคพเคเค เคชเคฐ เคซเคผเฅเคเคธ เคเคฐเคจเฅ เคเฅ เคฒเคฟเค \"{key}\" เคฆเคฌเคพเคเค",
+ "button_close_aria_label": "เคเคเฅเคถเคจ เคฌเคพเคฐ เคฌเคเคฆ เคเคฐเฅเค"
+ },
+ "logo_menu": {},
+ "brand": {
+ "logos": {},
+ "customize": {},
+ "typography": {},
+ "guidelines": {}
}
}
diff --git a/i18n/locales/hu-HU.json b/i18n/locales/hu-HU.json
index b81921f621..0a0b19980c 100644
--- a/i18n/locales/hu-HU.json
+++ b/i18n/locales/hu-HU.json
@@ -716,12 +716,10 @@
"code": {
"files_label": "Fรกjlok",
"no_files": "Nincsenek fรกjlok ebben a kรถnyvtรกrban",
- "root": "gyรถkรฉr",
"lines": "{count} sor | {count} sor",
"toggle_tree": "Fรกjlfa kapcsolรกsa",
"close_tree": "Fรกjlfa bezรกrรกsa",
"copy_link": "Link mรกsolรกsa",
- "raw": "Nyers",
"view_raw": "Nyers fรกjl megtekintรฉse",
"file_too_large": "A fรกjl tรบl nagy az elลnรฉzethez",
"file_size_warning": "{size} meghaladja az 500KB-os limitet a szintaxis alapรบ formรกzรกshoz",
diff --git a/i18n/locales/id-ID.json b/i18n/locales/id-ID.json
index 7383879d8c..cfc0a7c451 100644
--- a/i18n/locales/id-ID.json
+++ b/i18n/locales/id-ID.json
@@ -441,8 +441,6 @@
},
"page_title": "Riwayat Versi",
"current_tags": "Tag Saat Ini",
- "version_filter_placeholder": "Filter versiโฆ",
- "version_filter_label": "Filter versi",
"no_match_filter": "Tidak ada versi yang cocok dengan {filter}"
},
"dependencies": {
@@ -825,12 +823,10 @@
"code": {
"files_label": "Berkas",
"no_files": "Tidak ada file di direktori ini",
- "root": "root",
"lines": "{count} baris",
"toggle_tree": "Ganti file tree",
"close_tree": "Tutup file tree",
"copy_link": "Salin tautan",
- "raw": "Raw",
"view_raw": "Lihat file mentah",
"file_too_large": "Berkas terlalu besar untuk pratinjau",
"file_size_warning": "{size} melebihi batas 500KB untuk penyorotan sintaksis",
@@ -1493,8 +1489,8 @@
"mark_light_alt": "Logo mark npmx dengan titik dan garis di latar terang",
"on_dark": "di latar gelap",
"on_light": "di latar terang",
- "download_png": "PNG",
"download_svg": "SVG",
+ "download_png": "PNG",
"download_svg_aria": "Unduh {name} sebagai SVG",
"download_png_aria": "Unduh {name} sebagai PNG"
},
diff --git a/i18n/locales/it-IT.json b/i18n/locales/it-IT.json
index d96207920b..8335afc24d 100644
--- a/i18n/locales/it-IT.json
+++ b/i18n/locales/it-IT.json
@@ -634,12 +634,10 @@
"code": {
"files_label": "File",
"no_files": "Nessun file in questa directory",
- "root": "root",
"lines": "{count} riga | {count} righe",
"toggle_tree": "Attiva/disattiva albero dei file",
"close_tree": "Chiudi albero dei file",
"copy_link": "Copia link",
- "raw": "Raw",
"view_raw": "Visualizza file raw",
"file_too_large": "File troppo grande per visualizzare l'anteprima",
"file_size_warning": "{size} supera il limite di 500 KB per l'evidenziatore di sintassi",
diff --git a/i18n/locales/ja-JP.json b/i18n/locales/ja-JP.json
index 2270f6c5d3..2d21d1fb99 100644
--- a/i18n/locales/ja-JP.json
+++ b/i18n/locales/ja-JP.json
@@ -769,12 +769,10 @@
"code": {
"files_label": "ใใกใคใซ",
"no_files": "ใใฎใใฃใฌใฏใใชใซใใกใคใซใฏใใใพใใ",
- "root": "ใซใผใ",
"lines": "{count} ่ก",
"toggle_tree": "ใใกใคใซใใชใผใๅใๆฟใ",
"close_tree": "ใใกใคใซใใชใผใ้ใใ",
"copy_link": "ใชใณใฏใใณใใผ",
- "raw": "RAW",
"view_raw": "RAWใใกใคใซใ่กจ็คบ",
"file_too_large": "ใใกใคใซใๅคงใใใใใใใใฌใใฅใผใงใใพใใ",
"file_size_warning": "{size} ใฏๆงๆๅผท่ชฟ่กจ็คบใฎๅถ้ใงใใ500KBใ่ถ
ใใฆใใพใ",
diff --git a/i18n/locales/kn-IN.json b/i18n/locales/kn-IN.json
index f8ec04fa88..a78955fe25 100644
--- a/i18n/locales/kn-IN.json
+++ b/i18n/locales/kn-IN.json
@@ -546,12 +546,10 @@
"code": {
"files_label": "เฒซเณเฒฒเณโเฒเฒณเณ",
"no_files": "เฒ เฒกเณเฒฐเณเฒเณเฒเฒฐเฒฟเฒฏเฒฒเณเฒฒเฒฟ เฒฏเฒพเฒตเณเฒฆเณ เฒซเณเฒฒเณโเฒเฒณเฒฟเฒฒเณเฒฒ",
- "root": "เฒฎเณเฒฒ",
"lines": "{count} เฒธเฒพเฒฒเณเฒเฒณเณ",
"toggle_tree": "เฒซเณเฒฒเณ เฒฎเฒฐเฒตเฒจเณเฒจเณ เฒเฒพเฒเฒฒเณ เฒฎเฒพเฒกเฒฟ",
"close_tree": "เฒซเณเฒฒเณ เฒฎเฒฐ เฒฎเณเฒเณเฒเฒฟ",
"copy_link": "เฒฒเฒฟเฒเฒเณ เฒจเฒเฒฒเฒฟเฒธเฒฟ",
- "raw": "เฒฐเฒพ",
"view_raw": "เฒฐเฒพ เฒซเณเฒฒเณ เฒจเณเฒกเฒฟ",
"file_too_large": "เฒชเณเฒฐเณเฒตเฒฆเณเฒถเณเฒฏเฒเณเฒเฒพเฒเฒฟ เฒซเณเฒฒเณ เฒคเณเฒเฒฌเฒพ เฒฆเณเฒกเณเฒกเฒฆเณ",
"file_size_warning": "{size} เฒธเฒฟเฒเฒเณเฒฏเฒพเฒเณเฒธเณ เฒนเณเฒฒเณเฒเฒฟเฒเฒเณโเฒเณ 500KB เฒฎเฒฟเฒคเฒฟเฒฏเฒจเณเฒจเณ เฒฎเณเฒฐเฒฟเฒฆเณ",
diff --git a/i18n/locales/mr-IN.json b/i18n/locales/mr-IN.json
index c2684b5a49..dd8ee3d746 100644
--- a/i18n/locales/mr-IN.json
+++ b/i18n/locales/mr-IN.json
@@ -22,23 +22,7 @@
"keyboard_shortcuts": "เคเฅเคฌเฅเคฐเฅเคก เคถเฅเคฐเฅเคเคเค"
},
"shortcuts": {
- "section": {
- "global": "เคเคพเคเคคเคฟเค",
- "search": "เคถเฅเคง",
- "package": "เคชเฅ
เคเฅเค"
- },
- "focus_search": "เคถเฅเคงเคพเคตเคฐ เคซเฅเคเคธ เคเคฐเคพ",
- "show_kbd_hints": "เคเฅเคฌเฅเคฐเฅเคก เคธเฅเคเคจเคพเคเคจเคพ เค เคณเค เคเคฐเคพ",
- "settings": "เคธเฅเคเคฟเคเคเฅเค เคเคเคกเคพ",
- "compare": "เคคเฅเคฒเคจเคพ เคเคเคกเคพ",
- "compare_from_package": "เคคเฅเคฒเคจเคพ เคเคเคกเคพ (เคธเคงเฅเคฏเคพเคเฅเคฏเคพ เคชเฅ
เคเฅเคเคธเคน เคชเฅเคฐเฅเคตเคญเคฐเคฒเฅเคฒเฅ)",
- "navigate_results": "เคชเคฐเคฟเคฃเคพเคฎเคพเคเคฎเคงเฅเคฏเฅ เคซเคฟเคฐเคพ",
- "go_to_result": "เคชเคฐเคฟเคฃเคพเคฎเคพเคเคกเฅ เคเคพ",
- "open_code_view": "เคเฅเคก เคฆเฅเคถเฅเคฏ เคเคเคกเคพ",
- "open_docs": "เคฆเคธเฅเคคเคเคตเค เคเคเคกเคพ",
- "disable_shortcuts": "เคคเฅเคฎเฅเคนเฅ {settings} เคฎเคงเฅเคฏเฅ เคเฅเคฌเฅเคฐเฅเคก เคถเฅเคฐเฅเคเคเค เค
เคเฅเคทเคฎ เคเคฐเฅ เคถเคเคคเคพ.",
- "open_main": "เคฎเฅเคเฅเคฏ เคฎเคพเคนเคฟเคคเฅ เคเคเคกเคพ",
- "open_diff": "เคเคตเฅเคคเฅเคคเฅเคคเฅเคฒ เคซเคฐเค เคเคเคกเคพ"
+ "section": {}
},
"search": {
"label": "npm เคชเฅ
เคเฅเคเฅเคธ เคถเฅเคงเคพ",
@@ -229,21 +213,7 @@
"expand": "เคตเคฟเคธเฅเคคเฅเคค เคเคฐเคพ"
},
"profile": {
- "display_name": "เคชเฅเคฐเคฆเคฐเฅเคถเคจ เคจเคพเคต",
- "description": "เคตเคฐเฅเคฃเคจ",
- "no_description": "เคตเคฐเฅเคฃเคจ เคจเคพเคนเฅ",
- "website": "เคตเฅเคฌเคธเคพเคเค",
- "website_placeholder": "https://example.com",
- "likes": "เคชเคธเคเคคเฅ",
- "seo_title": "{handle} - npmx",
- "seo_description": "{handle} เคฆเฅเคตเคพเคฐเฅ npmx เคชเฅเคฐเฅเคซเคพเคเคฒ",
- "not_found": "เคชเฅเคฐเฅเคซเคพเคเคฒ เคธเคพเคชเคกเคฒเฅ เคจเคพเคนเฅ",
- "not_found_message": "{handle} เคธเคพเค เฅเคเฅ เคชเฅเคฐเฅเคซเคพเคเคฒ เคธเคพเคชเคกเคฒเฅ เคจเคพเคนเฅ.",
- "invite": {
- "message": "เคคเฅ เค
เคเฅเคจ npmx เคตเคพเคชเคฐเคค เคเคนเฅเคค เค
เคธเฅ เคฆเคฟเคธเคค เคจเคพเคนเฅ. เคคเฅเคฏเคพเคเคจเคพ เคฏเคพเคฌเคฆเฅเคฆเคฒ เคธเคพเคเคเคพเคฏเคเฅ เคเคพ?",
- "share_button": "Bluesky เคตเคฐ เคถเฅเค
เคฐ เคเคฐเคพ",
- "compose_text": "เค
เคนเฅ {'@'}{handle}! เคคเฅเคฎเฅเคนเฅ เค
เคเฅเคจ npmx.dev เคชเคพเคนเคฟเคฒเฅ เคเคนเฅ เคเคพ? เคนเคพ npm เคจเฅเคเคฆเคฃเฅเคธเคพเค เฅ เคเคฒเคฆ, เคเคงเฅเคจเคฟเค เคเคฃเคฟ เคฎเฅเคเฅเคค-เคธเฅเคฐเฅเคค เคฌเฅเคฐเคพเคเคเคฐ เคเคนเฅ.\nhttps://npmx.dev"
- }
+ "invite": {}
},
"package": {
"not_found": "เคชเฅ
เคเฅเค เคธเคพเคชเคกเคฒเฅ เคจเคพเคนเฅ",
@@ -440,8 +410,6 @@
},
"page_title": "เคเคตเฅเคคเฅเคคเฅ เคเคคเคฟเคนเคพเคธ",
"current_tags": "เคธเคงเฅเคฏเคพเคเฅ เคเฅ
เคเฅเคธ",
- "version_filter_placeholder": "เคเคตเฅเคคเฅเคคเฅเคฏเคพ เคซเคฟเคฒเฅเคเคฐ เคเคฐเคพโฆ",
- "version_filter_label": "เคเคตเฅเคคเฅเคคเฅเคฏเคพ เคซเคฟเคฒเฅเคเคฐ เคเคฐเคพ",
"no_match_filter": "{filter} เคถเฅ เคเฅเคณเคฃเคพเคฐเฅ เคเฅเคฃเคคเฅเคนเฅ เคเคตเฅเคคเฅเคคเฅ เคจเคพเคนเฅ"
},
"dependencies": {
@@ -815,12 +783,10 @@
"code": {
"files_label": "เคซเคพเคฏเคฒเฅ",
"no_files": "เคเฅเคฃเคคเฅเคฏเคพเคนเฅ เคซเคพเคเคฒเฅเคธ เคเคชเคฒเคฌเฅเคง เคจเคพเคนเฅเคค",
- "root": "เคฎเฅเคณ",
"lines": "{count} เคเคณเฅ",
"toggle_tree": "เคซเคพเคเคฒ เคเฅเคฐเฅ เคเฅเคเคฒ เคเคฐเคพ",
"close_tree": "เคซเคพเคเคฒ เคเฅเคฐเฅ เคฌเคเคฆ เคเคฐเคพ",
"copy_link": "เคฒเคฟเคเค เคเฅเคชเฅ เคเคฐเคพ",
- "raw": "เคเคเฅเคเคพ",
"view_raw": "เคเคเฅเคเฅ เคซเคพเคเคฒ เคชเคนเคพ",
"file_too_large": "เคชเฅเคฐเฅเคตเคพเคตเคฒเฅเคเคจเคพเคธเคพเค เฅ เคซเคพเคเคฒ เคเฅเคช เคฎเฅเค เฅ เคเคนเฅ",
"file_size_warning": "{size} เคนเฅ เคธเคฟเคเคเฅ
เคเฅเคธ เคนเคพเคฏเคฒเคพเคเคเคฟเคเคเคธเคพเค เฅเคเฅเคฏเคพ 500KB เคฎเคฐเฅเคฏเคพเคฆเฅเคชเฅเคเฅเคทเคพ เคเคพเคธเฅเคค เคเคนเฅ",
diff --git a/i18n/locales/nb-NO.json b/i18n/locales/nb-NO.json
index cb919c567b..eaebd471e5 100644
--- a/i18n/locales/nb-NO.json
+++ b/i18n/locales/nb-NO.json
@@ -13,13 +13,13 @@
"trademark_disclaimer": "npm er et registrert varemerke for npm, Inc. Dette nettstedet er ikke tilknyttet npm, Inc.",
"footer": {
"about": "om",
+ "blog": "blogg",
"docs": "dokumentasjon",
"source": "kildekode",
"social": "sosialt",
"chat": "chat",
- "keyboard_shortcuts": "tastatursnarveier",
- "blog": "blogg",
"builders_chat": "utviklere",
+ "keyboard_shortcuts": "tastatursnarveier",
"brand": "merkevare"
},
"shortcuts": {
@@ -89,9 +89,15 @@
"tap_to_search": "Trykk for รฅ sรธke"
},
"blog": {
+ "title": "Blogg",
+ "heading": "blogg",
+ "meta_description": "Innsikt og oppdateringer fra npmx-fellesskapet",
"author": {
"view_profile": "Vis {name}s profil pรฅ Bluesky"
},
+ "draft_badge": "Utkast",
+ "draft_banner": "Dette er et upublisert utkast. Det kan vรฆre ufullstendig eller inneholde unรธyaktigheter.",
+ "no_posts": "Ingen innlegg funnet.",
"atproto": {
"view_on_bluesky": "Vis pรฅ Bluesky",
"reply_on_bluesky": "Svar pรฅ Bluesky",
@@ -106,13 +112,7 @@
"like_count": "{count} likerklikk | {count} likerklikk",
"repost_count": "{count} deling | {count} delinger",
"more_replies": "{count} svar til... | {count} svar til..."
- },
- "title": "Blogg",
- "heading": "blogg",
- "meta_description": "Innsikt og oppdateringer fra npmx-fellesskapet",
- "draft_badge": "Utkast",
- "draft_banner": "Dette er et upublisert utkast. Det kan vรฆre ufullstendig eller inneholde unรธyaktigheter.",
- "no_posts": "Ingen innlegg funnet."
+ }
},
"settings": {
"title": "innstillinger",
@@ -133,17 +133,22 @@
"algolia": "Algolia",
"algolia_description": "Bruker Algolia for raskere sรธk, org- og brukersider."
},
+ "instant_search": "Hurtigsรธk",
+ "instant_search_description": "Navigerer til sรธkesiden og oppdaterer resultatene mens du skriver.",
"relative_dates": "Relative datoer",
"include_types": "Inkluder {'@'}types ved installasjon",
"include_types_description": "Legg til {'@'}types-pakken i installasjonskommandoer for pakker uten typer",
"hide_platform_packages": "Skjul plattformspesifikke pakker i sรธk",
"hide_platform_packages_description": "Skjul binรฆrpakker som {'@'}esbuild/linux-x64 fra resultatene",
+ "enable_graph_pulse_loop": "Aktiver pulseffekt-lรธkke pรฅ mini-graf",
+ "enable_graph_pulse_loop_description": "Aktiver en kontinuerlig pulsanimasjon pรฅ ukentlig nedlastingsgraf. Denne animasjonen kan vรฆre forstyrrende for noen brukere.",
"theme": "Tema",
"theme_light": "Lys",
"theme_dark": "Mรธrk",
"theme_system": "System",
"language": "Sprรฅk",
"help_translate": "Hjelp med รฅ oversette npmx",
+ "translation_status": "Sjekk global oversettelsesstatus",
"accent_colors": {
"label": "Aksentfarger",
"sky": "Himmel",
@@ -163,11 +168,6 @@
"slate": "Skifer",
"black": "Svart"
},
- "instant_search": "Hurtigsรธk",
- "instant_search_description": "Navigerer til sรธkesiden og oppdaterer resultatene mens du skriver.",
- "enable_graph_pulse_loop": "Aktiver pulseffekt-lรธkke pรฅ mini-graf",
- "enable_graph_pulse_loop_description": "Aktiver en kontinuerlig pulsanimasjon pรฅ ukentlig nedlastingsgraf. Denne animasjonen kan vรฆre forstyrrende for noen brukere.",
- "translation_status": "Sjekk global oversettelsesstatus",
"keyboard_shortcuts_enabled": "Aktiver tastatursnarveier",
"keyboard_shortcuts_enabled_description": "Tastatursnarveier kan deaktiveres hvis de er i konflikt med andre nettleser- eller systemsnarveier"
},
@@ -193,6 +193,7 @@
"end_of_results": "Slutt pรฅ resultater",
"try_again": "Prรธv igjen",
"close": "Lukk",
+ "or": "eller",
"retry": "Prรธv pรฅ nytt",
"copy": "kopier",
"copied": "kopiert!",
@@ -207,6 +208,10 @@
"members": "medlemmer"
},
"scroll_to_top": "Rull til toppen",
+ "cancel": "Avbryt",
+ "save": "Lagre",
+ "edit": "Rediger",
+ "error": "Feil",
"view_on": {
"npm": "vis pรฅ npm",
"github": "Vis pรฅ GitHub",
@@ -221,20 +226,10 @@
"sourcehut": "Vis pรฅ SourceHut",
"tangled": "Vis pรฅ Tangled"
},
- "or": "eller",
- "cancel": "Avbryt",
- "save": "Lagre",
- "edit": "Rediger",
- "error": "Feil",
"collapse": "Skjul",
"expand": "Utvid"
},
"profile": {
- "invite": {
- "message": "Det ser ikke ut som de bruker npmx ennรฅ. Vil du fortelle dem om det?",
- "share_button": "Del pรฅ Bluesky",
- "compose_text": "Hei {'@'}{handle}! Har du sjekket ut npmx.dev ennรฅ? Det er en leser for npm-registeret som er rask, moderne og รฅpen kildekode.\nhttps://npmx.dev"
- },
"display_name": "Visningsnavn",
"description": "Beskrivelse",
"no_description": "Ingen beskrivelse",
@@ -244,7 +239,12 @@
"seo_title": "{handle} - npmx",
"seo_description": "npmx-profil av {handle}",
"not_found": "Profil ikke funnet",
- "not_found_message": "Profilen for {handle} ble ikke funnet."
+ "not_found_message": "Profilen for {handle} ble ikke funnet.",
+ "invite": {
+ "message": "Det ser ikke ut som de bruker npmx ennรฅ. Vil du fortelle dem om det?",
+ "share_button": "Del pรฅ Bluesky",
+ "compose_text": "Hei {'@'}{handle}! Har du sjekket ut npmx.dev ennรฅ? Det er en leser for npm-registeret som er rask, moderne og รฅpen kildekode.\nhttps://npmx.dev"
+ }
},
"package": {
"not_found": "Pakke ikke funnet",
@@ -310,6 +310,7 @@
"skills_cli": "skills-kommandolinje"
},
"links": {
+ "main": "hoved",
"repo": "repo",
"homepage": "hjemmeside",
"issues": "saker",
@@ -318,7 +319,6 @@
"docs": "dok",
"fund": "stรธtt",
"compare": "sammenlign",
- "main": "hoved",
"compare_this_package": "sammenlign denne pakken"
},
"likes": {
@@ -326,10 +326,10 @@
"unlike": "Fjern like fra denne pakken"
},
"docs": {
- "not_available": "Dokumentasjon ikke tilgjengelig",
- "not_available_detail": "Vi kunne ikke generere dokumentasjon for denne versjonen.",
"contents": "Innhold",
"default_not_available": "Dokumentasjon er ikke tilgjengelig for denne versjonen.",
+ "not_available": "Dokumentasjon ikke tilgjengelig",
+ "not_available_detail": "Vi kunne ikke generere dokumentasjon for denne versjonen.",
"page_title": "API-dokumentasjon - npmx",
"page_title_name": "{name}-dokumentasjon - npmx",
"page_title_version": "{name}-dokumentasjon - npmx",
@@ -340,9 +340,9 @@
"title": "Kom i gang",
"pm_label": "Pakkebehandler",
"copy_command": "Kopier installeringskommando",
- "view_types": "Vis {package}",
"copy_dev_command": "Kopier dev-installeringskommando",
- "dev_dependency_hint": "Installeres vanligvis som en utviklingsavhengighet"
+ "dev_dependency_hint": "Installeres vanligvis som en utviklingsavhengighet",
+ "view_types": "Vis {package}"
},
"create": {
"title": "Opprett nytt prosjekt",
@@ -411,10 +411,6 @@
"all_covered": "Alle versjoner dekkes av taggene over",
"deprecated_title": "{version} (utfaset)",
"view_all": "Vis {count} versjon | Vis alle {count} versjoner",
- "copy_alt": {
- "per_version_analysis": "{version}-versjonen ble lastet ned {downloads} ganger",
- "general_description": "Stolpediagram som viser nedlastinger per versjon for {versions_count} {semver_grouping_mode}-versjoner av {package_name}-pakken, {date_range_label} fra {first_version}-versjonen til {last_version}-versjonen. Den mest nedlastede versjonen er {max_downloaded_version} med {max_version_downloads} nedlastinger. {per_version_analysis}. {watermark}."
- },
"view_all_versions": "Vis alle versjoner",
"distribution_title": "Semver-gruppe",
"distribution_modal_title": "Versjoner",
@@ -439,10 +435,12 @@
"filter_tooltip": "Filtrer versjoner ved hjelp av et {link}. For eksempel viser ^3.0.0 alle 3.x-versjoner.",
"filter_tooltip_link": "semver-omrรฅde",
"no_matches": "Ingen versjoner matcher dette omrรฅdet",
+ "copy_alt": {
+ "per_version_analysis": "{version}-versjonen ble lastet ned {downloads} ganger",
+ "general_description": "Stolpediagram som viser nedlastinger per versjon for {versions_count} {semver_grouping_mode}-versjoner av {package_name}-pakken, {date_range_label} fra {first_version}-versjonen til {last_version}-versjonen. Den mest nedlastede versjonen er {max_downloaded_version} med {max_version_downloads} nedlastinger. {per_version_analysis}. {watermark}."
+ },
"page_title": "Versjonshistorikk",
"current_tags": "Nรฅvรฆrende tagger",
- "version_filter_placeholder": "Filtrer versjonerโฆ",
- "version_filter_label": "Filtrer versjoner",
"no_match_filter": "Ingen versjoner matcher {filter}"
},
"dependencies": {
@@ -483,6 +481,12 @@
"maintainer_template": "{avatar} {char126}{name}"
},
"trends": {
+ "chart_assistive_text": {
+ "keyboard_navigation_horizontal": "Bruk venstre og hรธyre piltaster for รฅ bla gjennom datapunkter.",
+ "keyboard_navigation_vertical": "Bruk opp og ned piltaster for รฅ bla gjennom datapunkter.",
+ "table_available": "En datatabell for dette diagrammet er tilgjengelig nedenfor.",
+ "table_caption": "Diagramdatatabell"
+ },
"granularity": "Opplรธsning",
"granularity_daily": "Daglig",
"granularity_weekly": "Ukentlig",
@@ -495,14 +499,32 @@
"date_range_multiline": "{start}\ntil {end}",
"download_file": "Last ned {fileType}",
"toggle_annotator": "Veksle annotering",
+ "toggle_stack_mode": "Veksle stablingsmodus",
+ "open_options": "ร
pne alternativer",
+ "close_options": "Lukk alternativer",
"legend_estimation": "Estimat",
"no_data": "Ingen data tilgjengelig",
"y_axis_label": "{granularity} {facet}",
+ "facet": "Fasett",
+ "title": "Trender",
+ "contributors_skip": "Ikke vist i Bidragsytere (ingen GitHub-repo):",
"items": {
"downloads": "Nedlastinger",
"likes": "Likerklikk",
"contributors": "Bidragsytere"
},
+ "data_correction": "Datakorrigering",
+ "average_window": "Gjennomsnittsvindu",
+ "smoothing": "Utjevning",
+ "prediction": "Prediksjon",
+ "known_anomalies": "Kjente anomalier",
+ "known_anomalies_description": "Interpolerer over kjente nedlastingstopper forรฅrsaket av roboter eller CI-problemer.",
+ "known_anomalies_ranges": "Anomaliomrรฅder",
+ "known_anomalies_range": "Fra {start} til {end}",
+ "known_anomalies_range_named": "{packageName}: fra {start} til {end}",
+ "known_anomalies_none": "Ingen kjente anomalier for denne pakken. | Ingen kjente anomalier for disse pakkene.",
+ "known_anomalies_contribute": "Bidra med anomalidata",
+ "apply_correction": "Bruk korrigering",
"copy_alt": {
"trend_none": "hovedsakelig flat",
"trend_strong": "sterk",
@@ -518,31 +540,7 @@
"general_description": "Y-aksen representerer antall nedlastinger. X-aksen representerer datoomrรฅdet, fra {start_date} til {end_date}, med en {granularity} tidsperiode.{estimation_notice} {packages_analysis}. {watermark}.",
"facet_bar_general_description": "Horisontalt stolpediagram for: {packages}, sammenligner {facet} ({description}). {facet_analysis} {watermark}.",
"facet_bar_analysis": "{package_name} har en verdi pรฅ {value}."
- },
- "chart_assistive_text": {
- "keyboard_navigation_horizontal": "Bruk venstre og hรธyre piltaster for รฅ bla gjennom datapunkter.",
- "keyboard_navigation_vertical": "Bruk opp og ned piltaster for รฅ bla gjennom datapunkter.",
- "table_available": "En datatabell for dette diagrammet er tilgjengelig nedenfor.",
- "table_caption": "Diagramdatatabell"
- },
- "toggle_stack_mode": "Veksle stablingsmodus",
- "open_options": "ร
pne alternativer",
- "close_options": "Lukk alternativer",
- "facet": "Fasett",
- "title": "Trender",
- "contributors_skip": "Ikke vist i Bidragsytere (ingen GitHub-repo):",
- "data_correction": "Datakorrigering",
- "average_window": "Gjennomsnittsvindu",
- "smoothing": "Utjevning",
- "prediction": "Prediksjon",
- "known_anomalies": "Kjente anomalier",
- "known_anomalies_description": "Interpolerer over kjente nedlastingstopper forรฅrsaket av roboter eller CI-problemer.",
- "known_anomalies_ranges": "Anomaliomrรฅder",
- "known_anomalies_range": "Fra {start} til {end}",
- "known_anomalies_range_named": "{packageName}: fra {start} til {end}",
- "known_anomalies_none": "Ingen kjente anomalier for denne pakken. | Ingen kjente anomalier for disse pakkene.",
- "known_anomalies_contribute": "Bidra med anomalidata",
- "apply_correction": "Bruk korrigering"
+ }
},
"downloads": {
"title": "Ukentlige nedlastinger",
@@ -564,11 +562,11 @@
"esm": "ES Modules stรธttet",
"cjs": "CommonJS stรธttet",
"no_esm": "Ingen ES Modules-stรธtte",
+ "wasm": "Har WebAssembly",
"types_label": "Typer",
"types_included": "Typer inkludert",
"types_available": "Typer tilgjengelig via {package}",
- "no_types": "Ingen TypeScript-typer",
- "wasm": "Har WebAssembly"
+ "no_types": "Ingen TypeScript-typer"
},
"license": {
"view_spdx": "Vis lisenstekst pรฅ SPDX",
@@ -679,7 +677,9 @@
"otp_placeholder": "Skriv inn OTP-kode...",
"otp_label": "Engangskode (OTP)",
"retry_otp": "Prรธv igjen med OTP",
+ "retry_web_auth": "Prรธv igjen med nettautentisering",
"retrying": "Prรธver pรฅ nytt...",
+ "open_web_auth": "ร
pne nettautentiseringslenke",
"approve_operation": "Godkjenn operasjon",
"remove_operation": "Fjern operasjon",
"approve_all": "Godkjenn alle",
@@ -687,9 +687,7 @@
"executing": "Utfรธrer...",
"log": "Logg",
"log_label": "Fullfรธrte operasjoner logg",
- "remove_from_log": "Fjern fra logg",
- "retry_web_auth": "Prรธv igjen med nettautentisering",
- "open_web_auth": "ร
pne nettautentiseringslenke"
+ "remove_from_log": "Fjern fra logg"
}
},
"org": {
@@ -803,6 +801,7 @@
"invalid_name": "Ugyldig pakkenavn:",
"available": "Dette navnet er ledig!",
"taken": "Dette navnet er allerede opptatt.",
+ "missing_permission": "Du har ikke tillatelse til รฅ legge til en pakke i scope {'@'}{scope}.",
"similar_warning": "Lignende pakker finnes - npm kan avvise dette navnet:",
"related": "Relaterte pakker:",
"scope_warning_title": "Vurder รฅ bruke en scoped pakke i stedet",
@@ -815,19 +814,16 @@
"publishing": "Publiserer...",
"checking": "Sjekker tilgjengelighet...",
"failed_to_check": "Kunne ikke sjekke navnetilgjengelighet",
- "failed_to_claim": "Kunne ikke gjรธre krav pรฅ pakke",
- "missing_permission": "Du har ikke tillatelse til รฅ legge til en pakke i scope {'@'}{scope}."
+ "failed_to_claim": "Kunne ikke gjรธre krav pรฅ pakke"
}
},
"code": {
"files_label": "Filer",
"no_files": "Ingen filer i denne mappen",
- "root": "rot",
"lines": "{count} linje | {count} linjer",
"toggle_tree": "Veksle filtre",
"close_tree": "Lukk filtre",
"copy_link": "Kopier lenke",
- "raw": "Rรฅ",
"view_raw": "Vis rรฅfil",
"file_too_large": "Filen er for stor til รฅ forhรฅndsvises",
"file_size_warning": "{size} overstiger grensen pรฅ 500KB for syntaksmarkering",
@@ -910,6 +906,8 @@
"secure": "Uten advarsler",
"insecure": "Med advarsler"
},
+ "view_selected": "Vis valgte",
+ "clear_selected_label": "Fjern valgte",
"sort": {
"label": "Sorter pakker",
"toggle_direction": "Veksle sorteringsrekkefรธlge",
@@ -963,9 +961,7 @@
"security_warning": "Sikkerhetsadvarsel",
"secure": "Sikker",
"no_packages": "Ingen pakker funnet"
- },
- "view_selected": "Vis valgte",
- "clear_selected_label": "Fjern valgte"
+ }
},
"about": {
"title": "Om",
@@ -1099,11 +1095,11 @@
"section_packages": "Pakker",
"section_facets": "Fasetter",
"section_comparison": "Sammenligning",
+ "copy_as_markdown": "Kopier tabell",
"loading": "Laster pakkedata...",
"error": "Kunne ikke laste pakkedata. Vennligst prรธv igjen.",
"empty_title": "Velg pakker รฅ sammenligne",
"empty_description": "Sรธk og legg til minst 2 pakker ovenfor for รฅ se en side-om-side sammenligning av deres metrikker.",
- "copy_as_markdown": "Kopier tabell",
"table_view": "Tabell",
"charts_view": "Diagrammer",
"bar_chart_nav_hint": "Bruk โ โ",
@@ -1130,6 +1126,10 @@
"facets": {
"all": "alle",
"none": "ingen",
+ "select_all_category_facets": "Velg alle {category}-fasetter",
+ "deselect_all_category_facets": "Fravelg alle {category}-fasetter",
+ "selected_all_category_facets": "Valgte alle {category}-fasetter",
+ "deselected_all_category_facets": "Fravalgte alle {category}-fasetter",
"coming_soon": "Kommer snart",
"select_all": "Velg alle fasetter",
"deselect_all": "Fravelg alle fasetter",
@@ -1207,27 +1207,7 @@
},
"trends": {
"title": "Sammenlign trender"
- },
- "select_all_category_facets": "Velg alle {category}-fasetter",
- "deselect_all_category_facets": "Fravelg alle {category}-fasetter",
- "selected_all_category_facets": "Valgte alle {category}-fasetter",
- "deselected_all_category_facets": "Fravalgte alle {category}-fasetter"
- },
- "version_invalid_url_format": {
- "hint": "Ugyldig sammenlignings-URL. Bruk formatet: {0}",
- "from_version": "fra",
- "to_version": "til"
- },
- "file_filter_option": {
- "all": "Alle ({count})",
- "added": "Lagt til ({count})",
- "removed": "Fjernet ({count})",
- "modified": "Endret ({count})"
- },
- "filter": {
- "added": "lagt til",
- "removed": "fjernet",
- "modified": "endret"
+ }
},
"file_changes": "Filendringer",
"files_count": "{count} fil | {count} filer",
@@ -1239,6 +1219,11 @@
"comparing_versions_label": "Sammenligner versjoner...",
"version_back_to_package": "Tilbake til pakke",
"version_error_message": "Kunne ikke sammenligne versjoner.",
+ "version_invalid_url_format": {
+ "hint": "Ugyldig sammenlignings-URL. Bruk formatet: {0}",
+ "from_version": "fra",
+ "to_version": "til"
+ },
"version_selector_title": "Sammenlign med versjon",
"summary": "Sammendrag",
"deps_count": "{count} avh. | {count} avh.",
@@ -1247,10 +1232,21 @@
"peer_dependencies": "Peer-avhengigheter",
"optional_dependencies": "Valgfrie avhengigheter",
"no_dependency_changes": "Ingen avhengighetsendringer",
+ "file_filter_option": {
+ "all": "Alle ({count})",
+ "added": "Lagt til ({count})",
+ "removed": "Fjernet ({count})",
+ "modified": "Endret ({count})"
+ },
"search_files_placeholder": "Sรธk i filer...",
"no_files_all": "Ingen filer",
"no_files_search": "Ingen filer matcher ยซ{query}ยป",
"no_files_filtered": "Ingen {filter} filer",
+ "filter": {
+ "added": "lagt til",
+ "removed": "fjernet",
+ "modified": "endret"
+ },
"files_button": "Filer",
"select_file_prompt": "Velg en fil fra sidepanelet for รฅ se dens diff",
"close_files_panel": "Lukk filpanelet",
@@ -1268,6 +1264,8 @@
"word_wrap": "Tekstbryting"
},
"pds": {
+ "title": "npmx.social",
+ "meta_description": "Den offisielle AT Protocol Personal Data Server (PDS) for npmx-fellesskapet.",
"join": {
"title": "Bli med i fellesskapet",
"description": "Enten du oppretter din fรธrste konto pรฅ atmosfรฆren eller migrerer en eksisterende, hรธrer du hjemme her. Du kan migrere din nรฅvรฆrende konto uten รฅ miste hรฅndtaket, innleggene eller fรธlgerne dine.",
@@ -1291,11 +1289,12 @@
"empty": "Ingen fellesskapsmedlemmer รฅ vise.",
"view_profile": "Vis {handle}s profil",
"new_accounts": "...pluss {count} flere som er nye i atmosfรฆren"
- },
- "title": "npmx.social",
- "meta_description": "Den offisielle AT Protocol Personal Data Server (PDS) for npmx-fellesskapet."
+ }
},
"privacy_policy": {
+ "title": "personvernpolicy",
+ "last_updated": "Sist oppdatert: {date}",
+ "welcome": "Velkommen til {app}. Vi er forpliktet til รฅ beskytte personvernet ditt. Denne policyen forklarer hvilke data vi samler inn, hvordan vi bruker dem, og dine rettigheter angรฅende informasjonen din.",
"cookies": {
"what_are": {
"title": "Hva er informasjonskapsler?",
@@ -1370,12 +1369,12 @@
"changes": {
"title": "Endringer i denne policyen",
"p1": "Vi kan oppdatere denne personvernpolicyen fra tid til annen. Eventuelle endringer vil bli publisert pรฅ denne siden med en oppdatert revisjonsdato."
- },
- "title": "personvernpolicy",
- "last_updated": "Sist oppdatert: {date}",
- "welcome": "Velkommen til {app}. Vi er forpliktet til รฅ beskytte personvernet ditt. Denne policyen forklarer hvilke data vi samler inn, hvordan vi bruker dem, og dine rettigheter angรฅende informasjonen din."
+ }
},
"a11y": {
+ "title": "tilgjengelighet",
+ "footer_title": "a11y",
+ "welcome": "Vi รธnsker at {app} skal kunne brukes av sรฅ mange mennesker som mulig.",
"approach": {
"title": "Vรฅr tilnรฆrming",
"p1": "Vi prรธver รฅ fรธlge retningslinjene for tilgjengelig webinnhold (WCAG) 2.2 og bruker dem som referanse nรฅr vi bygger funksjoner. Vi hevder ikke full samsvar med noe nivรฅ av WCAG โ tilgjengelighet er en kontinuerlig prosess og det er alltid mer arbeid รฅ gjรธre.",
@@ -1400,19 +1399,9 @@
"title": "Tilbakemelding",
"p1": "Hvis du stรธter pรฅ en tilgjengelighetsbarriere pรฅ {app}, vennligst gi oss beskjed ved รฅ opprette en sak pรฅ vรฅr {link}. Vi tar disse rapportene pรฅ alvor og vil gjรธre vรฅrt beste for รฅ lรธse dem.",
"link": "GitHub-repositorium"
- },
- "title": "tilgjengelighet",
- "footer_title": "a11y",
- "welcome": "Vi รธnsker at {app} skal kunne brukes av sรฅ mange mennesker som mulig."
+ }
},
"translation_status": {
- "table": {
- "file": "Fil",
- "status": "Status",
- "error": "Feil ved lasting av filliste.",
- "empty": "Ingen filer funnet",
- "file_link": "Rediger {file} ({lang}) pรฅ GitHub"
- },
"title": "oversettelsesstatus",
"generated_at": "Genereringsdato: {date}",
"welcome": "Hvis du er interessert i รฅ hjelpe oss med รฅ oversette {npmx} til ett av sprรฅkene listet nedenfor, har du kommet til rett sted! Denne automatisk oppdaterende siden lister alltid alt innholdet som kan trenge din hjelp akkurat nรฅ.",
@@ -1426,13 +1415,14 @@
"complete_text": "Denne oversettelsen er fullfรธrt, fantastisk jobb!",
"missing_text": "mangler",
"missing_keys": "Det er ingen manglende oversettelser | Manglende oversettelse | Manglende oversettelser",
- "progress_label": "Fremdriftsstatus for {locale}"
- },
- "action_bar": {
- "title": "handlingslinje",
- "selection": "0 valgt | 1 valgt | {count} valgt",
- "shortcut": "Trykk ยซ{key}ยป for รฅ fokusere handlinger",
- "button_close_aria_label": "Lukk handlingslinje"
+ "progress_label": "Fremdriftsstatus for {locale}",
+ "table": {
+ "file": "Fil",
+ "status": "Status",
+ "error": "Feil ved lasting av filliste.",
+ "empty": "Ingen filer funnet",
+ "file_link": "Rediger {file} ({lang}) pรฅ GitHub"
+ }
},
"vacations": {
"title": "pรฅ ferie",
@@ -1468,6 +1458,12 @@
}
}
},
+ "action_bar": {
+ "title": "handlingslinje",
+ "selection": "0 valgt | 1 valgt | {count} valgt",
+ "shortcut": "Trykk ยซ{key}ยป for รฅ fokusere handlinger",
+ "button_close_aria_label": "Lukk handlingslinje"
+ },
"logo_menu": {
"copy_svg": "Kopier logo som SVG",
"copied": "Kopiert!",
diff --git a/i18n/locales/ne-NP.json b/i18n/locales/ne-NP.json
index 58b5a3ffe9..0d16b488c4 100644
--- a/i18n/locales/ne-NP.json
+++ b/i18n/locales/ne-NP.json
@@ -531,12 +531,10 @@
"code": {
"files_label": "เคซเคพเคเคฒเคนเคฐเฅ",
"no_files": "เคฏเฅ เคกเคพเคเคฐเฅเคเฅเคเคฐเฅเคฎเคพ เคเฅเคจเฅ เคซเคพเคเคฒ เคเฅเคจ",
- "root": "root",
"lines": "{count} เคฒเคพเคเคจ",
"toggle_tree": "เคซเคพเคเคฒ เคเฅเคฐเฅ เคเคเคฒ",
"close_tree": "เคซเคพเคเคฒ เคเฅเคฐเฅ เคฌเคจเฅเคฆ",
"copy_link": "เคฒเคฟเคเฅเค เคเคชเฅ",
- "raw": "Raw",
"view_raw": "raw เคซเคพเคเคฒ เคนเฅเคฐเฅเคจเฅเคนเฅเคธเฅ",
"file_too_large": "เคชเฅเคฐเคฟเคญเฅเคฏเฅ เคเคฐเฅเคจ เคซเคพเคเคฒ เคงเฅเคฐเฅ เค เฅเคฒเฅ เค",
"file_size_warning": "syntax highlighting เคเคพ เคฒเคพเคเคฟ 500KB เคธเฅเคฎเคพ เคญเคจเฅเคฆเคพ {size} เค เฅเคฒเฅ เค",
diff --git a/i18n/locales/pl-PL.json b/i18n/locales/pl-PL.json
index 15d071ae0a..c2b59412df 100644
--- a/i18n/locales/pl-PL.json
+++ b/i18n/locales/pl-PL.json
@@ -769,12 +769,10 @@
"code": {
"files_label": "Pliki",
"no_files": "Brak plikรณw w tym katalogu",
- "root": "root",
"lines": "{count} wierszy",
"toggle_tree": "Przeลฤ
cz drzewo plikรณw",
"close_tree": "Zamknij drzewo plikรณw",
"copy_link": "Kopiuj link",
- "raw": "Surowe",
"view_raw": "Zobacz surowy plik",
"file_too_large": "Plik jest zbyt duลผy, aby wyลwietliฤ podglฤ
d",
"file_size_warning": "{size} przekracza limit 500KB dla podลwietlania skลadni",
diff --git a/i18n/locales/pt-BR.json b/i18n/locales/pt-BR.json
index f0fef7d598..ff5a248825 100644
--- a/i18n/locales/pt-BR.json
+++ b/i18n/locales/pt-BR.json
@@ -412,8 +412,6 @@
},
"page_title": "Histรณrico de versรตes",
"current_tags": "Tags atuais",
- "version_filter_placeholder": "Filtrar versรตes...",
- "version_filter_label": "Filtrar versรตes",
"no_match_filter": "Nenhuma versรฃo corresponde a {filter}"
},
"dependencies": {
@@ -780,12 +778,10 @@
"code": {
"files_label": "Arquivos",
"no_files": "Nenhum arquivo neste diretรณrio",
- "root": "raiz",
"lines": "{count} linhas",
"toggle_tree": "Alternar รกrvore de arquivos",
"close_tree": "Fechar รกrvore de arquivos",
"copy_link": "Copiar link",
- "raw": "Bruto",
"view_raw": "Ver arquivo bruto",
"file_too_large": "Arquivo muito grande para visualizar",
"file_size_warning": "{size} excede o limite de 500KB para destaque de sintaxe",
diff --git a/i18n/locales/ru-RU.json b/i18n/locales/ru-RU.json
index a52805c443..2693510b8b 100644
--- a/i18n/locales/ru-RU.json
+++ b/i18n/locales/ru-RU.json
@@ -441,8 +441,6 @@
},
"page_title": "ะััะพัะธั ะฒะตััะธะน",
"current_tags": "ะขะตะบััะธะต ัะตะณะธ",
- "version_filter_placeholder": "ะคะธะปััั ะฒะตััะธะนโฆ",
- "version_filter_label": "ะคะธะปััั ะฒะตััะธะน",
"no_match_filter": "ะะตั ะฒะตััะธะน ะฟะพ ัะธะปัััั ยซ{filter}ยป"
},
"dependencies": {
@@ -825,12 +823,10 @@
"code": {
"files_label": "ะคะฐะนะปั",
"no_files": "ะ ััะพะน ะดะธัะตะบัะพัะธะธ ะฝะตั ัะฐะนะปะพะฒ",
- "root": "ะบะพัะฝะตะฒะฐั ะดะธัะตะบัะพัะธั",
"lines": "{count} ัััะพะบ",
"toggle_tree": "ะะตัะตะบะปััะธัั ะดะตัะตะฒะพ ัะฐะนะปะพะฒ",
"close_tree": "ะะฐะบัััั ะดะตัะตะฒะพ ัะฐะนะปะพะฒ",
"copy_link": "ะกะบะพะฟะธัะพะฒะฐัั ัััะปะบั",
- "raw": "Raw",
"view_raw": "ะะพัะผะพััะตัั ะธัั
ะพะดะฝัะน ัะฐะนะป",
"file_too_large": "ะคะฐะนะป ัะปะธัะบะพะผ ะฑะพะปััะพะน ะดะปั ะฟัะตะดะฟัะพัะผะพััะฐ",
"file_size_warning": "{size} ะฟัะตะฒััะฐะตั ะปะธะผะธั ะฒ 500 ะะ ะดะปั ะฟะพะดัะฒะตัะบะธ ัะธะฝัะฐะบัะธัะฐ",
diff --git a/i18n/locales/sr-Latn-RS.json b/i18n/locales/sr-Latn-RS.json
new file mode 100644
index 0000000000..ee5f0cb0c3
--- /dev/null
+++ b/i18n/locales/sr-Latn-RS.json
@@ -0,0 +1,1517 @@
+{
+ "$schema": "../schema.json",
+ "seo": {
+ "home": {
+ "title": "npmx - Pretraลพivaฤ paketa za npm registar",
+ "description": "brzi, moderan pretraลพivaฤ za npm registar. Pretraลพujte, pregledajte i istraลพujte pakete kroz moderan interfejs."
+ }
+ },
+ "built_at": "napravljeno {0}",
+ "alt_logo": "npmx logo",
+ "tagline": "brz, moderan pretraลพivaฤ za npm registar",
+ "non_affiliation_disclaimer": "nije povezano sa npm, Inc.",
+ "trademark_disclaimer": "npm je registrovani zaลกtitni znak kompanije npm, Inc. Ovaj sajt nije povezan sa kompanijom npm, Inc.",
+ "footer": {
+ "about": "o nama",
+ "blog": "blog",
+ "docs": "dokumentacija",
+ "source": "izvor",
+ "social": "druลกtvene mreลพe",
+ "chat": "ฤaskanje",
+ "builders_chat": "builders",
+ "keyboard_shortcuts": "preฤice na tastaturi",
+ "brand": "brend"
+ },
+ "shortcuts": {
+ "section": {
+ "global": "Globalno",
+ "search": "Pretraga",
+ "package": "Paket"
+ },
+ "focus_search": "Fokusirajte pretragu",
+ "show_kbd_hints": "Istaknite preฤice na tastaturi",
+ "settings": "Otvorite podeลกavanja",
+ "compare": "Otvorite poreฤenje",
+ "compare_from_package": "Otvorite poreฤenje (sa trenutnim paketom)",
+ "navigate_results": "Kreฤite se kroz rezultate",
+ "go_to_result": "Idite na rezultat",
+ "open_code_view": "Otvorite pregled koda",
+ "open_docs": "Otvorite dokumentaciju",
+ "disable_shortcuts": "Moลพete iskljuฤiti preฤice na tastaturi u {settings}.",
+ "open_main": "Otvorite glavne informacije",
+ "open_diff": "Otvorite razlike verzija"
+ },
+ "search": {
+ "label": "Pretraลพite npm pakete",
+ "placeholder": "pretraลพite pakete...",
+ "button": "pretraลพite",
+ "searching": "Pretraลพujem...",
+ "found_packages": "Nije pronaฤen nijedan paket | Pronaฤen 1 paket | Pronaฤeno {count} paketa",
+ "found_packages_sorted": "Nema rezultata | Sortiranje prvog {count} rezultata | Sortiranje prvih {count} rezultata",
+ "updating": "(aลพuriranje...)",
+ "no_results": "Nema paketa za \"{query}\"",
+ "rate_limited": "Dostignuto npm ograniฤenje, pokuลกajte ponovo za trenutak",
+ "title": "pretraga",
+ "title_search": "pretraga: {search}",
+ "title_packages": "pretraลพite pakete",
+ "meta_description": "Rezultati pretrage za '{search}'",
+ "meta_description_packages": "Pretraลพite npm pakete",
+ "not_taken": "{name} nije zauzet",
+ "claim_prompt": "Zauzmite ovo ime paketa na npm-u",
+ "claim_button": "Zauzmite \"{name}\"",
+ "want_to_claim": "ลฝelite da zauzmete ovo ime paketa?",
+ "start_typing": "Poฤnite da kucate za pretragu paketa",
+ "algolia_disclaimer": "Omoguฤio Algolia",
+ "exact_match": "taฤno",
+ "suggestion": {
+ "user": "korisnik",
+ "org": "organizacija",
+ "view_user_packages": "Pogledajte pakete ovog korisnika",
+ "view_org_packages": "Pogledajte pakete ove organizacije"
+ },
+ "instant_search": "Trenutna pretraga",
+ "instant_search_on": "ukljuฤeno",
+ "instant_search_off": "iskljuฤeno",
+ "instant_search_turn_on": "ukljuฤite",
+ "instant_search_turn_off": "iskljuฤite",
+ "instant_search_advisory": "{label} {state} โ {action}"
+ },
+ "nav": {
+ "main_navigation": "Glavno",
+ "popular_packages": "Popularni paketi",
+ "settings": "podeลกavanja",
+ "compare": "poreฤenje",
+ "back": "nazad",
+ "menu": "Meni",
+ "mobile_menu": "Meni za navigaciju",
+ "open_menu": "Otvorite meni",
+ "links": "Linkovi",
+ "tap_to_search": "Dodirnite za pretragu"
+ },
+ "blog": {
+ "title": "Blog",
+ "heading": "blog",
+ "meta_description": "Uvidi i novosti iz npmx zajednice",
+ "author": {
+ "view_profile": "Pogledajte profil {name} na Bluesky-u"
+ },
+ "draft_badge": "Nacrt",
+ "draft_banner": "Ovo je neobjavljeni nacrt. Moลพe biti nepotpun ili sadrลพati netaฤnosti.",
+ "no_posts": "Nema pronaฤenih objava.",
+ "atproto": {
+ "view_on_bluesky": "Pogledajte na Bluesky-u",
+ "reply_on_bluesky": "Odgovorite na Bluesky-u",
+ "likes_on_bluesky": "Sviฤanja na Bluesky-u",
+ "like_or_reply_on_bluesky": "Lajkujte ovu objavu ili dodajte komentar na Bluesky-u",
+ "no_comments_yet": "Joลก nema komentara.",
+ "could_not_load_comments": "Nije moguฤe uฤitati komentare.",
+ "comments": "Komentari",
+ "loading_comments": "Uฤitavanje komentara...",
+ "updating": "Aลพuriranje...",
+ "reply_count": "{count} odgovor | {count} odgovora | {count} odgovora",
+ "like_count": "{count} sviฤanje | {count} sviฤanja | {count} sviฤanja",
+ "repost_count": "{count} prosleฤivanje | {count} prosleฤivanja | {count} prosleฤivanja",
+ "more_replies": "{count} joลก odgovor... | {count} joลก odgovora... | {count} joลก odgovora..."
+ }
+ },
+ "settings": {
+ "title": "podeลกavanja",
+ "tagline": "prilagodite svoje npmx iskustvo",
+ "meta_description": "Prilagodite svoje npmx.dev iskustvo pomoฤu podeลกavanja teme, jezika i prikaza.",
+ "sections": {
+ "appearance": "Izgled",
+ "display": "Prikaz",
+ "search": "Moguฤnosti pretrage",
+ "language": "Jezik",
+ "keyboard_shortcuts": "Preฤice na tastaturi"
+ },
+ "data_source": {
+ "label": "Izvor podataka",
+ "description": "Izaberite odakle npmx dobija podatke za pretragu. Stranice pojedinaฤnih paketa uvek koriste direktno npm registar.",
+ "npm": "npm registar",
+ "npm_description": "Dohvata pretragu, liste organizacija i korisnika direktno iz zvaniฤnog npm registra. Verodostojno, ali moลพe biti sporije.",
+ "algolia": "Algolia",
+ "algolia_description": "Koristi Algolia za brลพu pretragu, stranice organizacija i korisnika."
+ },
+ "instant_search": "Trenutna pretraga",
+ "instant_search_description": "Preusmerava na stranicu za pretragu i aลพurira rezultate dok kucate.",
+ "relative_dates": "Relativni datumi",
+ "include_types": "Ukljuฤite {'@'}types u instalaciju",
+ "include_types_description": "Dodajte {'@'}types paket u komande za instalaciju za pakete bez tipova",
+ "hide_platform_packages": "Sakrijte pakete specifiฤne za platformu u pretrazi",
+ "hide_platform_packages_description": "Sakrijte izvorne binarne pakete poput {'@'}esbuild/linux-x64 iz rezultata",
+ "enable_graph_pulse_loop": "Omoguฤite ponavljanje puls efekta na malom grafiku",
+ "enable_graph_pulse_loop_description": "Aktivirajte neprekidnu pulsirajuฤu animaciju na grafiku nedeljnih preuzimanja. Ova animacija moลพe ometati neke korisnike.",
+ "theme": "Tema",
+ "theme_light": "Svetla",
+ "theme_dark": "Tamna",
+ "theme_system": "Sistemska",
+ "language": "Jezik",
+ "help_translate": "Pomozite u prevodu npmx-a",
+ "translation_status": "Proverite globalni status prevoda",
+ "accent_colors": {
+ "label": "Akcent boje",
+ "sky": "Nebeska",
+ "coral": "Koral",
+ "amber": "ฤilibar",
+ "emerald": "Smaragd",
+ "violet": "Ljubiฤasta",
+ "magenta": "Magenta"
+ },
+ "clear_accent": "Obriลกite akcent boju",
+ "translation_progress": "Napredak prevoda",
+ "background_themes": {
+ "label": "Nijansa pozadine",
+ "neutral": "Neutralna",
+ "stone": "Kamena",
+ "zinc": "Cink",
+ "slate": "ล kriljac",
+ "black": "Crna"
+ },
+ "keyboard_shortcuts_enabled": "Omoguฤite preฤice na tastaturi",
+ "keyboard_shortcuts_enabled_description": "Preฤice na tastaturi mogu biti iskljuฤene ako su u sukobu sa drugim preฤicama pregledaฤa ili sistema"
+ },
+ "i18n": {
+ "missing_keys": "{count} nedostajuฤi prevod | {count} nedostajuฤa prevoda | {count} nedostajuฤih prevoda",
+ "copy_keys": "Kopirajte kljuฤeve",
+ "show_more_keys": "Prikaลพite joลก {count}...",
+ "contribute_hint": "Pomozite poboljลกanju ovog prevoda dodavanjem kljuฤeva koji nedostaju.",
+ "edit_on_github": "Uredite na GitHub-u",
+ "view_guide": "Vodiฤ za prevod"
+ },
+ "error": {
+ "401": "Neovlaลกฤeno",
+ "404": "Stranica nije pronaฤena",
+ "500": "Interna greลกka servera",
+ "503": "Usluga nedostupna",
+ "default": "Neลกto je poลกlo naopako"
+ },
+ "common": {
+ "loading": "Uฤitavanje...",
+ "loading_more": "Uฤitavanje joลก...",
+ "loading_packages": "Uฤitavanje paketa...",
+ "end_of_results": "Kraj rezultata",
+ "try_again": "Pokuลกajte ponovo",
+ "close": "Zatvorite",
+ "or": "ili",
+ "retry": "Ponovite",
+ "copy": "kopirajte",
+ "copied": "kopirano!",
+ "skip_link": "Preskoฤite na glavni sadrลพaj",
+ "warnings": "Upozorenja:",
+ "go_back_home": "Vratite se na poฤetnu",
+ "per_week": "/ nedeljno",
+ "vanity_downloads_hint": "Ukrasni broj: nema prikazanih paketa | Ukrasni broj: za prikazani paket | Ukrasni broj: Zbir {count} prikazanih paketa",
+ "sort": {
+ "name": "ime",
+ "role": "uloga",
+ "members": "ฤlanovi"
+ },
+ "scroll_to_top": "Vratite se na vrh",
+ "cancel": "Otkaลพite",
+ "save": "Saฤuvajte",
+ "edit": "Uredite",
+ "error": "Greลกka",
+ "view_on": {
+ "npm": "pogledajte na npm-u",
+ "github": "Pogledajte na GitHub-u",
+ "gitlab": "Pogledajte na GitLab-u",
+ "bitbucket": "Pogledajte na Bitbucket-u",
+ "codeberg": "Pogledajte na Codeberg-u",
+ "git_repo": "Pogledajte u Git repozitorijumu",
+ "forgejo": "Pogledajte na Forgejo-u",
+ "gitea": "Pogledajte na Gitea-i",
+ "gitee": "Pogledajte na Gitee-u",
+ "radicle": "Pogledajte na Radicle-u",
+ "sourcehut": "Pogledajte na SourceHut-u",
+ "tangled": "Pogledajte na Tangled-u"
+ },
+ "collapse": "Skupite",
+ "expand": "Proลกirite"
+ },
+ "profile": {
+ "display_name": "Ime za prikaz",
+ "description": "Opis",
+ "no_description": "Nema opisa",
+ "website": "Veb sajt",
+ "website_placeholder": "https://example.com",
+ "likes": "Sviฤanja",
+ "seo_title": "{handle} - npmx",
+ "seo_description": "npmx profil korisnika {handle}",
+ "not_found": "Profil nije pronaฤen",
+ "not_found_message": "Profil za {handle} nije moguฤe pronaฤi.",
+ "invite": {
+ "message": "Izgleda da joลก uvek ne koriste npmx. ลฝelite li da im kaลพete neลกto viลกe o tome?",
+ "share_button": "Podelite na Bluesky-u",
+ "compose_text": "Hej {'@'}{handle}! Da li ste veฤ pogledali npmx.dev? To je pretraลพivaฤ za npm registar koji je brz, moderan i otvorenog koda.\nhttps://npmx.dev"
+ }
+ },
+ "package": {
+ "not_found": "Paket nije pronaฤen",
+ "not_found_message": "Paket nije moguฤe pronaฤi.",
+ "no_description": "Nema opisa",
+ "verified_provenance": "Verifikovano poreklo",
+ "navigation": "Paket",
+ "copy_name": "Kopirajte ime paketa",
+ "deprecation": {
+ "package": "Ovaj paket je zastareo.",
+ "version": "Ova verzija je zastarela.",
+ "no_reason": "Nije naveden razlog"
+ },
+ "size_increase": {
+ "title_size": "Znaฤajno poveฤanje veliฤine od verzije v{version}",
+ "title_deps": "Znaฤajno poveฤanje broja zavisnosti od verzije v{version}",
+ "title_both": "Znaฤajno poveฤanje veliฤine i broja zavisnosti od verzije v{version}",
+ "size": "Veliฤina instalacije poveฤana za {percent} ({size} veฤa)",
+ "deps": "{count} viลกe zavisnosti"
+ },
+ "replacement": {
+ "title": "Moลพda vam ova zavisnost ne treba.",
+ "native": "Ovo se moลพe zameniti sa {replacement}, dostupno od Node verzije {nodeVersion}.",
+ "simple": "{community} je oznaฤio ovaj paket kao suviลกan, sa savetom: {replacement}.",
+ "documented": "{community} je oznaฤio ovaj paket kao onaj koji ima performantnije alternative.",
+ "none": "Ovaj paket je oznaฤen kao nepotreban, a njegova funkcionalnost je verovatno dostupna izvorno u svim okruลพenjima.",
+ "learn_more": "Saznajte viลกe",
+ "learn_more_above": "Saznajte viลกe iznad.",
+ "mdn": "MDN",
+ "community": "zajednica",
+ "consider_no_dep": "+ Razmislite bez zavisnosti?"
+ },
+ "stats": {
+ "license": "Licenca",
+ "deps": "Zavisnosti",
+ "install_size": "Veliฤina instalacije",
+ "vulns": "Ranjivosti",
+ "published": "Objavljen",
+ "published_tooltip": "Datum kada je {package}{'@'}{version} objavljen",
+ "view_dependency_graph": "Pogledajte grafikon zavisnosti",
+ "inspect_dependency_tree": "Pregledajte stablo zavisnosti",
+ "size_tooltip": {
+ "unpacked": "{size} raspakovana veliฤina (ovaj paket)",
+ "total": "{size} ukupna raspakovana veliฤina (ukljuฤujuฤi {count} zavisnost za linux-x64) | {size} ukupna raspakovana veliฤina (ukljuฤujuฤi {count} zavisnosti za linux-x64) | {size} ukupna raspakovana veliฤina (ukljuฤujuฤi svih {count} zavisnosti za linux-x64)"
+ }
+ },
+ "skills": {
+ "title": "Agent veลกtine",
+ "skills_available": "{count} veลกtina dostupna | {count} veลกtine dostupne | {count} veลกtina dostupno",
+ "compatible_with": "Kompatibilno sa {tool}",
+ "install": "Instalirajte",
+ "installation_method": "Metoda instalacije",
+ "learn_more": "Saznajte viลกe",
+ "available_skills": "Dostupne veลกtine",
+ "click_to_expand": "Kliknite za proลกirenje",
+ "no_description": "Nema opisa",
+ "file_counts": {
+ "scripts": "{count} skripta | {count} skripte | {count} skripti",
+ "refs": "{count} referenca | {count} reference | {count} referenci",
+ "assets": "{count} stavka | {count} stavke | {count} stavki"
+ },
+ "view_source": "Pogledajte izvorni kod",
+ "skills_cli": "skills CLI"
+ },
+ "links": {
+ "main": "glavno",
+ "repo": "repozitorijum",
+ "homepage": "poฤetna stranica",
+ "issues": "prijave problema",
+ "jsr": "jsr",
+ "code": "kod",
+ "docs": "dokumentacija",
+ "fund": "podrลพite",
+ "compare": "uporedite",
+ "compare_this_package": "uporedite ovaj paket"
+ },
+ "likes": {
+ "like": "Sviฤa mi se ovaj paket",
+ "unlike": "Uklonite sviฤanje"
+ },
+ "docs": {
+ "contents": "Sadrลพaj",
+ "default_not_available": "Dokumentacija nije dostupna za ovu verziju.",
+ "not_available": "Dokumentacija nije dostupna",
+ "not_available_detail": "Nismo uspeli da generiลกemo dokumentaciju za ovu verziju.",
+ "page_title": "API dokumentacija - npmx",
+ "page_title_name": "{name} dokumentacija - npmx",
+ "page_title_version": "{name} dokumentacija - npmx",
+ "og_title": "{name} - Dokumentacija",
+ "view_package": "Pogledajte paket"
+ },
+ "get_started": {
+ "title": "Poฤetak",
+ "pm_label": "Upravljaฤ paketima",
+ "copy_command": "Kopirajte komandu za instalaciju",
+ "copy_dev_command": "Kopirajte komandu za razvojnu instalaciju",
+ "dev_dependency_hint": "Obiฤno se instalira kao razvojna zavisnost",
+ "view_types": "Pogledajte {package}"
+ },
+ "create": {
+ "title": "Kreirajte novi projekat",
+ "copy_command": "Kopirajte komandu za kreiranje",
+ "view": "{packageName} ima istog odrลพavaoca. Kliknite za viลกe detalja."
+ },
+ "run": {
+ "title": "Pokrenite",
+ "locally": "Pokrenite lokalno"
+ },
+ "readme": {
+ "title": "Readme",
+ "no_readme": "Nema README datoteke.",
+ "toc_title": "Sadrลพaj",
+ "callout": {
+ "note": "Napomena",
+ "tip": "Savet",
+ "important": "Vaลพno",
+ "warning": "Upozorenje",
+ "caution": "Oprez"
+ },
+ "copy_as_markdown": "Kopirajte README kao Markdown"
+ },
+ "provenance_section": {
+ "title": "Poreklo",
+ "built_and_signed_on": "Izgraฤeno i potpisano na {provider}",
+ "view_build_summary": "Pogledajte saลพetak izgradnje",
+ "source_commit": "Izvorni commit",
+ "build_file": "Build datoteka",
+ "public_ledger": "Javni dnevnik",
+ "transparency_log_entry": "Zapis u transparentnom dnevniku",
+ "view_more_details": "Pogledajte viลกe detalja",
+ "error_loading": "Neuspeลกno uฤitavanje detalja o poreklu"
+ },
+ "security_downgrade": {
+ "title": "Smanjenje poverenja",
+ "description_to_none_provenance": "Ova verzija je objavljena bez {provenance}.",
+ "description_to_none_trustedPublisher": "Ova verzija je objavljena bez {trustedPublishing}.",
+ "description_to_provenance_trustedPublisher": "Ova verzija koristi {provenance}, ali ne i {trustedPublishing}.",
+ "fallback_install_provenance": "Komande za instalaciju su zakljuฤane na {version}, poslednju verziju sa poreklom.",
+ "fallback_install_trustedPublisher": "Komande za instalaciju su zakljuฤane na {version}, poslednju verziju sa poverljivim objavljivanjem.",
+ "provenance_link_text": "poreklo",
+ "trusted_publishing_link_text": "poverljivo objavljivanje"
+ },
+ "keywords_title": "Kljuฤne reฤi",
+ "compatibility": "Kompatibilnost",
+ "card": {
+ "publisher": "Izdavaฤ",
+ "published": "Objavljen",
+ "weekly_downloads": "Nedeljna preuzimanja",
+ "keywords": "Kljuฤne reฤi",
+ "license": "Licenca",
+ "select": "Izaberite paket",
+ "select_maximum": "Maksimalno {count} paketa moลพe biti izabrano"
+ },
+ "versions": {
+ "title": "Verzije",
+ "collapse": "Skupite {tag}",
+ "expand": "Proลกirite {tag}",
+ "collapse_other": "Skupite ostale verzije",
+ "expand_other": "Proลกirite ostale verzije",
+ "collapse_major": "Skupite glavnu verziju {major}",
+ "expand_major": "Proลกirite glavnu verziju {major}",
+ "other_versions": "Ostale verzije",
+ "more_tagged": "joลก {count} sa oznakom",
+ "all_covered": "Sve verzije su pokrivene gornjim oznakama",
+ "deprecated_title": "{version} (zastarelo)",
+ "view_all": "Pogledajte {count} verziju | Pogledajte {count} verzije | Pogledajte svih {count} verzija",
+ "view_all_versions": "Pogledajte sve verzije",
+ "distribution_title": "Semver grupa",
+ "distribution_modal_title": "Verzije",
+ "distribution_range_date_same_year": "od {from} do {to}, {endYear}",
+ "distribution_range_date_multiple_years": "od {from}, {startYear} do {to}, {endYear}",
+ "grouping_major": "Glavni",
+ "grouping_minor": "Sporedni",
+ "grouping_versions_title": "Verzije",
+ "grouping_versions_about": "O grupisanju verzija",
+ "grouping_versions_all": "Sve",
+ "grouping_versions_only_recent": "Samo nedavne",
+ "grouping_usage_title": "Koriลกฤenje",
+ "grouping_usage_about": "O grupisanju po koriลกฤenju",
+ "grouping_usage_all": "Sve",
+ "grouping_usage_most_used": "Najฤeลกฤe koriลกฤeno",
+ "recent_versions_only_tooltip": "Prikaลพite samo verzije objavljene u poslednjih godinu dana.",
+ "show_low_usage_tooltip": "Ukljuฤite grupe verzija sa manje od 1% ukupnih preuzimanja.",
+ "y_axis_label": "Preuzimanja",
+ "filter_placeholder": "Filtrirajte po semver-u (npr. ^3.0.0)",
+ "filter_invalid": "Neispravan semver opseg",
+ "filter_help": "Pomoฤ za filtriranje semver opsega",
+ "filter_tooltip": "Filtrirajte verzije koristeฤi {link}. Na primer, ^3.0.0 prikazuje sve 3.x verzije.",
+ "filter_tooltip_link": "semver opseg",
+ "no_matches": "Nijedna verzija ne odgovara ovom opsegu",
+ "copy_alt": {
+ "per_version_analysis": "Verzija {version} je preuzeta {downloads} puta",
+ "general_description": "Stubni grafikon koji prikazuje broj preuzimanja po verziji za {versions_count} {semver_grouping_mode} verzija paketa {package_name}, {date_range_label} od verzije {first_version} do verzije {last_version}. Najviลกe preuzimana verzija je {max_downloaded_version} sa {max_version_downloads} preuzimanja. {per_version_analysis}. {watermark}."
+ },
+ "page_title": "Istorija verzija",
+ "current_tags": "Trenutne oznake",
+ "no_match_filter": "Nijedna verzija ne odgovara filteru {filter}"
+ },
+ "dependencies": {
+ "title": "Zavisnost ({count}) | Zavisnosti ({count})",
+ "list_label": "Zavisnosti paketa",
+ "show_all": "prikaลพite {count} zavisnost | prikaลพite {count} zavisnosti | prikaลพite svih {count} zavisnosti",
+ "optional": "opciono",
+ "view_vulnerabilities": "Pogledajte ranljivosti",
+ "outdated_major": "{count} glavna verzija kasni (najnovija: {latest}) | {count} glavne verzije kasne (najnovija: {latest}) | {count} glavnih verzija kasni (najnovija: {latest})",
+ "outdated_minor": "{count} sporedna verzija kasni (najnovija: {latest}) | {count} sporedne verzije kasne (najnovija: {latest}) | {count} sporednih verzija kasni (najnovija: {latest})",
+ "outdated_patch": "Dostupno je aลพuriranje zakrpe (najnovija: {latest})",
+ "has_replacement": "Ova zavisnost ima predloลพene zamene",
+ "vulnerabilities_count": "{count} ranjivost | {count} ranjivosti | {count} ranjivosti"
+ },
+ "peer_dependencies": {
+ "title": "Peer zavisnost ({count}) | Peer zavisnosti ({count})",
+ "list_label": "Peer zavisnosti",
+ "show_all": "prikaลพite {count} peer zavisnost | prikaลพite {count} peer zavisnosti | prikaลพite svih {count} peer zavisnosti"
+ },
+ "optional_dependencies": {
+ "title": "Opciona zavisnost ({count}) | Opcione zavisnosti ({count})",
+ "list_label": "Opcione zavisnosti paketa",
+ "show_all": "prikaลพite {count} opcionu zavisnost | prikaลพite {count} opcione zavisnosti | prikaลพite svih {count} opcionih zavisnosti"
+ },
+ "maintainers": {
+ "title": "Odrลพavaoci",
+ "list_label": "Odrลพavaoci paketa",
+ "you": "(vi)",
+ "via": "preko {teams}",
+ "remove_owner": "Uklonite {name} kao vlasnika",
+ "username_to_add": "Korisniฤko ime za dodavanje kao vlasnika",
+ "username_placeholder": "korisniฤko ime...",
+ "add_button": "dodajte",
+ "cancel_add": "Otkaลพite dodavanje vlasnika",
+ "add_owner": "+ Dodajte vlasnika",
+ "show_more": "(prikaลพite joลก {count})",
+ "show_less": "(prikaลพite manje)",
+ "maintainer_template": "{avatar} {char126}{name}"
+ },
+ "trends": {
+ "chart_assistive_text": {
+ "keyboard_navigation_horizontal": "Koristite strelice levo i desno za kretanje kroz podatke.",
+ "keyboard_navigation_vertical": "Koristite strelice gore i dole za kretanje kroz podatke.",
+ "table_available": "Tabela podataka za ovaj grafikon je dostupna ispod.",
+ "table_caption": "Tabela podataka grafikona"
+ },
+ "granularity": "Granularnost",
+ "granularity_daily": "Dnevno",
+ "granularity_weekly": "Nedeljno",
+ "granularity_monthly": "Meseฤno",
+ "granularity_yearly": "Godiลกnje",
+ "start_date": "Poฤetak",
+ "end_date": "Kraj",
+ "loading": "Uฤitavanje...",
+ "date_range": "{start} do {end}",
+ "date_range_multiline": "{start}\ndo {end}",
+ "download_file": "Preuzmite {fileType}",
+ "toggle_annotator": "Ukljuฤite/iskljuฤite anotator",
+ "toggle_stack_mode": "Ukljuฤite/iskljuฤite slogovni naฤin",
+ "open_options": "Otvorite opcije",
+ "close_options": "Zatvorite opcije",
+ "legend_estimation": "Procena",
+ "no_data": "Nema dostupnih podataka",
+ "y_axis_label": "{granularity} {facet}",
+ "facet": "Aspekt",
+ "title": "Trendovi",
+ "contributors_skip": "Nije prikazano u saradnicima (nema GitHub repozitorijuma):",
+ "items": {
+ "downloads": "Preuzimanja",
+ "likes": "Sviฤanja",
+ "contributors": "Saradnici"
+ },
+ "data_correction": "Korekcija podataka",
+ "average_window": "Prozor proseka",
+ "smoothing": "Izglaฤivanje",
+ "prediction": "Predviฤanje",
+ "known_anomalies": "Poznate anomalije",
+ "known_anomalies_description": "Interpolacija preko poznatih skokova u preuzimanjima uzrokovanih botovima ili CI problemima.",
+ "known_anomalies_ranges": "Opsezi anomalija",
+ "known_anomalies_range": "Od {start} do {end}",
+ "known_anomalies_range_named": "{packageName}: od {start} do {end}",
+ "known_anomalies_none": "Nema poznatih anomalija za ovaj paket. | Nema poznatih anomalija za ove pakete.",
+ "known_anomalies_contribute": "Doprinesite podacima o anomalijama",
+ "apply_correction": "Primenite ispravku",
+ "copy_alt": {
+ "trend_none": "uglavnom ravno",
+ "trend_strong": "jak",
+ "trend_weak": "slab",
+ "trend_undefined": "nedefinisano (nedovoljno podataka)",
+ "button_label": "Kopirajte alt tekst",
+ "watermark": "Pri dnu, vodeni ลพig kaลพe \"./npmx a fast, modern browser for the npm registry\"",
+ "analysis": "{package_name} poฤinje od {start_value} i zavrลกava na {end_value}, pokazujuฤi {trend} trend sa nagibom od {downloads_slope} preuzimanja po vremenskom intervalu",
+ "estimation": "Konaฤna vrednost je procena zasnovana na delimiฤnim podacima za tekuฤi period.",
+ "estimations": "Konaฤne vrednosti su procene zasnovane na delimiฤnim podacima za tekuฤi period.",
+ "compare": "Uporedni linijski grafikon preuzimanja paketa za: {packages}.",
+ "single_package": "Linijski grafikon preuzimanja za paket {package}.",
+ "general_description": "Y osa predstavlja broj preuzimanja. X osa predstavlja opseg datuma, od {start_date} do {end_date}, sa vremenskim periodom {granularity}.{estimation_notice} {packages_analysis}. {watermark}.",
+ "facet_bar_general_description": "Horizontalni stubiฤasti grafikon za: {packages}, poreฤenje {facet} ({description}). {facet_analysis} {watermark}.",
+ "facet_bar_analysis": "{package_name} ima vrednost {value}."
+ }
+ },
+ "downloads": {
+ "title": "Nedeljna preuzimanja",
+ "community_distribution": "Pogledajte distribuciju prihvatanja u zajednici",
+ "subtitle": "Kroz sve verzije",
+ "sparkline_nav_hint": "Koristite โ โ"
+ },
+ "install_scripts": {
+ "title": "Skripte za instalaciju",
+ "script_label": "(skripta)",
+ "npx_packages": "{count} npx paket | {count} npx paketa | {count} npx paketa",
+ "currently": "trenutno {version}"
+ },
+ "playgrounds": {
+ "title": "Isprobajte",
+ "choose": "izaberite igraliลกte"
+ },
+ "metrics": {
+ "esm": "ES moduli podrลพani",
+ "cjs": "CommonJS podrลพan",
+ "no_esm": "ES moduli nisu podrลพani",
+ "wasm": "Ima WebAssembly",
+ "types_label": "Tipovi",
+ "types_included": "Ukljuฤeni tipovi",
+ "types_available": "Tipovi dostupni preko {package}",
+ "no_types": "Nema tipova"
+ },
+ "license": {
+ "view_spdx": "Pogledajte tekst licence na SPDX-u",
+ "none": "Nema"
+ },
+ "vulnerabilities": {
+ "tree_found": "{vulns} ranjivost u {packages}/{total} paketa | {vulns} ranjivosti u {packages}/{total} paketa | {vulns} ranjivosti u {packages}/{total} paketa",
+ "show_all_packages": "prikaลพite {count} pogoฤeni paket | prikaลพite svih {count} pogoฤenih paketa",
+ "path": "putanja",
+ "more": "+ {count} joลก",
+ "packages_failed": "{count} paket nije mogao biti proveren | {count} paketa nije moglo biti provereno",
+ "scan_failed": "Nije moguฤe skenirati ranjivosti",
+ "severity": {
+ "critical": "kritiฤna",
+ "high": "visoka",
+ "moderate": "umerena",
+ "low": "niska"
+ },
+ "fixed_in_title": "Popravljeno u verziji {version}"
+ },
+ "deprecated": {
+ "label": "Zastarelo",
+ "tree_found": "{count} zastarela zavisnost | {count} zastarele zavisnosti | {count} zastarelih zavisnosti",
+ "show_all": "prikaลพite {count} zastareli paket | prikaลพite svih {count} zastarelih paketa"
+ },
+ "access": {
+ "title": "Pristup timu",
+ "refresh": "Osveลพite pristup timu",
+ "list_label": "Lista pristupa timu",
+ "owner": "vlasnik",
+ "rw": "rw",
+ "ro": "ro",
+ "revoke_access": "Opozovite pristup za {name}",
+ "no_access": "Nije podeลกen pristup timu",
+ "select_team_label": "Izaberite tim",
+ "loading_teams": "Uฤitavanje timova...",
+ "select_team": "Izaberite tim",
+ "permission_label": "Nivo dozvole",
+ "permission": {
+ "read_only": "samo ฤitanje",
+ "read_write": "ฤitanje i pisanje"
+ },
+ "grant_button": "odobrite",
+ "cancel_grant": "Otkaลพite odobravanje pristupa",
+ "grant_access": "+ Odobrite pristup timu"
+ },
+ "list": {
+ "filter_label": "Filtrirajte pakete",
+ "filter_placeholder": "Filtrirajte pakete...",
+ "sort_label": "Sortirajte pakete",
+ "showing_count": "Prikazano {filtered} od {total} paketa"
+ },
+ "skeleton": {
+ "loading": "Uฤitavanje detalja paketa",
+ "maintainers": "Odrลพavaoci",
+ "keywords": "Kljuฤne reฤi",
+ "versions": "Verzije",
+ "dependencies": "Zavisnosti"
+ },
+ "sort": {
+ "downloads": "Najviลกe preuzimanja",
+ "published": "Najnovije objavljeni",
+ "name_asc": "Ime (A-Z)",
+ "name_desc": "Ime (Z-A)"
+ },
+ "size": {
+ "b": "{size} B",
+ "kb": "{size} kB",
+ "mb": "{size} MB"
+ },
+ "download": {
+ "button": "Preuzmite",
+ "tarball": "Preuzmite Tarball kao .tar.gz"
+ }
+ },
+ "connector": {
+ "modal": {
+ "title": "Lokalni konektor",
+ "connected": "Povezano",
+ "connected_as_user": "Povezano kao ~{user}",
+ "connected_hint": "Sada moลพete upravljati paketima i organizacijama putem veb interfejsa.",
+ "disconnect": "Prekinite vezu",
+ "run_hint": "Pokrenite konektor na svom raฤunaru da biste omoguฤili administratorske funkcije.",
+ "copy_command": "Kopirajte komandu",
+ "copied": "Kopirano",
+ "paste_token": "Zatim nalepite token ispod za povezivanje:",
+ "token_label": "Token",
+ "token_placeholder": "nalepite token ovde...",
+ "advanced": "Napredne opcije",
+ "port_label": "Port",
+ "warning": "UPOZORENJE",
+ "warning_text": "Ovo dozvoljava npmx-u pristup vaลกem npm CLI-ju. Povezujte se samo sa sajtovima kojima verujete.",
+ "connect": "Poveลพite se",
+ "connecting": "Povezivanje...",
+ "auto_open_url": "Automatski otvorite stranicu za autentifikaciju"
+ }
+ },
+ "operations": {
+ "queue": {
+ "title": "Red operacija",
+ "clear_all": "obriลกite sve",
+ "refresh": "Osveลพite operacije",
+ "empty": "Nema operacija u redu",
+ "empty_hint": "Dodajte operacije sa stranica paketa ili organizacija",
+ "active_label": "Aktivne operacije",
+ "otp_required": "OTP potreban",
+ "otp_prompt": "Unesite OTP za nastavak",
+ "otp_placeholder": "Unesite OTP kod...",
+ "otp_label": "Jednokratna lozinka",
+ "retry_otp": "Ponovite sa OTP-om",
+ "retry_web_auth": "Ponovite sa veb autentifikacijom",
+ "retrying": "Ponavljanje...",
+ "open_web_auth": "Otvorite veb link za autentifikaciju",
+ "approve_operation": "Odobrite operaciju",
+ "remove_operation": "Uklonite operaciju",
+ "approve_all": "Odobrite sve",
+ "execute": "Izvrลกite",
+ "executing": "Izvrลกavanje...",
+ "log": "Dnevnik",
+ "log_label": "Dnevnik zavrลกenih operacija",
+ "remove_from_log": "Uklonite iz dnevnika"
+ }
+ },
+ "org": {
+ "teams": {
+ "title": "Timovi",
+ "refresh": "Osveลพite timove",
+ "filter_label": "Filtrirajte timove",
+ "filter_placeholder": "Filtrirajte timove...",
+ "sort_by": "Sortirajte po",
+ "loading": "Uฤitavanje timova...",
+ "no_teams": "Nije pronaฤen nijedan tim",
+ "list_label": "Timovi organizacije",
+ "delete_team": "Obriลกite tim {name}",
+ "member_count": "{count} ฤlan | {count} ฤlana | {count} ฤlanova",
+ "members_of": "ฤlanovi tima {team}",
+ "no_members": "Nema ฤlanova",
+ "remove_user": "Uklonite {user} iz tima",
+ "username_to_add": "Korisniฤko ime za dodavanje u {team}",
+ "username_placeholder": "korisniฤko ime...",
+ "add_button": "dodajte",
+ "cancel_add_user": "Otkaลพite dodavanje korisnika",
+ "add_member": "+ Dodajte ฤlana",
+ "team_name_label": "Ime tima",
+ "team_name_placeholder": "ime-tima...",
+ "create_button": "napravite",
+ "no_match": "Nijedan tim ne odgovara \"{query}\"",
+ "cancel_create": "Otkaลพite kreiranje tima",
+ "create_team": "+ Kreirajte tim"
+ },
+ "members": {
+ "title": "ฤlanovi",
+ "refresh": "Osveลพite ฤlanove",
+ "filter_label": "Filtrirajte ฤlanove",
+ "filter_placeholder": "Filtrirajte ฤlanove...",
+ "filter_by_role": "Filtrirajte po ulozi",
+ "filter_by_team": "Filtrirajte po timu",
+ "all_teams": "svi timovi",
+ "sort_by": "Sortirajte po",
+ "loading": "Uฤitavanje ฤlanova...",
+ "no_members": "Nema pronaฤenih ฤlanova",
+ "list_label": "ฤlanovi organizacije",
+ "change_role_for": "Promenite ulogu za {name}",
+ "remove_from_org": "Uklonite {name} iz organizacije",
+ "view_team": "Pogledajte tim {team}",
+ "no_match": "Nijedan ฤlan ne odgovara vaลกim filterima",
+ "username_label": "Korisniฤko ime",
+ "username_placeholder": "korisniฤko ime...",
+ "role_label": "Uloga",
+ "role": {
+ "all": "sve",
+ "developer": "developer",
+ "admin": "admin",
+ "owner": "vlasnik"
+ },
+ "team_label": "Tim",
+ "no_team": "bez tima",
+ "add_button": "dodajte",
+ "cancel_add": "Otkaลพite dodavanje ฤlana",
+ "add_member": "+ Dodajte ฤlana"
+ },
+ "public_packages": "{count} javni paket | {count} javna paketa | {count} javnih paketa",
+ "page": {
+ "packages_title": "Paketi",
+ "members_tab": "ฤlanovi",
+ "teams_tab": "Timovi",
+ "no_packages": "Nema javnih paketa za",
+ "no_packages_hint": "Ova organizacija moลพda ne postoji ili nema javne pakete.",
+ "failed_to_load": "Neuspeลกno uฤitavanje paketa organizacije",
+ "no_match": "Nijedan paket ne odgovara \"{query}\"",
+ "not_found": "Organizacija nije pronaฤena",
+ "not_found_message": "Organizacija \"{'@'}{name}\" ne postoji na npm-u"
+ }
+ },
+ "user": {
+ "combobox": {
+ "add_to_org_hint": "(takoฤe ฤe dodati u organizaciju)",
+ "press_enter_to_add": "Pritisnite Enter za dodavanje {'@'}{username}",
+ "default_placeholder": "korisniฤko ime...",
+ "suggestions_label": "Predlozi korisnika"
+ },
+ "page": {
+ "packages_title": "Paketi",
+ "no_packages": "Nema javnih paketa za",
+ "no_packages_hint": "Ovaj korisnik moลพda ne postoji ili nema javne pakete.",
+ "failed_to_load": "Neuspeลกno uฤitavanje korisniฤkih paketa",
+ "no_match": "Nijedan paket ne odgovara \"{query}\"",
+ "filter_placeholder": "Filtrirajte {count} paket... | Filtrirajte {count} paketa... | Filtrirajte {count} paketa..."
+ },
+ "orgs_page": {
+ "title": "Organizacije",
+ "back_to_profile": "Nazad na profil",
+ "connect_required": "Poveลพite lokalni CLI da biste videli svoje organizacije.",
+ "connect_hint_prefix": "Pokrenite",
+ "connect_hint_suffix": "da biste poฤeli.",
+ "own_orgs_only": "Moลพete videti samo svoje organizacije.",
+ "view_your_orgs": "Pogledajte svoje organizacije",
+ "loading": "Uฤitavanje organizacija...",
+ "empty": "Nema pronaฤenih organizacija.",
+ "empty_hint": "Organizacije se otkrivaju iz vaลกih scoped paketa.",
+ "count": "{count} organizacija | {count} organizacije | {count} organizacija",
+ "packages_count": "{count} paket | {count} paketa | {count} paketa"
+ }
+ },
+ "claim": {
+ "modal": {
+ "title": "Zauzmite ime paketa",
+ "success": "Paket je zauzet!",
+ "success_detail": "{name}{'@'}0.0.0 je objavljen na npm-u.",
+ "success_hint": "Sada moลพete objavljivati nove verzije ovog paketa pomoฤu npm publish.",
+ "view_package": "Pogledajte paket",
+ "invalid_name": "Neispravno ime paketa:",
+ "available": "Ovo ime je dostupno!",
+ "taken": "Ovo ime je veฤ zauzeto.",
+ "missing_permission": "Nemate dozvolu da dodate paket u scope {'@'}{scope}.",
+ "similar_warning": "Postoje sliฤni paketi - npm moลพe odbiti ovo ime:",
+ "related": "Povezani paketi:",
+ "scope_warning_title": "Razmislite o koriลกฤenju scoped paketa",
+ "scope_warning_text": "Nazivi paketa bez scope-a su zajedniฤki resurs. Zauzmite ime samo ako zaista nameravate da objavite i odrลพavate paket. Za liฤne ili organizacione projekte, koristite scoped naziv, na primer {'@'}{username}/{name}.",
+ "connect_required": "Poveลพite se sa lokalnim konektorom da biste zauzeli ovo ime paketa.",
+ "connect_button": "Poveลพite se na konektor",
+ "publish_hint": "Ovo ฤe objaviti minimalni paket za rezervaciju mesta.",
+ "preview_json": "Pregledajte package.json",
+ "claim_button": "Zauzmite ime paketa",
+ "publishing": "Objavljivanje...",
+ "checking": "Provera dostupnosti...",
+ "failed_to_check": "Neuspeลกna provera dostupnosti imena",
+ "failed_to_claim": "Neuspeลกno zauzimanje paketa"
+ }
+ },
+ "code": {
+ "files_label": "Datoteke",
+ "no_files": "Nema datoteka u ovom direktorijumu",
+ "lines": "{count} linija | {count} linije | {count} linija",
+ "toggle_tree": "Ukljuฤite/iskljuฤite stablo datoteka",
+ "close_tree": "Zatvorite stablo datoteka",
+ "copy_link": "Kopirajte link",
+ "view_raw": "Pogledajte izvornu datoteku",
+ "file_too_large": "Datoteka je prevelika za pregled",
+ "file_size_warning": "{size} premaลกuje ograniฤenje od 500KB za isticanje sintakse",
+ "failed_to_load": "Neuspeลกno uฤitavanje",
+ "unavailable_hint": "Datoteka je moลพda prevelika ili nedostupna",
+ "version_required": "Verzija je potrebna za pregled koda",
+ "go_to_package": "Idite na paket",
+ "loading_tree": "Uฤitavanje stabla datoteka...",
+ "failed_to_load_tree": "Neuspeลกno uฤitavanje datoteka za ovu verziju paketa",
+ "back_to_package": "Nazad na paket",
+ "table": {
+ "name": "Ime",
+ "size": "Veliฤina"
+ },
+ "markdown_view_mode": {
+ "preview": "pregled",
+ "code": "kod"
+ },
+ "file_path": "Putanja datoteke",
+ "binary_file": "Binarna datoteka",
+ "binary_rendering_warning": "Tip datoteke \"{contentType}\" nije podrลพan za pregled."
+ },
+ "badges": {
+ "provenance": {
+ "verified": "verifikovano",
+ "verified_title": "Verifikovano poreklo",
+ "verified_via": "Verifikovano: objavljeno preko {provider}"
+ },
+ "jsr": {
+ "title": "takoฤe dostupno na JSR-u"
+ }
+ },
+ "filters": {
+ "title": "Filteri",
+ "search": "Pretraga",
+ "search_scope": "Opseg pretrage",
+ "search_placeholder_name": "Filtrirajte po imenu paketa...",
+ "search_placeholder_description": "Filtrirajte po opisu...",
+ "search_placeholder_keywords": "Filtrirajte po kljuฤnim reฤima...",
+ "search_placeholder_all": "Pretraลพite sve ili koristite name: desc: kw:",
+ "scope_name": "Ime",
+ "scope_name_description": "Pretraลพuje samo imena paketa",
+ "scope_description": "Opis",
+ "scope_description_description": "Pretraลพuje samo opise",
+ "scope_keywords": "Kljuฤne reฤi",
+ "scope_keywords_description": "Pretraลพuje samo kljuฤne reฤi",
+ "scope_all": "Sve",
+ "scope_all_description": "Pretraลพuje sva polja, podrลพava operatore name: desc: kw:",
+ "weekly_downloads": "Nedeljna preuzimanja",
+ "updated_within": "Aลพurirano u poslednjih",
+ "security": "Bezbednost",
+ "keywords": "Kljuฤne reฤi",
+ "more_keywords": "+{count} joลก",
+ "clear_all": "Obriลกite sve",
+ "remove_filter": "Uklonite filter {label}",
+ "chips": {
+ "search": "Pretraga",
+ "downloads": "Preuzimanja",
+ "keyword": "Kljuฤna reฤ",
+ "security": "Bezbednost",
+ "updated": "Aลพurirano"
+ },
+ "download_range": {
+ "any": "Bilo koje",
+ "lt100": "< 100",
+ "100_1k": "100 - 1K",
+ "1k_10k": "1K - 10K",
+ "10k_100k": "10K - 100K",
+ "gt100k": "> 100K"
+ },
+ "updated": {
+ "any": "Bilo kada",
+ "week": "Proลกle nedelje",
+ "month": "Proลกlog meseca",
+ "quarter": "Poslednja 3 meseca",
+ "year": "Proลกle godine"
+ },
+ "security_options": {
+ "all": "Svi paketi",
+ "secure": "Bez upozorenja",
+ "insecure": "Sa upozorenjima"
+ },
+ "view_selected": "Pogledajte izabrano",
+ "clear_selected_label": "Obriลกite izabrano",
+ "sort": {
+ "label": "Sortirajte pakete",
+ "toggle_direction": "Promenite smer sortiranja",
+ "ascending": "Rastuฤe",
+ "descending": "Opadajuฤe",
+ "relevance": "Relevantnost",
+ "downloads_week": "Preuzimanja/ned",
+ "downloads_day": "Preuzimanja/dan",
+ "downloads_month": "Preuzimanja/mes",
+ "downloads_year": "Preuzimanja/god",
+ "published": "Poslednje objavljivanje",
+ "name": "Ime"
+ },
+ "columns": {
+ "title": "Kolone",
+ "show": "Prikaลพite kolone",
+ "reset": "Vratite na podrazumevano",
+ "coming_soon": "Uskoro",
+ "name": "Ime",
+ "version": "Verzija",
+ "description": "Opis",
+ "downloads": "Preuzimanja/nedeljno",
+ "published": "Poslednje objavljeno",
+ "maintainers": "Odrลพavaoci",
+ "keywords": "Kljuฤne reฤi",
+ "security": "Bezbednost",
+ "selection": "Izaberite paket"
+ },
+ "view_mode": {
+ "label": "Reลพim prikaza",
+ "cards": "Kartice",
+ "table": "Tabela"
+ },
+ "pagination": {
+ "mode_label": "Reลพim paginacije",
+ "infinite": "Beskonaฤno",
+ "paginated": "Sa stranicama",
+ "items_per_page": "Stavki po stranici",
+ "per_page": "{count} / stranici",
+ "showing": "{range} od {total}",
+ "previous": "Prethodna stranica",
+ "next": "Sledeฤa stranica",
+ "nav_label": "Paginacija"
+ },
+ "count": {
+ "showing_filtered": "{filtered} od {count} paketa",
+ "showing_all": "{count} paket | {count} paketa",
+ "showing_paginated": "{pageSize} od {count} paketa"
+ },
+ "table": {
+ "security_warning": "Bezbednosno upozorenje",
+ "secure": "Bezbedno",
+ "no_packages": "Nema pronaฤenih paketa"
+ }
+ },
+ "about": {
+ "title": "O nama",
+ "heading": "o nama",
+ "meta_description": "npmx je brz, moderan pretraลพivaฤ za npm registar. Odliฤno korisniฤko i programersko iskustvo za istraลพivanje npm paketa.",
+ "what_we_are": {
+ "title": "ล ta smo",
+ "better_ux_dx": "odliฤno korisniฤko/programersko iskustvo",
+ "admin_ui": "admin interfejs",
+ "description": "npmx je {betterUxDx} za npm registar paketa i alat. Teลพimo da pruลพimo brz, moderan interfejs za istraลพivanje paketa, sa funkcijama poput tamnog reลพima, navigacije tastaturom, pregledom koda i vezama ka alternativnim registrima poput {jsr}.",
+ "admin_description": "Takoฤe ciljamo da pruลพimo odliฤan {adminUi} za upravljanje vaลกim paketima, timovima i organizacijama โ sve iz pretraลพivaฤa, pokretano vaลกim lokalnim npm CLI-jem."
+ },
+ "what_we_are_not": {
+ "title": "ล ta nismo",
+ "not_package_manager": "Nismo upravljaฤ paketima.",
+ "not_registry": "Nismo registar.",
+ "registry_description": "Ne hostujemo pakete. Samo smo brzi, moderni naฤin za njihovo pregledanje.",
+ "package_managers_exist": "{already} {people} {building} {really} {cool} {package} {managers}.",
+ "words": {
+ "already": "Veฤ postoje",
+ "people": "veฤ",
+ "building": "ljudi",
+ "really": "grade",
+ "cool": "stvarno",
+ "package": "cool",
+ "managers": "package managers"
+ }
+ },
+ "sponsors": {
+ "title": "Sponzori"
+ },
+ "oss_partners": {
+ "title": "OSS partneri"
+ },
+ "team": {
+ "title": "Tim",
+ "governance": "Upravljanje",
+ "role_steward": "steward",
+ "role_maintainer": "odrลพavalac",
+ "sponsor": "sponzor",
+ "sponsor_aria": "Sponzoriลกite {name} na GitHub-u"
+ },
+ "contributors": {
+ "title": "... i joลก {count} saradnik | ... i joลก {count} saradnika | ... i joลก {count} saradnika",
+ "description": "npmx je potpuno otvorenog koda, izgraฤen od strane neverovatne zajednice saradnika. Pridruลพite nam se i zajedno izgradimo iskustvo pregledanja npm-a koje smo oduvek ลพeleli.",
+ "loading": "Uฤitavanje saradnika...",
+ "error": "Neuspeลกno uฤitavanje saradnika",
+ "view_profile": "Pogledajte GitHub profil {name}"
+ },
+ "get_involved": {
+ "title": "Ukljuฤite se",
+ "contribute": {
+ "title": "Doprinesite",
+ "description": "Pomozite nam da izgradimo npm iskustvo koje svi ลพelimo.",
+ "cta": "Pogledajte na GitHub-u"
+ },
+ "community": {
+ "title": "Pridruลพite se zajednici",
+ "description": "ฤaskajte, postavljajte pitanja i delite ideje.",
+ "cta": "Pridruลพite se Discord-u"
+ },
+ "builders": {
+ "title": "Pomozite u izgradnji npmx-a",
+ "description": "Pridruลพite se graditeljima koji oblikuju buduฤnost npmx-a.",
+ "cta": "Pridruลพite se Builders Discord-u"
+ },
+ "follow": {
+ "title": "Ostanite u toku",
+ "description": "Saznajte najnovije o npmx-u.",
+ "cta": "Zapratite na Bluesky-u"
+ }
+ }
+ },
+ "account_menu": {
+ "connect": "poveลพite se",
+ "account": "Nalog",
+ "npm_cli": "npm CLI",
+ "atmosphere": "Atmosfera",
+ "npm_cli_desc": "Upravljajte paketima i organizacijama",
+ "atmosphere_desc": "Druลกtvene funkcije i identitet",
+ "connect_npm_cli": "Poveลพite se na npm CLI",
+ "connect_atmosphere": "Poveลพite se na Atmosferu",
+ "connecting": "Povezivanje...",
+ "ops": "{count} op | {count} ops"
+ },
+ "auth": {
+ "modal": {
+ "title": "Atmosfera",
+ "connected_as": "Povezani ste kao {'@'}{handle}",
+ "disconnect": "Prekinite vezu",
+ "connect_prompt": "Poveลพite se sa svojim nalogom na Atmosferi",
+ "handle_label": "Korisniฤko ime",
+ "handle_placeholder": "alice.npmx.social",
+ "connect": "Poveลพite se",
+ "create_account": "Napravite novi nalog",
+ "connect_bluesky": "Poveลพite se preko Bluesky-a",
+ "what_is_atmosphere": "ล ta je Atmosphere nalog?",
+ "atmosphere_explanation": "{npmx} koristi {atproto} za pokretanje mnogih svojih druลกtvenih funkcija, omoguฤavajuฤi korisnicima da poseduju svoje podatke i koriste jedan nalog za sve kompatibilne aplikacije. Kada napravite nalog, moลพete ga koristiti sa drugim aplikacijama poput {bluesky} i {tangled}.",
+ "default_input_error": "Unesite vaลพeฤe korisniฤko ime, DID ili puni PDS URL",
+ "profile": "Profil"
+ }
+ },
+ "header": {
+ "home": "npmx poฤetna",
+ "packages": "paketi",
+ "packages_dropdown": {
+ "title": "Vaลกi paketi",
+ "loading": "Uฤitavanje...",
+ "error": "Neuspeลกno uฤitavanje paketa",
+ "empty": "Nema pronaฤenih paketa",
+ "view_all": "Pogledajte sve"
+ },
+ "orgs": "organizacije",
+ "orgs_dropdown": {
+ "title": "Vaลกe organizacije",
+ "loading": "Uฤitavanje...",
+ "error": "Neuspeลกno uฤitavanje organizacija",
+ "empty": "Nema pronaฤenih organizacija",
+ "view_all": "Pogledajte sve"
+ },
+ "pr": "Otvorite GitHub pull request #{prNumber}"
+ },
+ "compare": {
+ "packages": {
+ "title": "uporedite pakete",
+ "tagline": "uporedite npm pakete jedan pored drugog da bi vam pomoglo da izaberete pravi.",
+ "meta_title": "Uporedite {packages} - npmx",
+ "meta_title_empty": "Uporedite pakete - npmx",
+ "meta_description": "Uporedni prikaz paketa {packages}",
+ "meta_description_empty": "Uporedite npm pakete jedan pored drugog",
+ "section_packages": "Paketi",
+ "section_facets": "Aspekti",
+ "section_comparison": "Poreฤenje",
+ "copy_as_markdown": "Kopirajte tabelu",
+ "loading": "Uฤitavanje podataka o paketu...",
+ "error": "Neuspeลกno uฤitavanje podataka o paketu. Pokuลกajte ponovo.",
+ "empty_title": "Izaberite pakete za poreฤenje",
+ "empty_description": "Pretraลพite i dodajte najmanje 2 paketa iznad da biste videli uporedni prikaz njihovih metrika.",
+ "table_view": "Tabela",
+ "charts_view": "Grafikoni",
+ "bar_chart_nav_hint": "Koristite โ โ",
+ "line_chart_nav_hint": "Koristite โ โ"
+ },
+ "selector": {
+ "search_label": "Pretraลพite pakete",
+ "search_first": "Pretraลพite paket...",
+ "search_add": "Dodajte joลก jedan paket...",
+ "searching": "Pretraลพivanje...",
+ "remove_package": "Uklonite {package}",
+ "packages_selected": "{count}/{max} paketa izabrano.",
+ "add_hint": "Dodajte najmanje 2 paketa za poreฤenje."
+ },
+ "no_dependency": {
+ "label": "(Bez zavisnosti)",
+ "typeahead_title": "ล ta bi James uradio?",
+ "typeahead_description": "Uporedite sa nekoriลกฤenjem zavisnosti! e18e odobreno.",
+ "tooltip_title": "Moลพda vam zavisnost ne treba",
+ "tooltip_description": "Uporedite sa nekoriลกฤenjem zavisnosti! {link} odrลพava listu paketa koji se mogu zameniti izvornim API-jima ili jednostavnijim alternativama.",
+ "e18e_community": "e18e zajednica",
+ "add_column": "Dodajte kolonu \"bez zavisnosti\" u poreฤenje"
+ },
+ "facets": {
+ "all": "sve",
+ "none": "niลกta",
+ "select_all_category_facets": "Izaberite sve aspekte kategorije {category}",
+ "deselect_all_category_facets": "Poniลกtite izbor svih aspekata kategorije {category}",
+ "selected_all_category_facets": "Izabrani svi aspekti kategorije {category}",
+ "deselected_all_category_facets": "Poniลกten izbor svih aspekata kategorije {category}",
+ "coming_soon": "Uskoro",
+ "select_all": "Izaberite sve aspekte",
+ "deselect_all": "Poniลกtite izbor svih aspekata",
+ "binary_only_tooltip": "Ovaj paket izlaลพe binarne datoteke i nema izvoze",
+ "categories": {
+ "performance": "Performanse",
+ "health": "Zdravlje",
+ "compatibility": "Kompatibilnost",
+ "security": "Bezbednost i usaglaลกenost"
+ },
+ "items": {
+ "packageSize": {
+ "label": "Veliฤina paketa",
+ "description": "Veliฤina samog paketa (raspakovano)"
+ },
+ "installSize": {
+ "label": "Veliฤina instalacije",
+ "description": "Ukupna veliฤina instalacije ukljuฤujuฤi sve zavisnosti"
+ },
+ "dependencies": {
+ "label": "Direktne zavisnosti",
+ "description": "Broj direktnih zavisnosti"
+ },
+ "totalDependencies": {
+ "label": "Ukupno zavisnosti",
+ "description": "Ukupan broj zavisnosti ukljuฤujuฤi prenosive"
+ },
+ "downloads": {
+ "label": "Preuzimanja/nedeljno",
+ "description": "Nedeljni broj preuzimanja"
+ },
+ "totalLikes": {
+ "label": "Sviฤanja",
+ "description": "Broj sviฤanja"
+ },
+ "lastUpdated": {
+ "label": "Objavljen",
+ "description": "Kada je ova verzija objavljena"
+ },
+ "deprecated": {
+ "label": "Zastareo?",
+ "description": "Da li je paket zastareo"
+ },
+ "engines": {
+ "label": "Okruลพenja",
+ "description": "Zahtevi za verziju Node.js-a"
+ },
+ "types": {
+ "label": "Tipovi",
+ "description": "TypeScript definicije tipova"
+ },
+ "moduleFormat": {
+ "label": "Format modula",
+ "description": "ESM/CJS podrลกka"
+ },
+ "license": {
+ "label": "Licenca",
+ "description": "Licenca paketa"
+ },
+ "vulnerabilities": {
+ "label": "Ranjivosti",
+ "description": "Poznate bezbednosne ranjivosti"
+ }
+ },
+ "values": {
+ "any": "Bilo koje",
+ "none": "Nema",
+ "unknown": "Nepoznato",
+ "deprecated": "Zastarelo",
+ "not_deprecated": "Ne",
+ "types_included": "Ukljuฤeni",
+ "types_none": "Nema",
+ "vulnerabilities_summary": "{count} ({critical}C/{high}H)",
+ "up_to_you": "Na vama je!"
+ },
+ "trends": {
+ "title": "Uporedite trendove"
+ }
+ },
+ "file_changes": "Izmene datoteka",
+ "files_count": "{count} datoteka | {count} datoteke | {count} datoteka",
+ "lines_hidden": "{count} linija sakrivena | {count} linije sakrivene | {count} linija sakriveno",
+ "file_too_large": "Datoteka je prevelika za poreฤenje",
+ "file_size_warning": "{size} premaลกuje ograniฤenje od 250KB za poreฤenje",
+ "compare_versions": "razlika",
+ "compare_versions_title": "Uporedite sa najnovijom verzijom",
+ "comparing_versions_label": "Poreฤenje verzija...",
+ "version_back_to_package": "Nazad na paket",
+ "version_error_message": "Neuspelo poreฤenje verzija.",
+ "version_invalid_url_format": {
+ "hint": "Neispravan URL za poreฤenje. Koristite format: {0}",
+ "from_version": "od",
+ "to_version": "do"
+ },
+ "version_selector_title": "Uporedite sa verzijom",
+ "summary": "Saลพetak",
+ "deps_count": "{count} zavisnost | {count} zavisnosti | {count} zavisnosti",
+ "dependencies": "Zavisnosti",
+ "dev_dependencies": "Razvojne zavisnosti",
+ "peer_dependencies": "Peer zavisnosti",
+ "optional_dependencies": "Opcione zavisnosti",
+ "no_dependency_changes": "Nema promena u zavisnostima",
+ "file_filter_option": {
+ "all": "Sve ({count})",
+ "added": "Dodato ({count})",
+ "removed": "Uklonjeno ({count})",
+ "modified": "Izmenjeno ({count})"
+ },
+ "search_files_placeholder": "Pretraลพite datoteke...",
+ "no_files_all": "Nema datoteka",
+ "no_files_search": "Nema datoteka koje odgovaraju \"{query}\"",
+ "no_files_filtered": "Nema {filter} datoteka",
+ "filter": {
+ "added": "dodato",
+ "removed": "uklonjeno",
+ "modified": "izmenjeno"
+ },
+ "files_button": "Datoteke",
+ "select_file_prompt": "Izaberite datoteku sa boฤne trake da biste videli njene razlike",
+ "close_files_panel": "Zatvorite panel sa datotekama",
+ "filter_files_label": "Filtrirajte datoteke po tipu izmene",
+ "change_ratio": "Odnos promene",
+ "char_edits": "Izmene znakova",
+ "diff_distance": "Udaljenost razlike",
+ "loading_diff": "Uฤitavanje razlike...",
+ "loading_diff_error": "Neuspeลกno uฤitavanje razlike",
+ "merge_modified_lines": "Spojite izmenjene linije",
+ "no_content_changes": "Nema otkrivenih promena u sadrลพaju",
+ "options": "Opcije",
+ "view_file": "Pogledajte datoteku",
+ "view_in_code_browser": "Pogledajte u pregledaฤu koda",
+ "word_wrap": "Prelamanje reฤi"
+ },
+ "pds": {
+ "title": "npmx.social",
+ "meta_description": "Zvaniฤni AT Protocol Personal Data Server (PDS) za npmx zajednicu.",
+ "join": {
+ "title": "Pridruลพite se zajednici",
+ "description": "Bilo da kreirate svoj prvi nalog na atmosferi ili migrirate postojeฤi, pripadate ovde. Moลพete migrirati svoj trenutni nalog bez gubitka korisniฤkog imena, objava ili pratilaca.",
+ "migrate": "Migrirajte sa PDS MOOver-om"
+ },
+ "server": {
+ "title": "Detalji servera",
+ "location_label": "Lokacija:",
+ "location_value": "Nuremberg, Nemaฤka",
+ "infrastructure_label": "Infrastruktura:",
+ "infrastructure_value": "Hostovan na Hetzner-u",
+ "privacy_label": "Privatnost:",
+ "privacy_value": "Podleลพe strogim zakonima EU o zaลกtiti podataka",
+ "learn_more": "Saznajte kako npmx koristi Atmosferu"
+ },
+ "community": {
+ "title": "Ko je ovde",
+ "description": "Neki od {count} naloga koji veฤ zovu npmx.social domom:",
+ "loading": "Uฤitavanje PDS zajednice...",
+ "error": "Neuspeลกno uฤitavanje PDS zajednice.",
+ "empty": "Nema prikazanih ฤlanova zajednice.",
+ "view_profile": "Pogledajte profil {handle}",
+ "new_accounts": "...plus joลก {count} koji su novi na atmosferi"
+ }
+ },
+ "privacy_policy": {
+ "title": "politika privatnosti",
+ "last_updated": "Poslednje aลพuriranje: {date}",
+ "welcome": "Dobrodoลกli na {app}. Posveฤeni smo zaลกtiti vaลกe privatnosti. Ova politika objaลกnjava koje podatke prikupljamo, kako ih koristimo i vaลกa prava u vezi sa vaลกim informacijama.",
+ "cookies": {
+ "what_are": {
+ "title": "ล ta su kolaฤiฤi?",
+ "p1": "Kolaฤiฤi su male tekstualne datoteke koje se ฤuvaju na vaลกem ureฤaju kada posetite veb sajt. Njihova svrha je da poboljลกaju vaลกe iskustvo pretraลพivanja pamฤenjem odreฤenih preferenci i podeลกavanja."
+ },
+ "types": {
+ "title": "Koje kolaฤiฤe koristimo?",
+ "p1": "Koristimo {bold} iskljuฤivo u svrhe koje su neophodne za funkcionalnost sajta. Ne koristimo kolaฤiฤe treฤih strana ili reklamne kolaฤiฤe.",
+ "bold": "esencijalne tehniฤke kolaฤiฤe",
+ "li1": "{li11}{separator} {li12}",
+ "li2": "{li21}{separator} {li22}",
+ "separator": ":",
+ "cookie_vdpl": "__vdpl",
+ "cookie_vdpl_desc": "Ovaj kolaฤiฤ koristi naลก hosting provajder (Vercel) radi zaลกtite od neslaganja izmeฤu verzija. Osigurava da preuzimate resurse iz ispravne verzije deploy-a ako se tokom pregledanja objavi novo aลพuriranje. Ne koristi se za vaลกe praฤenje.",
+ "cookie_h3": "h3",
+ "cookie_h3_desc": "Ovo je naลก bezbednosni sesijski kolaฤiฤ. ฤuva OAuth pristupni token kada poveลพete svoj nalog na Atmosferi. Neophodan je za odrลพavanje vaลกe autentifikovane sesije."
+ },
+ "local_storage": {
+ "title": "Lokalno skladiลกte",
+ "p1": "Pored kolaฤiฤa sesije, koristimo {bold} vaลกeg pregledaฤa kako bismo saฤuvali vaลกa podeลกavanja prikaza. To nam omoguฤava da zapamtimo temu (svetlo/tamno) i neka druga {settings} koja ste izabrali, tako da ne morate da ih ponovo podeลกavate pri svakoj poseti.",
+ "bold": "Lokalno skladiลกte",
+ "p2": "Ova informacija je iskljuฤivo funkcionalna, ฤuva se samo na vaลกem ureฤaju i {bold2}. Koristimo je iskljuฤivo da poboljลกamo vaลกe iskustvo na naลกem veb sajtu.",
+ "bold2": "ne sadrลพi liฤne podatke niti se koristi za praฤenje",
+ "settings": "podeลกavanja"
+ },
+ "management": {
+ "title": "Upravljanje kolaฤiฤima",
+ "p1": "Moลพete podesiti svoj pretraลพivaฤ da prihvati, odbije ili obriลกe kolaฤiฤe prema vaลกim ลพeljama. Meฤutim, imajte na umu da {bold}.",
+ "bold": "odbijanje esencijalnih kolaฤiฤa moลพe spreฤiti potpuni pristup aplikaciji",
+ "p2": "Ispod su linkovi sa uputstvima za upravljanje kolaฤiฤima u najฤeลกฤe koriลกฤenim pretraลพivaฤima:",
+ "chrome": "Google Chrome (otvara se u novom prozoru)",
+ "firefox": "Mozilla Firefox (otvara se u novom prozoru)",
+ "edge": "Microsoft Edge (otvara se u novom prozoru)"
+ }
+ },
+ "analytics": {
+ "title": "Analitika",
+ "p1": "Koristimo {bold} da bismo razumeli kako posetioci koriste naลก veb sajt. To nam pomaลพe da poboljลกamo korisniฤko iskustvo i identifikujemo probleme.",
+ "bold": "Vercel Web Analytics",
+ "p2": "Vercel Analytics je dizajniran sa privatnoลกฤu na umu:",
+ "li1": "Ne koristi kolaฤiฤe",
+ "li2": "Ne prikuplja liฤne identifikatore",
+ "li3": "Ne prati korisnike na razliฤitim veb sajtovima",
+ "li4": "Svi podaci su agregirani i anonimizovani",
+ "p3": "Jedine informacije koje se prikupljaju ukljuฤuju: URL-ove stranica, referer, zemlju/region, vrstu ureฤaja, pregledaฤ i operativni sistem. Ovi podaci se ne mogu koristiti za identifikaciju pojedinaฤnih korisnika."
+ },
+ "authenticated": {
+ "title": "Autentifikovani korisnici",
+ "p1": "Kada poveลพete svoj {bold} nalog sa npmx-om, ฤuvamo vaลก OAuth pristupni token u bezbednom, HTTP-only kolaฤiฤu sesije. Ovaj token se koristi iskljuฤivo za autentifikaciju zahteva u vaลกe ime.",
+ "bold": "Atmosfera",
+ "p2": "Ne ฤuvamo vaลกe akreditive i ne pristupamo nijednim podacima izvan onoga ลกto je neophodno za pruลพanje funkcija koje koristite. Moลพete prekinuti vezu sa svojim nalogom u bilo kom trenutku sa stranice {settings}.",
+ "settings": "podeลกavanja"
+ },
+ "data_retention": {
+ "title": "ฤuvanje podataka",
+ "p1": "Kolaฤiฤi sesije se automatski briลกu kada zatvorite pregledaฤ ili nakon perioda neaktivnosti. Podeลกavanja u lokalnom skladiลกtu ostaju na vaลกem ureฤaju dok ne obriลกete podatke pregledaฤa. Analitiฤki podaci se ฤuvaju u agregiranom obliku i ne mogu se povezati sa pojedinaฤnim korisnicima."
+ },
+ "your_rights": {
+ "title": "Vaลกa prava",
+ "p1": "Imate pravo na:",
+ "li1": "Pristup informacijama o tome koje podatke prikupljamo",
+ "li2": "Brisanje vaลกeg lokalnog skladiลกta i kolaฤiฤa u bilo kom trenutku",
+ "li3": "Prekid vaลกe autentifikovane sesije",
+ "li4": "Zahtev za informacijama o naลกim praksama u vezi sa podacima",
+ "p2": "Poลกto ne prikupljamo liฤne podatke, obiฤno nema liฤnih informacija za brisanje ili izvoz."
+ },
+ "contact": {
+ "title": "Kontaktirajte nas",
+ "p1": "Za sva pitanja ili nedoumice u vezi sa ovom politikom privatnosti, moลพete nas kontaktirati otvaranjem issue-a na naลกem {link}.",
+ "link": "GitHub repozitorijumu"
+ },
+ "changes": {
+ "title": "Izmene ove politike",
+ "p1": "Moลพemo povremeno aลพurirati ovu politiku privatnosti. Sve izmene biฤe objavljene na ovoj stranici sa aลพuriranim datumom revizije."
+ }
+ },
+ "a11y": {
+ "title": "pristupaฤnost",
+ "footer_title": "a11y",
+ "welcome": "ลฝelimo da {app} bude upotrebljiv ลกto veฤem broju ljudi.",
+ "approach": {
+ "title": "Naลก pristup",
+ "p1": "Trudimo se da pratimo Smernice za pristupaฤnost veb sadrลพaja (WCAG) 2.2 i koristimo ih kao referencu prilikom izrade funkcija. Ne tvrdimo da smo u potpunosti usklaฤeni ni sa jednim nivoom WCAG-a โ pristupaฤnost je stalan proces i uvek ima joลก posla.",
+ "p2": "Ovaj sajt je {about}. Poboljลกanja pristupaฤnosti se uvode postepeno kao deo naลกeg redovnog razvoja.",
+ "about_link": "projekat otvorenog koda kojim upravlja zajednica"
+ },
+ "measures": {
+ "title": "ล ta radimo",
+ "p1": "Neke od stvari kojima teลพimo na celom sajtu:",
+ "li1": "Koriลกฤenje semantiฤkog HTML-a i ARIA atributa gde je to prikladno.",
+ "li2": "Koriลกฤenje relativnih veliฤina teksta tako da ih moลพete prilagoditi u svom pregledaฤu.",
+ "li3": "Podrลกka za navigaciju tastaturom kroz ceo interfejs.",
+ "li4": "Poลกtovanje prefers-reduced-motion i prefers-color-scheme medijskih upita.",
+ "li5": "Dizajniranje sa dovoljnim kontrastom boja na umu.",
+ "li6": "Osiguravanje da je suลกtinski sadrลพaj dostupan bez JavaScript-a, iako neke interaktivne funkcije zahtevaju njegovo koriลกฤenje."
+ },
+ "limitations": {
+ "title": "Poznata ograniฤenja",
+ "p1": "Neki delovi sajta โ posebno sadrลพaj treฤih strana poput README datoteka paketa โ moลพda ne ispunjavaju standarde pristupaฤnosti. Radimo na poboljลกanju ovih oblasti tokom vremena."
+ },
+ "contact": {
+ "title": "Povratne informacije",
+ "p1": "Ako naiฤete na prepreku u pristupaฤnosti na {app}, obavestite nas otvaranjem prijave problema u naลกem {link}. Ove prijave shvatamo ozbiljno i potrudiฤemo se da ih reลกimo.",
+ "link": "GitHub repozitorijumu"
+ }
+ },
+ "translation_status": {
+ "title": "status prevoda",
+ "generated_at": "Datum generisanja: {date}",
+ "welcome": "Ako ste zainteresovani da nam pomognete da prevedemo {npmx} na neki od jezika navedenih ispod, na pravom ste mestu! Ova stranica koja se automatski aลพurira uvek prikazuje sav sadrลพaj kome je trenutno potrebna vaลกa pomoฤ.",
+ "p1": "Koristimo {lang} kao podrazumevani jezik, sa ukupno {count}. Ako ลพelite da pomognete u dodavanju prevoda, pronaฤite jezik u {bylang} i proลกirite detalje.",
+ "p1_lang": "ameriฤki engleski (en-US)",
+ "p1_count": "{count} poruka | {count} poruke | {count} poruka",
+ "p2": "Pre nego ลกto poฤnete, proฤitajte naลก {guide} da biste nauฤili o naลกem procesu prevoฤenja i kako moลพete da se ukljuฤite.",
+ "guide": "vodiฤ za lokalizaciju (i18n)",
+ "by_locale": "Napredak prevoda po lokalitetu",
+ "by_file": "Napredak prevoda po datoteci",
+ "complete_text": "Ovaj prevod je kompletan, neverovatan posao!",
+ "missing_text": "nedostaje",
+ "missing_keys": "{count} nedostajuฤi prevod | {count} nedostajuฤa prevoda | {count} nedostajuฤih prevoda",
+ "progress_label": "Status napretka za {locale}",
+ "table": {
+ "file": "Datoteka",
+ "status": "Status",
+ "error": "Greลกka pri uฤitavanju liste datoteka.",
+ "empty": "Nema pronaฤenih datoteka",
+ "file_link": "Uredite {file} ({lang}) na GitHub-u"
+ }
+ },
+ "vacations": {
+ "title": "na odmoru",
+ "meta_description": "npmx tim se punio energijom. Discord je ponovo otvoren nakon nedelju dana.",
+ "heading": "punjenje energijom",
+ "subtitle": "gradili smo npmx tempom koji je koลกtao {some} od nas sna. nismo ลพeleli da to postane norma! zato smo uzeli nedelju dana odmora. zajedno.",
+ "illustration_alt": "jedan red udobnih ikonica",
+ "poke_log": "Dodirnite logorsku vatru",
+ "what": {
+ "title": "ลกta se dogodilo",
+ "p1": "discord je bio zatvoren {dates}.",
+ "dates": "14 โ 21. februar",
+ "p2": "svi pozivni linkovi su nestali i kanali su zakljuฤani โ osim {garden}, koji je ostao otvoren za one koji su ลพeleli da se i dalje druลพe.",
+ "garden": "#garden"
+ },
+ "meantime": {
+ "title": "u meฤuvremenu",
+ "p1": "{site} i {repo} su ostali otvoreni โ ljudi su i dalje ulazili, prijavljivali probleme, otvarali po koji PR, ali uglavnom su svi provodili vreme negde blizu udobnog kamina.",
+ "repo_link": "repozitorijum"
+ },
+ "return": {
+ "title": "vratili smo se!",
+ "p1": "vratili smo se napunjeni energijom i spremni za poslednji pritisak do 3. marta. {social} za novosti.",
+ "social_link": "zapratite nas na Bluesky-u"
+ },
+ "stats": {
+ "contributors": "Saradnici",
+ "commits": "Commit-ovi",
+ "pr": "Spojeni PR-ovi",
+ "subtitle": {
+ "some": "neki",
+ "all": "svi"
+ }
+ }
+ },
+ "action_bar": {
+ "title": "traka akcija",
+ "selection": "{count} izabran | {count} izabrana | {count} izabrano",
+ "shortcut": "Pritisnite \"{key}\" da fokusirate akcije",
+ "button_close_aria_label": "Zatvorite traku akcija"
+ },
+ "logo_menu": {
+ "copy_svg": "Kopirajte logo kao SVG",
+ "copied": "Kopirano!",
+ "browse_brand": "Pregledajte brand kit"
+ },
+ "brand": {
+ "title": "Brend",
+ "heading": "brend",
+ "meta_description": "Smernice za npmx brend, logotipi, boje i tipografija za upotrebu u ลกtampi i medijima.",
+ "intro": "Resursi i smernice za koriลกฤenje npmx brenda u vaลกim projektima, ฤlancima i medijima.",
+ "logos": {
+ "title": "logotipi",
+ "description": "Preuzmite npmx logotipe u SVG i PNG formatima. Koristite odgovarajuฤu varijantu za svoju pozadinu.",
+ "wordmark": "PUNI ZNAK",
+ "wordmark_alt": "npmx puni znak logotipa sa plavom kosom crtom na tamnoj pozadini",
+ "wordmark_light_alt": "npmx puni znak logotipa sa akcentovanom kosom crtom na svetloj pozadini",
+ "mark": "ZNAK",
+ "mark_alt": "npmx znak logotipa sa taฤkom i kosom crtom na tamnoj pozadini",
+ "mark_light_alt": "npmx znak logotipa sa taฤkom i kosom crtom na svetloj pozadini",
+ "on_dark": "na tamnom",
+ "on_light": "na svetlom",
+ "download_svg": "SVG",
+ "download_png": "PNG",
+ "download_svg_aria": "Preuzmite {name} kao SVG",
+ "download_png_aria": "Preuzmite {name} kao PNG"
+ },
+ "customize": {
+ "title": "prilagodite svoj logo",
+ "description": "Pregledajte npmx logo sa svojom akcent bojom i pozadinom. Pregled odraลพava vaลกa trenutna podeลกavanja โ izaberite boju, promenite pozadinu i preuzmite.",
+ "accent_label": "akcent",
+ "bg_label": "pozadina",
+ "download_svg_aria": "Preuzmite prilagoฤeni logo kao SVG",
+ "download_png_aria": "Preuzmite prilagoฤeni logo kao PNG"
+ },
+ "typography": {
+ "title": "tipografija",
+ "description": "npmx koristi Geist familiju fontova od Vercel-a i za interfejs tekst i za kod.",
+ "sans": "Geist Sans",
+ "sans_desc": "Koristi se za osnovni tekst i elemente korisniฤkog interfejsa.",
+ "mono": "Geist Mono",
+ "mono_desc": "Koristi se za kod, naslove i tehniฤki sadrลพaj.",
+ "pangram": "Ljubazni fenjerdลพija ฤaฤavog lica hoฤe da mi pokaลพe ลกtos.",
+ "numbers": "0123456789"
+ },
+ "guidelines": {
+ "title": "samo napomena",
+ "message": "Pristupaฤnost nam je vaลพna, i voleli bismo da nas pratite u ovoj viziji. Kada koristite pomenute medije, osigurajte dovoljan kontrast u odnosu na pozadinu i nemojte iฤi manje od 24px. Ako su vam potrebni bilo kakvi drugi resursi ili dodatne informacije o projektu, slobodno nas kontaktirajte na {link}.",
+ "discord_link_text": "chat.npmx.dev"
+ }
+ }
+}
diff --git a/i18n/locales/ta-IN.json b/i18n/locales/ta-IN.json
index 0f566ebfef..96a41eb17d 100644
--- a/i18n/locales/ta-IN.json
+++ b/i18n/locales/ta-IN.json
@@ -626,12 +626,10 @@
"code": {
"files_label": "เฎเฏเฎชเฏเฎชเฏเฎเฎณเฏ",
"no_files": "เฎเฎจเฏเฎค เฎเฏเฎชเฏเฎชเฎเฎคเฏเฎคเฎฟเฎฒเฏ เฎเฏเฎชเฏเฎชเฏเฎเฎณเฏ เฎเฎฒเฏเฎฒเฏ",
- "root": "เฎฎเฏเฎฒเฎฎเฏ",
"lines": "{count} เฎตเฎฐเฎฟ | {count} เฎตเฎฐเฎฟเฎเฎณเฏ",
"toggle_tree": "เฎเฏเฎชเฏเฎชเฏ เฎฎเฎฐเฎคเฏเฎคเฏ เฎจเฎฟเฎฒเฏเฎฎเฎพเฎฑเฏเฎฑเฏ",
"close_tree": "เฎเฏเฎชเฏเฎชเฏ เฎฎเฎฐเฎคเฏเฎคเฏ เฎฎเฏเฎเฏ",
"copy_link": "เฎเฎฃเฏเฎชเฏเฎชเฏ เฎจเฎเฎฒเฏเฎเฏ",
- "raw": "เฎฎเฏเฎฒเฎฎเฏ",
"view_raw": "เฎฎเฏเฎฒ เฎเฏเฎชเฏเฎชเฏเฎเฏ เฎเฎพเฎฃเฏเฎ",
"file_too_large": "เฎฎเฏเฎฉเฏเฎฉเฏเฎเฏเฎเฎฎเฎฟเฎ เฎเฏเฎชเฏเฎชเฏ เฎฎเฎฟเฎเฎชเฏเฎชเฏเฎฐเฎฟเฎฏเฎคเฏ",
"file_size_warning": "{size} เฎคเฏเฎเฎฐเฎฟเฎฏเฎฒเฏ เฎเฎฟเฎฑเฎชเฏเฎชเฎฟเฎคเฏเฎคเฎฒเฏเฎเฏเฎเฎพเฎฉ 500KB เฎตเฎฐเฎฎเฏเฎชเฏ เฎฎเฏเฎฑเฏเฎเฎฟเฎฑเฎคเฏ",
diff --git a/i18n/locales/te-IN.json b/i18n/locales/te-IN.json
index 18dd0d5646..ab580f63b4 100644
--- a/i18n/locales/te-IN.json
+++ b/i18n/locales/te-IN.json
@@ -546,12 +546,10 @@
"code": {
"files_label": "เฐซเฑเฐฒเฑโเฐฒเฑ",
"no_files": "เฐ เฐกเฑเฐฐเฑเฐเฑเฐเฐฐเฑเฐฒเฑ เฐซเฑเฐฒเฑโเฐฒเฑ เฐฒเฑเฐตเฑ",
- "root": "เฐฐเฑเฐเฑ",
"lines": "{count} เฐชเฐเฐเฑเฐคเฑเฐฒเฑ",
"toggle_tree": "เฐซเฑเฐฒเฑ เฐเฑเฐฐเฑเฐจเฐฟ เฐเฐพเฐเฑเฐฒเฑ เฐเฑเฐฏเฐเฐกเฐฟ",
"close_tree": "เฐซเฑเฐฒเฑ เฐเฑเฐฐเฑเฐจเฐฟ เฐฎเฑเฐธเฐฟเฐตเฑเฐฏเฐเฐกเฐฟ",
"copy_link": "เฐฒเฐฟเฐเฐเฑโเฐจเฑ เฐเฐพเฐชเฑ เฐเฑเฐฏเฐเฐกเฐฟ",
- "raw": "เฐฐเฐพ",
"view_raw": "เฐฐเฐพ เฐซเฑเฐฒเฑโเฐจเฑ เฐตเฑเฐเฑเฐทเฐฟเฐเฐเฐเฐกเฐฟ",
"file_too_large": "เฐซเฑเฐฒเฑ เฐชเฑเฐฐเฐฟเฐตเฑเฐฏเฑ เฐเฑเฐธเฐ เฐเฐพเฐฒเฐพ เฐชเฑเฐฆเฑเฐฆเฐฆเฐฟ",
"file_size_warning": "{size} เฐธเฐฟเฐเฐเฐพเฐเฑเฐธเฑ เฐนเฑเฐฒเฑเฐเฐฟเฐเฐเฑ เฐเฑเฐธเฐ 500KB เฐชเฐฐเฐฟเฐฎเฐฟเฐคเฐฟ เฐเฐเฐเฑ เฐเฐเฑเฐเฑเฐต",
diff --git a/i18n/locales/tr-TR.json b/i18n/locales/tr-TR.json
index 47ac20eb2b..8d686950a3 100644
--- a/i18n/locales/tr-TR.json
+++ b/i18n/locales/tr-TR.json
@@ -755,12 +755,10 @@
"code": {
"files_label": "Dosyalar",
"no_files": "Bu klasรถrde dosya yok",
- "root": "kรถk",
"lines": "{count} satฤฑr",
"toggle_tree": "Dosya aฤacฤฑnฤฑ deฤiลtir",
"close_tree": "Dosya aฤacฤฑnฤฑ kapat",
"copy_link": "Baฤlantฤฑyฤฑ kopyala",
- "raw": "Ham",
"view_raw": "Ham dosyayฤฑ gรถster",
"file_too_large": "Dosya รถnizleme iรงin รงok bรผyรผk",
"file_size_warning": "{size} sรถzdizimi vurgulama iรงin 500KB limitini aลฤฑyor",
diff --git a/i18n/locales/uk-UA.json b/i18n/locales/uk-UA.json
index eb7037f0d0..41417d1893 100644
--- a/i18n/locales/uk-UA.json
+++ b/i18n/locales/uk-UA.json
@@ -441,8 +441,6 @@
},
"page_title": "ะััะพััั ะฒะตัััะน",
"current_tags": "ะะพัะพัะฝั ัะตะณะธ",
- "version_filter_placeholder": "ะคัะปััััะฒะฐัะธ ะฒะตััััโฆ",
- "version_filter_label": "ะคัะปััััะฒะฐัะธ ะฒะตัััั",
"no_match_filter": "ะะตัััะน ะทะฐ ััะปัััะพะผ \"{filter}\" ะฝะต ะทะฝะฐะนะดะตะฝะพ"
},
"dependencies": {
@@ -822,12 +820,10 @@
"code": {
"files_label": "ะคะฐะนะปะธ",
"no_files": "ะะตะผะฐั ัะฐะนะปัะฒ ั ััะน ะฟะฐะฟัั",
- "root": "ะบะพััะฝั",
"lines": "{count} ััะดะบัะฒ",
"toggle_tree": "ะะตัะตะบะปััะธัะธ ะดะตัะตะฒะพ ัะฐะนะปัะฒ",
"close_tree": "ะะฐะบัะธัะธ ะดะตัะตะฒะพ ัะฐะนะปัะฒ",
"copy_link": "ะะพะฟััะฒะฐัะธ ะฟะพัะธะปะฐะฝะฝั",
- "raw": "ะะตะพะฑัะพะฑะปะตะฝะพ",
"view_raw": "ะะตัะตะณะปัะฝััะธ ะฝะตะพะฑัะพะฑะปะตะฝะธะน ัะฐะนะป",
"file_too_large": "ะคะฐะนะป ะทะฐะฝะฐะดัะพ ะฒะตะปะธะบะธะน ะดะปั ะฟะพะฟะตัะตะดั",
"file_size_warning": "{size} ะฟะตัะตะฒะธััั ะปัะผัั 500KB ะดะปั ะฒะธะดัะปะตะฝะฝั ัะธะฝัะฐะบัะธัั",
diff --git a/i18n/locales/vi-VN.json b/i18n/locales/vi-VN.json
index 362f1831f7..8eb5694da7 100644
--- a/i18n/locales/vi-VN.json
+++ b/i18n/locales/vi-VN.json
@@ -441,8 +441,6 @@
},
"page_title": "Lแปch sแปญ phiรชn bแบฃn",
"current_tags": "Thแบป hiแปn tแบกi",
- "version_filter_placeholder": "Lแปc phiรชn bแบฃnโฆ",
- "version_filter_label": "Lแปc phiรชn bแบฃn",
"no_match_filter": "Khรดng cรณ phiรชn bแบฃn khแปp {filter}"
},
"dependencies": {
@@ -822,12 +820,10 @@
"code": {
"files_label": "Tแปp",
"no_files": "Khรดng cรณ tแปp nร o trong thฦฐ mแปฅc nร y",
- "root": "gแปc",
"lines": "{count} dรฒng | {count} dรฒng",
"toggle_tree": "Bแบญt/tแบฏt cรขy thฦฐ mแปฅc",
"close_tree": "ฤรณng cรขy thฦฐ mแปฅc",
"copy_link": "Sao chรฉp liรชn kแบฟt",
- "raw": "Thรด",
"view_raw": "Xem tแปp thรด",
"file_too_large": "Tแปp quรก lแปn ฤแป xem trฦฐแปc",
"file_size_warning": "{size} vฦฐแปฃt quรก giแปi hแบกn 500KB ฤแป tรด mร u cรบ phรกp (syntax highlight)",
diff --git a/i18n/locales/zh-CN.json b/i18n/locales/zh-CN.json
index 865e40a93f..57a2037ce3 100644
--- a/i18n/locales/zh-CN.json
+++ b/i18n/locales/zh-CN.json
@@ -414,8 +414,6 @@
},
"page_title": "็ๆฌๅๅฒ",
"current_tags": "ๅฝๅๆ ็ญพ",
- "version_filter_placeholder": "็ญ้็ๆฌโฆ",
- "version_filter_label": "็ญ้็ๆฌ",
"no_match_filter": "ๆฒกๆไธโ{filter}โๅน้
็็ๆฌ"
},
"dependencies": {
@@ -783,12 +781,10 @@
"code": {
"files_label": "ๆไปถ",
"no_files": "่ฟไธช็ฎๅฝไธญๆฒกๆๆไปถ",
- "root": "ๆ น็ฎๅฝ",
"lines": "{count} ่ก",
"toggle_tree": "ๅๆขๆไปถๆ ",
"close_tree": "ๅ
ณ้ญๆไปถๆ ",
"copy_link": "ๅคๅถ้พๆฅ",
- "raw": "ๅๅงๆไปถ",
"view_raw": "ๆฅ็ๅๅงๆไปถ",
"file_too_large": "ๆไปถ่ฟๅคง๏ผๆ ๆณ้ข่ง",
"file_size_warning": "{size} ่ถ
ๅบไบ 500KB ็่ฏญๆณ้ซไบฎ้ๅถ",
diff --git a/i18n/locales/zh-TW.json b/i18n/locales/zh-TW.json
index d7e467d582..ac8a333fac 100644
--- a/i18n/locales/zh-TW.json
+++ b/i18n/locales/zh-TW.json
@@ -414,8 +414,6 @@
},
"page_title": "็ๆฌๆญทๅฒ่จ้",
"current_tags": "็ถๅๆจ็ฑค",
- "version_filter_placeholder": "็ฏฉ้ธ็ๆฌโฆ",
- "version_filter_label": "็ฏฉ้ธ็ๆฌ",
"no_match_filter": "ๆฒๆ็ๆฌ็ฌฆๅ {filter}"
},
"dependencies": {
@@ -783,12 +781,10 @@
"code": {
"files_label": "ๆชๆก",
"no_files": "ๆญค็ฎ้ไธญๆฒๆๆชๆก",
- "root": "ๆ น็ฎ้",
"lines": "{count} ่ก",
"toggle_tree": "ๅๆๆชๆกๆจน",
"close_tree": "้้ๆชๆกๆจน",
"copy_link": "่ค่ฃฝ้ฃ็ต",
- "raw": "ๅๅง",
"view_raw": "ๆชข่ฆๅๅงๆช",
"file_too_large": "ๆชๆกๅคชๅคง็กๆณ้ ่ฆฝ",
"file_size_warning": "{size} ่ถ
้ 500KB ็่ชๆณ้ซไบฎ้ๅถ",
diff --git a/i18n/schema.json b/i18n/schema.json
index 01c96fd953..a621a2e288 100644
--- a/i18n/schema.json
+++ b/i18n/schema.json
@@ -1327,12 +1327,6 @@
"current_tags": {
"type": "string"
},
- "version_filter_placeholder": {
- "type": "string"
- },
- "version_filter_label": {
- "type": "string"
- },
"no_match_filter": {
"type": "string"
}
@@ -2479,9 +2473,6 @@
"no_files": {
"type": "string"
},
- "root": {
- "type": "string"
- },
"lines": {
"type": "string"
},
@@ -2491,15 +2482,24 @@
"close_tree": {
"type": "string"
},
- "copy_link": {
+ "copy_content": {
"type": "string"
},
- "raw": {
+ "copy_link": {
"type": "string"
},
"view_raw": {
"type": "string"
},
+ "toggle_container": {
+ "type": "string"
+ },
+ "open_raw_file": {
+ "type": "string"
+ },
+ "open_path_dropdown": {
+ "type": "string"
+ },
"file_too_large": {
"type": "string"
},
diff --git a/lunaria/styles.ts b/lunaria/styles.ts
index 3c2bb86be9..1dadd4a38b 100644
--- a/lunaria/styles.ts
+++ b/lunaria/styles.ts
@@ -7,8 +7,8 @@ export const BaseStyles = html`
--ln-font-fallback:
-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji,
Segoe UI Emoji;
- --ln-font-body: 'Geist', var(--ln-font-fallback);
- --ln-font-mono: 'Geist Mono', monospace;
+ --ln-font-body: 'Geist', 'IBM Plex Sans Arabic', var(--ln-font-fallback);
+ --ln-font-mono: 'Geist Mono', 'IBM Plex Sans Arabic', monospace;
/* Light theme colors */
--ln-color-white: #f9fafb;
diff --git a/modules/blog.ts b/modules/blog.ts
index 3ece7abae8..26af619377 100644
--- a/modules/blog.ts
+++ b/modules/blog.ts
@@ -13,10 +13,9 @@ import {
type BlogPostFrontmatter,
type ResolvedAuthor,
} from '../shared/schemas/blog'
-import { globSync } from 'tinyglobby'
import { isProduction } from '../config/env'
import { BLUESKY_API } from '../shared/utils/constants'
-import { mkdir, writeFile } from 'node:fs/promises'
+import { glob, mkdir, writeFile } from 'node:fs/promises'
import { existsSync } from 'node:fs'
import crypto from 'node:crypto'
@@ -89,7 +88,7 @@ function resolveAuthors(authors: Author[], avatarMap: Map): Reso
* Resolves Bluesky avatars at build time.
*/
async function loadBlogPosts(blogDir: string, imagesDir: string): Promise {
- const files: string[] = globSync(join(blogDir, '*.md').replace(/\\/g, '/'))
+ const files = await Array.fromAsync(glob(join(blogDir, '*.md').replace(/\\/g, '/')))
// First pass: extract raw frontmatter and collect all Bluesky handles
const rawPosts: Array<{ frontmatter: Record }> = []
diff --git a/modules/security-headers.ts b/modules/security-headers.ts
index 748e5ac6c4..e5b6b0dfaa 100644
--- a/modules/security-headers.ts
+++ b/modules/security-headers.ts
@@ -1,4 +1,4 @@
-import { defineNuxtModule } from 'nuxt/kit'
+import { defineNuxtModule, useNuxt } from 'nuxt/kit'
import { BLUESKY_API } from '#shared/utils/constants'
import { ALL_KNOWN_GIT_API_ORIGINS } from '#shared/utils/git-providers'
import { TRUSTED_IMAGE_DOMAINS } from '#server/utils/image-proxy'
@@ -19,7 +19,16 @@ import { TRUSTED_IMAGE_DOMAINS } from '#server/utils/image-proxy'
*/
export default defineNuxtModule({
meta: { name: 'security-headers' },
- setup(_, nuxt) {
+ setup() {
+ const nuxt = useNuxt()
+ const devtools = nuxt.options.devtools
+
+ const isDevtoolsRuntime =
+ nuxt.options.dev &&
+ devtools !== false &&
+ (devtools == null || typeof devtools !== 'object' || devtools.enabled !== false) &&
+ !process.env.TEST
+
// These assets are embedded directly on blog pages and should not affect image-proxy trust.
const cspOnlyImgOrigins = ['https://api.star-history.com', 'https://cdn.bsky.app']
const imgSrc = [
@@ -39,9 +48,21 @@ export default defineNuxtModule({
...ALL_KNOWN_GIT_API_ORIGINS,
// Local CLI connector (npmx CLI communicates via localhost)
'http://127.0.0.1:*',
+ // Devtools runtime (Vue Devtools, Nuxt Devtools, etc) โ only in dev mode with devtools enabled
+ ...(isDevtoolsRuntime ? ['ws://localhost:*'] : []),
+ ].join(' ')
+
+ const frameSrc = [
+ 'https://bsky.app',
+ 'https://pdsmoover.com',
+ ...(isDevtoolsRuntime ? ["'self'"] : []),
].join(' ')
- const frameSrc = ['https://bsky.app', 'https://pdsmoover.com'].join(' ')
+ const securityHeaders = {
+ 'X-Content-Type-Options': 'nosniff',
+ 'X-Frame-Options': 'DENY',
+ 'Referrer-Policy': 'strict-origin-when-cross-origin',
+ }
const csp = [
`default-src 'none'`,
@@ -74,9 +95,20 @@ export default defineNuxtModule({
...wildCardRules,
headers: {
...wildCardRules?.headers,
- 'X-Content-Type-Options': 'nosniff',
- 'X-Frame-Options': 'DENY',
- 'Referrer-Policy': 'strict-origin-when-cross-origin',
+ ...securityHeaders,
+ },
+ }
+
+ if (!isDevtoolsRuntime) return
+
+ const devtoolsRule = nuxt.options.routeRules['/__nuxt_devtools__/**']
+ nuxt.options.routeRules['/__nuxt_devtools__/**'] = {
+ ...devtoolsRule,
+ headers: {
+ ...wildCardRules?.headers,
+ ...securityHeaders,
+ ...devtoolsRule?.headers,
+ 'X-Frame-Options': 'SAMEORIGIN',
},
}
},
diff --git a/modules/standard-site-sync.ts b/modules/standard-site-sync.ts
index 121ca13123..db9c98691e 100644
--- a/modules/standard-site-sync.ts
+++ b/modules/standard-site-sync.ts
@@ -1,5 +1,7 @@
import process from 'node:process'
import { createHash } from 'node:crypto'
+import { glob } from 'node:fs/promises'
+import { join } from 'node:path'
import { defineNuxtModule, useNuxt, createResolver } from 'nuxt/kit'
import { safeParse } from 'valibot'
import { BlogPostSchema, type BlogPostFrontmatter } from '#shared/schemas/blog'
@@ -51,8 +53,7 @@ export default defineNuxtModule({
const possiblePublication = await checkPublication(handle, pdsPublicClient)
nuxt.hook('build:before', async () => {
- const { glob } = await import('tinyglobby')
- const files: string[] = await glob(`${contentDir}/**/*.md`)
+ const files = await Array.fromAsync(glob(join(contentDir, '**/*.md')))
// INFO: Arbitrarily chosen concurrency limit, can be changed if needed
const concurrencyLimit = 5
diff --git a/nuxt.config.ts b/nuxt.config.ts
index 9a375d02b4..6a317eed0d 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -277,6 +277,12 @@ export default defineNuxtConfig({
preload: true,
global: true,
},
+ {
+ name: 'IBM Plex Sans Arabic',
+ weights: ['400', '500', '600'],
+ global: true,
+ subsets: ['arabic'],
+ },
],
},
diff --git a/package.json b/package.json
index cc29a66be3..f010bdea9d 100644
--- a/package.json
+++ b/package.json
@@ -57,6 +57,7 @@
"@iconify-json/svg-spinners": "1.2.4",
"@iconify-json/vscode-icons": "1.2.45",
"@intlify/shared": "11.3.0",
+ "@li/regexp-escape-polyfill": "jsr:0.3.4",
"@lunariajs/core": "https://pkg.pr.new/lunariajs/lunaria/@lunariajs/core@904b935",
"@napi-rs/canvas": "0.1.97",
"@nuxt/a11y": "1.0.0-alpha.1",
@@ -99,7 +100,6 @@
"simple-git": "3.33.0",
"spdx-license-list": "6.11.0",
"std-env": "4.0.0",
- "tinyglobby": "0.2.15",
"ufo": "1.6.3",
"unocss": "66.6.7",
"unplugin-vue-router": "0.19.2",
@@ -109,7 +109,7 @@
"vite-plugin-pwa": "1.2.0",
"vite-plus": "0.1.12",
"vue": "3.5.30",
- "vue-data-ui": "3.17.1"
+ "vue-data-ui": "3.17.3"
},
"devDependencies": {
"@e18e/eslint-plugin": "0.3.0",
diff --git a/playwright.config.ts b/playwright.config.ts
index 01e43f7a5d..7c2cb39fbc 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -1,5 +1,5 @@
import process from 'node:process'
-import { fileURLToPath } from 'node:url'
+import { join } from 'node:path'
import { defineConfig, devices } from '@playwright/test'
import type { ConfigOptions } from '@nuxt/test-utils/playwright'
@@ -19,14 +19,14 @@ export default defineConfig({
timeout: 60_000,
},
// Start/stop mock connector server before/after all tests (teardown via returned closure)
- globalSetup: fileURLToPath(new URL('./test/e2e/global-setup.ts', import.meta.url)),
+ globalSetup: join(import.meta.dirname, 'test/e2e/global-setup.ts'),
// We currently only test on one browser on one platform
snapshotPathTemplate: '{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{ext}',
use: {
baseURL,
trace: 'on-first-retry',
nuxt: {
- rootDir: fileURLToPath(new URL('.', import.meta.url)),
+ rootDir: import.meta.dirname,
host: baseURL,
},
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 25ffb6f791..f2b39e2f38 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -78,6 +78,9 @@ importers:
'@intlify/shared':
specifier: 11.3.0
version: 11.3.0
+ '@li/regexp-escape-polyfill':
+ specifier: jsr:0.3.4
+ version: '@jsr/li__regexp-escape-polyfill@0.3.4'
'@lunariajs/core':
specifier: https://pkg.pr.new/lunariajs/lunaria/@lunariajs/core@904b935
version: https://pkg.pr.new/lunariajs/lunaria/@lunariajs/core@904b935
@@ -204,9 +207,6 @@ importers:
std-env:
specifier: 4.0.0
version: 4.0.0
- tinyglobby:
- specifier: 0.2.15
- version: 0.2.15
ufo:
specifier: 1.6.3
version: 1.6.3
@@ -235,8 +235,8 @@ importers:
specifier: 3.5.30
version: 3.5.30(typescript@6.0.2)
vue-data-ui:
- specifier: 3.17.1
- version: 3.17.1(vue@3.5.30(typescript@6.0.2))
+ specifier: 3.17.3
+ version: 3.17.3(vue@3.5.30(typescript@6.0.2))
devDependencies:
'@e18e/eslint-plugin':
specifier: 0.3.0
@@ -2002,6 +2002,9 @@ packages:
'@jsr/deno__graph@0.86.9':
resolution: {integrity: sha512-+qrrma5/bL+hcG20mfaEeC8SLopqoyd1RjcKFMRu++3SAXyrTKuvuIjBJCn/NyN7X+kV+QrJG67BCHX38Rzw+g==, tarball: https://npm.jsr.io/~/11/@jsr/deno__graph/0.86.9.tgz}
+ '@jsr/li__regexp-escape-polyfill@0.3.4':
+ resolution: {integrity: sha512-UGHzM9zAlRt0DUQIgsXAuXBd9jdzJ3t1v+fHsIcIj2fbUKplO9A8v2FE/w9KZo8hs79n5IamuBvqCTndGADM2Q==, tarball: https://npm.jsr.io/~/11/@jsr/li__regexp-escape-polyfill/0.3.4.tgz}
+
'@jsr/std__bytes@1.0.6':
resolution: {integrity: sha512-St6yKggjFGhxS52IFLJWvkchRFbAKg2Xh8UxA4S1EGz7GJ2Ui+ssDDldj/w2c8vCxvl6qgR0HaYbKeFJNqujmA==, tarball: https://npm.jsr.io/~/11/@jsr/std__bytes/1.0.6.tgz}
@@ -10721,8 +10724,8 @@ packages:
vue-component-type-helpers@3.2.6:
resolution: {integrity: sha512-O02tnvIfOQVmnvoWwuSydwRoHjZVt8UEBR+2p4rT35p8GAy5VTlWP8o5qXfJR/GWCN0nVZoYWsVUvx2jwgdBmQ==}
- vue-data-ui@3.17.1:
- resolution: {integrity: sha512-MRSWzNXQQpfWQq5GMaxwNoOFYnHEj5sAui19HaA9rT5eHdgAAgwqJS1Gzx+7XBqNcYmW4MK/3qzX8KH0BbiiQQ==}
+ vue-data-ui@3.17.3:
+ resolution: {integrity: sha512-Adfyb/x2Jy0BdpGgugckK44/XRW43lVChqsJuM3cVdx9x87A9Q4sDfH2HjAxLH2BWIeQcEgkI6ozXf8m/97tHw==}
peerDependencies:
jspdf: '>=3.0.1'
vue: '>=3.3.0'
@@ -12843,6 +12846,8 @@ snapshots:
'@jsr/deno__graph@0.86.9': {}
+ '@jsr/li__regexp-escape-polyfill@0.3.4': {}
+
'@jsr/std__bytes@1.0.6': {}
'@jsr/std__fmt@1.0.9': {}
@@ -23600,7 +23605,7 @@ snapshots:
vue-component-type-helpers@3.2.6: {}
- vue-data-ui@3.17.1(vue@3.5.30(typescript@6.0.2)):
+ vue-data-ui@3.17.3(vue@3.5.30(typescript@6.0.2)):
dependencies:
vue: 3.5.30(typescript@6.0.2)
diff --git a/public/robots.txt b/public/robots.txt
index bdd4add700..1efdb87b4f 100644
--- a/public/robots.txt
+++ b/public/robots.txt
@@ -1,5 +1,19 @@
-User-agent: *
-Allow: /
+Allow: /$
+Allow: /about$
+Allow: /accessibility$
+Allow: /blog
+Allow: /brand$
+Allow: /pds$
+Allow: /privacy$
+Allow: /translation-status$
+Allow: /recharging$
+Allow: /__og-image__/*
+Allow: /opensearch.xml$
+
+Disallow: /
+
+# User-agent: *
+# Allow: /
# Search pages: infinite query-param combinations
Disallow: /search
diff --git a/scripts/compare-translations.ts b/scripts/compare-translations.ts
index c670995625..3afd9bd76b 100644
--- a/scripts/compare-translations.ts
+++ b/scripts/compare-translations.ts
@@ -3,12 +3,11 @@ import type { LocaleObject } from '@nuxtjs/i18n'
import * as process from 'node:process'
import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'
import { basename, join, resolve } from 'node:path'
-import { fileURLToPath } from 'node:url'
import { deepCopy } from '@intlify/shared'
import { countryLocaleVariants, currentLocales } from '../config/i18n.ts'
import { COLORS } from './utils.ts'
-const LOCALES_DIRECTORY = fileURLToPath(new URL('../i18n/locales', import.meta.url))
+const LOCALES_DIRECTORY = join(import.meta.dirname, '../i18n/locales')
const REFERENCE_FILE_NAME = 'en.json'
type NestedObject = { [key: string]: unknown }
diff --git a/scripts/find-invalid-translations.ts b/scripts/find-invalid-translations.ts
index 5c32edf070..173ae7a2b7 100644
--- a/scripts/find-invalid-translations.ts
+++ b/scripts/find-invalid-translations.ts
@@ -1,10 +1,9 @@
/* eslint-disable no-console */
import { join } from 'node:path'
-import { fileURLToPath } from 'node:url'
import { createI18NReport, type I18NItem } from 'vue-i18n-extract'
import { colors } from './utils/colors.ts'
-const LOCALES_DIRECTORY = fileURLToPath(new URL('../i18n/locales', import.meta.url))
+const LOCALES_DIRECTORY = join(import.meta.dirname, '../i18n/locales')
const REFERENCE_FILE_NAME = 'en.json'
const VUE_FILES_GLOB = './app/**/*.?(vue|ts|js)'
diff --git a/scripts/generate-fixtures.ts b/scripts/generate-fixtures.ts
index fdad17fc4a..bf71c05161 100644
--- a/scripts/generate-fixtures.ts
+++ b/scripts/generate-fixtures.ts
@@ -12,9 +12,8 @@
import { writeFileSync, mkdirSync, existsSync } from 'node:fs'
import { dirname, join } from 'node:path'
-import { fileURLToPath } from 'node:url'
-const FIXTURES_DIR = fileURLToPath(new URL('../test/fixtures', import.meta.url))
+const FIXTURES_DIR = join(import.meta.dirname, '../test/fixtures')
const NPM_REGISTRY = 'https://registry.npmjs.org'
const NPM_API = 'https://api.npmjs.org'
diff --git a/scripts/generate-i18n-schema.ts b/scripts/generate-i18n-schema.ts
index 2f1b498d61..9f991880f0 100644
--- a/scripts/generate-i18n-schema.ts
+++ b/scripts/generate-i18n-schema.ts
@@ -1,10 +1,9 @@
/* oxlint-disable no-console */
import { readFile, writeFile } from 'node:fs/promises'
import { join } from 'node:path'
-import { fileURLToPath } from 'node:url'
import { colors } from './utils/colors.ts'
-const I18N_DIRECTORY = fileURLToPath(new URL('../i18n', import.meta.url))
+const I18N_DIRECTORY = join(import.meta.dirname, '../i18n')
const LOCALES_DIRECTORY = join(I18N_DIRECTORY, 'locales')
const REFERENCE_FILE_NAME = 'en.json'
const SCHEMA_FILE_NAME = 'schema.json'
diff --git a/scripts/remove-unused-translations.ts b/scripts/remove-unused-translations.ts
index 75632a9385..602d9643d2 100644
--- a/scripts/remove-unused-translations.ts
+++ b/scripts/remove-unused-translations.ts
@@ -1,11 +1,10 @@
/* eslint-disable no-console */
import { join } from 'node:path'
-import { fileURLToPath } from 'node:url'
import { createI18NReport, type I18NItem } from 'vue-i18n-extract'
import { colors } from './utils/colors.ts'
import { readdir, readFile, writeFile } from 'node:fs/promises'
-const LOCALES_DIRECTORY = fileURLToPath(new URL('../i18n/locales', import.meta.url))
+const LOCALES_DIRECTORY = join(import.meta.dirname, '../i18n/locales')
const REFERENCE_FILE_NAME = 'en.json'
const VUE_FILES_GLOB = './app/**/*.?(vue|ts|js)'
diff --git a/scripts/unocss-checker.ts b/scripts/unocss-checker.ts
index 697621d582..0cf58cd8af 100644
--- a/scripts/unocss-checker.ts
+++ b/scripts/unocss-checker.ts
@@ -1,6 +1,5 @@
import type { Dirent } from 'node:fs'
import { glob, readFile } from 'node:fs/promises'
-import { fileURLToPath } from 'node:url'
import { resolve } from 'node:path'
import { createGenerator } from 'unocss'
import { presetRtl } from '../uno-preset-rtl.ts'
@@ -9,7 +8,7 @@ import { COLORS } from './utils.ts'
import { presetWind4 } from 'unocss'
const argvFiles = process.argv.slice(2)
-const APP_DIRECTORY = fileURLToPath(new URL('../app', import.meta.url))
+const APP_DIRECTORY = resolve(import.meta.dirname, '../app')
async function checkFile(path: Dirent): Promise {
if (path.isDirectory() || !path.name.endsWith('.vue')) {
diff --git a/server/api/github/contributors-evolution/[owner]/[repo].get.ts b/server/api/github/contributors-evolution/[owner]/[repo].get.ts
index 24499a53a7..47cde6df85 100644
--- a/server/api/github/contributors-evolution/[owner]/[repo].get.ts
+++ b/server/api/github/contributors-evolution/[owner]/[repo].get.ts
@@ -1,3 +1,4 @@
+import { setTimeout } from 'node:timers/promises'
import { CACHE_MAX_AGE_ONE_DAY } from '#shared/utils/constants'
type GitHubContributorWeek = {
@@ -12,8 +13,6 @@ type GitHubContributorStats = {
weeks: GitHubContributorWeek[]
}
-const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))
-
export default defineCachedEventHandler(
async event => {
const owner = getRouterParam(event, 'owner')
@@ -50,7 +49,7 @@ export default defineCachedEventHandler(
if (status === 202) {
if (attempt === maxAttempts - 1) return []
- await sleep(delayMs)
+ await setTimeout(delayMs)
delayMs = Math.min(delayMs * 2, 16_000)
continue
}
diff --git a/server/utils/atproto/lock.ts b/server/utils/atproto/lock.ts
index 21f00dc2b2..b91a1ac812 100644
--- a/server/utils/atproto/lock.ts
+++ b/server/utils/atproto/lock.ts
@@ -1,3 +1,4 @@
+import { setTimeout } from 'node:timers/promises'
import type { RuntimeLock } from '@atproto/oauth-client-node'
import { requestLocalLock } from '@atproto/oauth-client-node'
import { Redis } from '@upstash/redis'
@@ -22,7 +23,7 @@ function createUpstashLock(redis: Redis): RuntimeLock {
if (!acquired) {
// Another instance holds the lock, wait briefly and retry once
- await new Promise(resolve => setTimeout(resolve, 100))
+ await setTimeout(100)
const retryAcquired = await redis.set(lockKey, lockValue, {
nx: true,
ex: lockTTL,
diff --git a/server/utils/atproto/oauth.ts b/server/utils/atproto/oauth.ts
index 58152fd2b1..ae9ba489d2 100644
--- a/server/utils/atproto/oauth.ts
+++ b/server/utils/atproto/oauth.ts
@@ -41,11 +41,11 @@ export function getOauthClientMetadata(pkAlg: string | undefined = undefined): O
? webUriSchema.parse(`${clientUri}/.well-known/jwks.json`)
: undefined
- // If anything changes here, please make sure to also update /shared/schemas/oauth.ts to match
return {
client_name: 'npmx.dev',
client_id,
client_uri: clientUri,
+ logo_uri: webUriSchema.parse(`${clientUri}/logo-icon.svg`),
scope,
redirect_uris: [redirect_uri],
grant_types: ['authorization_code', 'refresh_token'],
diff --git a/server/utils/readme.ts b/server/utils/readme.ts
index b5befe67b7..a97e620ebd 100644
--- a/server/utils/readme.ts
+++ b/server/utils/readme.ts
@@ -298,6 +298,14 @@ function toUserContentHash(value: string): string {
return `#${withUserContentPrefix(value)}`
}
+function decodeHashFragment(value: string): string {
+ try {
+ return decodeURIComponent(value)
+ } catch {
+ return value
+ }
+}
+
function normalizePreservedAnchorAttrs(attrs: string): string {
const cleanedAttrs = attrs
.replace(/\s+href\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)/gi, '')
@@ -333,8 +341,18 @@ function resolveUrl(url: string, packageName: string, repoInfo?: RepositoryInfo)
if (!url) return url
if (url.startsWith('#')) {
// Prefix anchor links to match heading IDs (avoids collision with page IDs)
- // Idempotent: don't double-prefix if already prefixed
- return toUserContentHash(url.slice(1))
+ // Normalize markdown-style heading fragments to the same slug format used
+ // for generated README heading IDs, but leave already-prefixed values as-is.
+ const fragment = url.slice(1)
+ if (!fragment) {
+ return '#'
+ }
+ if (fragment.startsWith(USER_CONTENT_PREFIX)) {
+ return `#${fragment}`
+ }
+
+ const normalizedFragment = slugify(decodeHashFragment(fragment))
+ return toUserContentHash(normalizedFragment || fragment)
}
// Absolute paths (e.g. /package/foo from a previous npmjs redirect) are already resolved
if (url.startsWith('/')) return url
diff --git a/shared/utils/dev-dependency.ts b/shared/utils/dev-dependency.ts
index f45449ba52..ae30d8855f 100644
--- a/shared/utils/dev-dependency.ts
+++ b/shared/utils/dev-dependency.ts
@@ -1,3 +1,5 @@
+import { regExpEscape } from '@li/regexp-escape-polyfill'
+
export type DevDependencySuggestionReason = 'known-package' | 'readme-hint'
export interface DevDependencySuggestion {
@@ -59,15 +61,11 @@ function isKnownDevDependencyPackage(packageName: string): boolean {
)
}
-function escapeRegExp(text: string): string {
- return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
-}
-
function hasReadmeDevInstallHint(packageName: string, readmeContent?: string | null): boolean {
if (!readmeContent) return false
- const escapedName = escapeRegExp(packageName)
- const escapedNpmName = escapeRegExp(`npm:${packageName}`)
+ const escapedName = regExpEscape(packageName)
+ const escapedNpmName = regExpEscape(`npm:${packageName}`)
const packageSpec = `(?:${escapedName}|${escapedNpmName})(?:@[\\w.-]+)?`
const patterns = [
diff --git a/shared/utils/emoji.ts b/shared/utils/emoji.ts
index b617309226..f9da977b6f 100644
--- a/shared/utils/emoji.ts
+++ b/shared/utils/emoji.ts
@@ -1,3 +1,5 @@
+import { regExpEscape } from '@li/regexp-escape-polyfill'
+
// copied from https://github.com/markdown-it/markdown-it-emoji/blob/master/lib/data/full.mjs
const emojis = {
'100': '๐ฏ',
@@ -1907,7 +1909,7 @@ const emojis = {
const emojisKeysRegex = new RegExp(
Object.keys(emojis)
- .map(key => `:${key}:`)
+ .map(key => `:${regExpEscape(key)}:`)
.join('|'),
'g',
)
diff --git a/test/nuxt/a11y.spec.ts b/test/nuxt/a11y.spec.ts
index 09f2f1f048..46bba7bba1 100644
--- a/test/nuxt/a11y.spec.ts
+++ b/test/nuxt/a11y.spec.ts
@@ -144,10 +144,11 @@ import {
LandingLogo,
LinkBase,
CallToAction,
- ChartPatternSlot,
CodeDirectoryListing,
CodeFileTree,
+ CodeHeader,
CodeMobileTreeDrawer,
+ CodeSkeletonLoader,
CodeViewer,
CopyToClipboardButton,
CollapsibleSection,
@@ -1256,6 +1257,44 @@ describe('component accessibility audits', () => {
})
})
+ describe('CodeHeader', () => {
+ it('should have no accessibility violations', async () => {
+ const component = await mountSuspended(CodeHeader, {
+ props: {
+ filePath: 'misc/true.js',
+ loading: false,
+ isViewingFile: true,
+ isBinaryFile: false,
+ fileContent: {
+ package: 'vite',
+ version: '1.0.0',
+ path: 'misc/true.js',
+ language: 'javascript',
+ contentType: 'application/javascript',
+ content: 'const x = 1;',
+ html: 'const x = 1;
',
+ lines: 1,
+ },
+ markdownViewMode: 'preview',
+ selectedLines: null,
+ getCodeUrlWithPath: (path = '') => `/package-code/vite/v/1.0.0/${path}`,
+ packageName: 'vite',
+ version: '1.0.0',
+ },
+ })
+ const results = await runAxe(component)
+ expect(results.violations).toEqual([])
+ })
+ })
+
+ describe('CodeSkeletonLoader', () => {
+ it('should have no accessibility violations', async () => {
+ const component = await mountSuspended(CodeSkeletonLoader)
+ const results = await runAxe(component)
+ expect(results.violations).toEqual([])
+ })
+ })
+
describe('CodeViewer', () => {
it('should have no accessibility violations', async () => {
const component = await mountSuspended(CodeViewer, {
@@ -2261,23 +2300,6 @@ describe('component accessibility audits', () => {
})
})
- describe('ChartPatternSlot', () => {
- it('should have no accessibility violations', async () => {
- const component = await mountSuspended(ChartPatternSlot, {
- props: {
- id: 'perennius',
- seed: 1,
- foregroundColor: 'black',
- fallbackColor: 'transparent',
- maxSize: 24,
- minSize: 16,
- },
- })
- const results = await runAxe(component)
- expect(results.violations).toEqual([])
- })
- })
-
describe('CopyToClipboardButton', () => {
it('should have no accessibility violations in default state', async () => {
const component = await mountSuspended(CopyToClipboardButton, {
diff --git a/test/nuxt/components/Package/Versions.spec.ts b/test/nuxt/components/Package/Versions.spec.ts
index 93db7103ab..03d3e2db6e 100644
--- a/test/nuxt/components/Package/Versions.spec.ts
+++ b/test/nuxt/components/Package/Versions.spec.ts
@@ -2,6 +2,7 @@ import { describe, expect, it, vi, beforeEach } from 'vitest'
import { mountSuspended } from '@nuxt/test-utils/runtime'
import type { DOMWrapper } from '@vue/test-utils'
import PackageVersions from '~/components/Package/Versions.vue'
+import { packageVersionsRoute } from '~/utils/router'
// Mock the fetchAllPackageVersions function
const mockFetchAllPackageVersions = vi.fn()
@@ -39,6 +40,12 @@ function isVersionLink(a: DOMWrapper): boolean {
)
}
+function getRouter(
+ component: Awaited>,
+): Pick {
+ return component.vm.$router
+}
+
describe('PackageVersions', () => {
beforeEach(() => {
mockFetchAllPackageVersions.mockReset()
@@ -109,6 +116,42 @@ describe('PackageVersions', () => {
expect(versionLinks[0]?.text()).toBe('1.0.0')
})
+ it('view-all-versions link uses packageVersionsRoute for unscoped packages', async () => {
+ const component = await mountSuspended(PackageVersions, {
+ props: {
+ packageName: 'test-package',
+ versions: {
+ '1.0.0': createVersion('1.0.0'),
+ },
+ distTags: { latest: '1.0.0' },
+ time: { '1.0.0': '2024-01-15T12:00:00.000Z' },
+ },
+ })
+
+ const router = getRouter(component)
+ const expectedHref = router.resolve(packageVersionsRoute('test-package')).href
+ const viewAll = component.find('[data-testid="view-all-versions-link"]')
+ expect(viewAll.attributes('href')).toBe(expectedHref)
+ })
+
+ it('view-all-versions link uses packageVersionsRoute for scoped packages', async () => {
+ const component = await mountSuspended(PackageVersions, {
+ props: {
+ packageName: '@scope/test-package',
+ versions: {
+ '1.0.0': createVersion('1.0.0'),
+ },
+ distTags: { latest: '1.0.0' },
+ time: { '1.0.0': '2024-01-15T12:00:00.000Z' },
+ },
+ })
+
+ const router = getRouter(component)
+ const expectedHref = router.resolve(packageVersionsRoute('@scope/test-package')).href
+ const viewAll = component.find('[data-testid="view-all-versions-link"]')
+ expect(viewAll.attributes('href')).toBe(expectedHref)
+ })
+
it('highlights the current version row when selectedVersion prop matches', async () => {
const component = await mountSuspended(PackageVersions, {
props: {
@@ -815,11 +858,8 @@ describe('PackageVersions', () => {
describe('loading states', () => {
it('shows loading spinner when fetching versions', async () => {
// Create a promise that won't resolve immediately
- let resolvePromise: (value: unknown[]) => void
- const loadingPromise = new Promise(resolve => {
- resolvePromise = resolve
- })
- mockFetchAllPackageVersions.mockReturnValue(loadingPromise)
+ const { promise, resolve } = Promise.withResolvers()
+ mockFetchAllPackageVersions.mockReturnValue(promise)
const component = await mountSuspended(PackageVersions, {
props: {
@@ -842,14 +882,12 @@ describe('PackageVersions', () => {
})
// Resolve the promise to clean up
- resolvePromise!([])
+ resolve([])
})
it('shows loading spinner for other versions when fetching', async () => {
- let resolvePromise: (value: unknown[]) => void
- const loadingPromise = new Promise(resolve => {
- resolvePromise = resolve
- })
+ const { promise: loadingPromise, resolve: resolvePromise } =
+ Promise.withResolvers()
mockFetchAllPackageVersions.mockReturnValue(loadingPromise)
const component = await mountSuspended(PackageVersions, {
@@ -876,7 +914,7 @@ describe('PackageVersions', () => {
})
// Resolve the promise to clean up
- resolvePromise!([])
+ resolvePromise([])
})
})
@@ -1243,6 +1281,21 @@ describe('PackageVersions', () => {
expect(text).not.toContain('0.5.0')
})
})
+
+ it('does not show latest tag when it does not match the filter', async () => {
+ const component = await mountSuspended(PackageVersions, { props: multiVersionProps })
+
+ const input = component.find('input[type="text"]')
+ await input.setValue('^1.0.0 <2.0.0')
+
+ const versionLinks = component.findAll('a').filter(isVersionLink)
+ const versions = versionLinks.map(l => l.text())
+
+ // 3.0.0 is latest but does NOT match the filter
+ expect(versions).not.toContain('3.0.0')
+ // 1.0.0 does match
+ expect(versions).toContain('1.0.0')
+ })
})
describe('error handling', () => {
diff --git a/test/nuxt/components/VersionSelector.spec.ts b/test/nuxt/components/VersionSelector.spec.ts
index df6d3a2a1d..bbc259bdd0 100644
--- a/test/nuxt/components/VersionSelector.spec.ts
+++ b/test/nuxt/components/VersionSelector.spec.ts
@@ -1,5 +1,6 @@
import { describe, expect, it, vi, beforeEach } from 'vitest'
import { mountSuspended } from '@nuxt/test-utils/runtime'
+import type { PackageVersionInfo } from '#shared/types/npm-registry'
import VersionSelector from '~/components/VersionSelector.vue'
// Mock the fetchAllPackageVersions function
@@ -424,6 +425,187 @@ describe('VersionSelector', () => {
{ timeout: 2000 },
)
})
+
+ it('toggles older version groups for a single-version tagged release', async () => {
+ mockFetchAllPackageVersions.mockResolvedValue([
+ { version: '1.0.0', time: '2024-01-15T12:00:00.000Z', hasProvenance: false },
+ { version: '0.9.0', time: '2024-01-10T12:00:00.000Z', hasProvenance: false },
+ ])
+
+ const component = await mountSuspended(VersionSelector, {
+ props: {
+ packageName: 'test-package',
+ currentVersion: '1.0.0',
+ versions: { '1.0.0': {}, '0.9.0': {} },
+ distTags: { latest: '1.0.0' },
+ urlPattern: '/package-docs/test-package/v/{version}',
+ },
+ })
+
+ const button = component.find('button[aria-haspopup="listbox"]')
+ await button.trigger('click')
+
+ const expandButton = component.find('[role="listbox"] button[aria-expanded="false"]')
+ await expandButton.trigger('click')
+
+ await vi.waitFor(() => {
+ expect(mockFetchAllPackageVersions).toHaveBeenCalledWith('test-package')
+ })
+
+ await vi.waitFor(() => {
+ expect(component.find('[role="listbox"]').text()).toContain('0.9')
+ const expandedButton = component.find('[role="listbox"] button[aria-expanded="true"]')
+ expect(expandedButton.exists()).toBe(true)
+ })
+
+ const expandedButton = component.find('[role="listbox"] button[aria-expanded="true"]')
+ await expandedButton.trigger('click')
+
+ await vi.waitFor(() => {
+ expect(component.find('[role="listbox"]').text()).not.toContain('0.9')
+ const collapsedButton = component.find('[role="listbox"] button[aria-expanded="false"]')
+ expect(collapsedButton.exists()).toBe(true)
+ })
+ })
+
+ it('does not reveal unrelated older groups when expanding a tagged row with nested versions', async () => {
+ mockFetchAllPackageVersions.mockResolvedValue([
+ { version: '1.2.0', time: '2024-01-15T12:00:00.000Z', hasProvenance: false },
+ { version: '1.1.0', time: '2024-01-12T12:00:00.000Z', hasProvenance: false },
+ { version: '1.0.0', time: '2024-01-10T12:00:00.000Z', hasProvenance: false },
+ { version: '0.9.0', time: '2024-01-08T12:00:00.000Z', hasProvenance: false },
+ ])
+
+ const component = await mountSuspended(VersionSelector, {
+ props: {
+ packageName: 'test-package',
+ currentVersion: '1.2.0',
+ versions: { '1.2.0': {}, '1.1.0': {}, '1.0.0': {}, '0.9.0': {} },
+ distTags: { latest: '1.2.0' },
+ urlPattern: '/package-docs/test-package/v/{version}',
+ },
+ })
+
+ const trigger = component.find('button[aria-haspopup="listbox"]')
+ await trigger.trigger('click')
+
+ const expandButton = component.find('[role="listbox"] button[aria-expanded="false"]')
+ await expandButton.trigger('click')
+
+ await vi.waitFor(() => {
+ expect(mockFetchAllPackageVersions).toHaveBeenCalledWith('test-package')
+ })
+
+ await vi.waitFor(() => {
+ const listboxText = component.find('[role="listbox"]').text()
+ expect(listboxText).toContain('1.1.0')
+ expect(listboxText).toContain('1.0.0')
+ expect(listboxText).not.toContain('0.9')
+ })
+
+ const expandedButton = component.find('[role="listbox"] button[aria-expanded="true"]')
+ await expandedButton.trigger('click')
+
+ await vi.waitFor(() => {
+ const listboxText = component.find('[role="listbox"]').text()
+ expect(listboxText).not.toContain('1.1.0')
+ expect(listboxText).not.toContain('1.0.0')
+ expect(listboxText).not.toContain('0.9')
+ })
+ })
+
+ it('collapses additional version groups with ArrowLeft when showAllGroups is open', async () => {
+ mockFetchAllPackageVersions.mockResolvedValue([
+ { version: '1.0.0', time: '2024-01-15T12:00:00.000Z', hasProvenance: false },
+ { version: '0.9.0', time: '2024-01-10T12:00:00.000Z', hasProvenance: false },
+ ])
+
+ const component = await mountSuspended(VersionSelector, {
+ props: {
+ packageName: 'test-package',
+ currentVersion: '1.0.0',
+ versions: { '1.0.0': {}, '0.9.0': {} },
+ distTags: { latest: '1.0.0' },
+ urlPattern: '/package-docs/test-package/v/{version}',
+ },
+ })
+
+ const trigger = component.find('button[aria-haspopup="listbox"]')
+ await trigger.trigger('click')
+
+ await component.find('[role="listbox"] button[aria-expanded="false"]').trigger('click')
+
+ await vi.waitFor(() => {
+ expect(component.find('[role="listbox"]').text()).toContain('0.9')
+ })
+
+ const listbox = component.find('[role="listbox"]')
+ await listbox.trigger('keydown', { key: 'ArrowLeft' })
+
+ await vi.waitFor(() => {
+ expect(listbox.text()).not.toContain('0.9')
+ })
+ })
+
+ it('resets showAllGroups when dist-tags props change after loading', async () => {
+ mockFetchAllPackageVersions.mockResolvedValue([
+ { version: '1.0.0', time: '2024-01-15T12:00:00.000Z', hasProvenance: false },
+ { version: '0.9.0', time: '2024-01-10T12:00:00.000Z', hasProvenance: false },
+ ])
+
+ const component = await mountSuspended(VersionSelector, {
+ props: {
+ packageName: 'test-package',
+ currentVersion: '1.0.0',
+ versions: { '1.0.0': {}, '0.9.0': {} },
+ distTags: { latest: '1.0.0' },
+ urlPattern: '/package-docs/test-package/v/{version}',
+ },
+ })
+
+ const trigger = component.find('button[aria-haspopup="listbox"]')
+ await trigger.trigger('click')
+ await component.find('[role="listbox"] button[aria-expanded="false"]').trigger('click')
+
+ await vi.waitFor(() => {
+ expect(component.find('[role="listbox"]').text()).toContain('0.9')
+ })
+
+ await component.setProps({ distTags: { latest: '1.0.0' } })
+
+ await vi.waitFor(() => {
+ expect(component.find('[role="listbox"]').text()).not.toContain('0.9')
+ })
+ })
+
+ it('ignores expand clicks while a group is already loading', async () => {
+ let finishLoad: (value: PackageVersionInfo[]) => void
+ const loadPromise = new Promise(resolve => {
+ finishLoad = resolve
+ })
+ mockFetchAllPackageVersions.mockReturnValue(loadPromise)
+
+ const component = await mountSuspended(VersionSelector, {
+ props: {
+ packageName: 'test-package',
+ currentVersion: '1.0.0',
+ versions: { '1.0.0': {} },
+ distTags: { latest: '1.0.0' },
+ urlPattern: '/package-docs/test-package/v/{version}',
+ },
+ })
+
+ const trigger = component.find('button[aria-haspopup="listbox"]')
+ await trigger.trigger('click')
+
+ const expandButton = component.find('[role="listbox"] button[aria-expanded]')
+ await expandButton.trigger('click')
+ await expandButton.trigger('click')
+
+ expect(mockFetchAllPackageVersions).toHaveBeenCalledTimes(1)
+
+ finishLoad!([{ version: '1.0.0', time: '2024-01-15T12:00:00.000Z', hasProvenance: false }])
+ })
})
describe('0.x version grouping', () => {
@@ -459,12 +641,10 @@ describe('VersionSelector', () => {
// Wait for versions to load
await vi.waitFor(
() => {
- // 0.9.x versions should NOT be under the 0.10.x group
- // They should be in a separate group
const text = component.text()
- // The component should have separate groups for 0.10 and 0.9
expect(text).toContain('0.10')
- expect(text).toContain('0.9')
+ expect(text).toContain('0.10.0')
+ expect(text).not.toContain('0.9')
},
{ timeout: 2000 },
)
@@ -519,11 +699,8 @@ describe('VersionSelector', () => {
describe('loading states', () => {
it('shows loading spinner when fetching versions', async () => {
- let resolvePromise: (value: unknown[]) => void
- const loadingPromise = new Promise(resolve => {
- resolvePromise = resolve
- })
- mockFetchAllPackageVersions.mockReturnValue(loadingPromise)
+ const { promise, resolve } = Promise.withResolvers()
+ mockFetchAllPackageVersions.mockReturnValue(promise)
const component = await mountSuspended(VersionSelector, {
props: {
@@ -549,7 +726,7 @@ describe('VersionSelector', () => {
})
// Resolve the promise to clean up
- resolvePromise!([])
+ resolve([])
})
})
diff --git a/test/nuxt/composables/use-install-size-diff.spec.ts b/test/nuxt/composables/use-install-size-diff.spec.ts
index 100ca89f93..3faba4232e 100644
--- a/test/nuxt/composables/use-install-size-diff.spec.ts
+++ b/test/nuxt/composables/use-install-size-diff.spec.ts
@@ -84,7 +84,7 @@ describe('useInstallSizeDiff', () => {
expect(comparisonVersion.value).toBe('1.0.0')
})
- it('uses the latest dist-tag for a prerelease version', () => {
+ it('compares a prerelease against the previous stable version', () => {
const pkg = createPackage(
'test',
{ '1.0.0': '2020-01-01', '2.0.0-beta.1': '2021-01-01' },
@@ -95,20 +95,28 @@ describe('useInstallSizeDiff', () => {
expect(comparisonVersion.value).toBe('1.0.0')
})
- it('returns null when the prerelease version is already latest', () => {
+ it('compares an old prerelease against the stable version before it, not latest', () => {
const pkg = createPackage(
'test',
- { '2.0.0-beta.1': '2021-01-01' },
- { latest: '2.0.0-beta.1' },
+ {
+ '1.16.0': '2024-01-01',
+ '1.17.0-alpha.0': '2024-02-01',
+ '1.18.0': '2024-03-01',
+ '1.50.0': '2025-01-01',
+ },
+ { latest: '1.50.0' },
)
- const { comparisonVersion } = useInstallSizeDiff('test', '2.0.0-beta.1', pkg, null)
- expect(comparisonVersion.value).toBeNull()
+ const { comparisonVersion } = useInstallSizeDiff('test', '1.17.0-alpha.0', pkg, null)
+ expect(comparisonVersion.value).toBe('1.16.0')
})
- it('returns null for a prerelease when there is no latest tag', () => {
- const pkg = createPackage('test', { '2.0.0-beta.1': '2021-01-01' }, {})
- pkg['dist-tags'] = {}
+ it('returns null for a prerelease with no prior stable versions', () => {
+ const pkg = createPackage(
+ 'test',
+ { '2.0.0-beta.1': '2021-01-01' },
+ { latest: '2.0.0-beta.1' },
+ )
const { comparisonVersion } = useInstallSizeDiff('test', '2.0.0-beta.1', pkg, null)
expect(comparisonVersion.value).toBeNull()
diff --git a/test/nuxt/pages/PackageVersionsPage.spec.ts b/test/nuxt/pages/PackageVersionsPage.spec.ts
index 9e9e1c4a13..d83c6243d8 100644
--- a/test/nuxt/pages/PackageVersionsPage.spec.ts
+++ b/test/nuxt/pages/PackageVersionsPage.spec.ts
@@ -16,7 +16,7 @@ vi.mock('fast-npm-meta', async importOriginal => {
}
})
-// Phase 2: full metadata (loaded on first group expand)
+// Phase 2: full metadata (fired automatically after phase 1 completes)
const mockFetchAllPackageVersions = vi.fn()
vi.mock('~/utils/npm/api', async importOriginal => {
const actual = await importOriginal()
@@ -52,6 +52,7 @@ describe('package versions page', () => {
beforeEach(() => {
mockGetVersions.mockReset()
mockFetchAllPackageVersions.mockReset()
+ mockFetchAllPackageVersions.mockResolvedValue([])
clearNuxtData()
})
@@ -140,23 +141,16 @@ describe('package versions page', () => {
})
})
- it('only fetches full metadata once across multiple group expansions', async () => {
+ it('fetches full metadata automatically after phase 1 completes, exactly once', async () => {
mockGetVersions.mockResolvedValue(makeVersionData(['2.0.0', '1.0.0'], { latest: '2.0.0' }))
mockFetchAllPackageVersions.mockResolvedValue([
{ version: '2.0.0', time: '2024-01-15T00:00:00.000Z', hasProvenance: false },
{ version: '1.0.0', time: '2024-01-10T00:00:00.000Z', hasProvenance: false },
])
- const component = await mountPage()
- await vi.waitFor(() => {
- expect(component.findAll('button[aria-expanded="false"]').length).toBeGreaterThanOrEqual(2)
- })
- const [first, second] = component.findAll('button[aria-expanded="false"]')
- await first!.trigger('click')
- await vi.waitFor(() => expect(mockFetchAllPackageVersions).toHaveBeenCalledTimes(1))
+ await mountPage()
- await second!.trigger('click')
- expect(mockFetchAllPackageVersions).toHaveBeenCalledTimes(1)
+ await vi.waitFor(() => expect(mockFetchAllPackageVersions).toHaveBeenCalledTimes(1))
})
})
@@ -173,7 +167,7 @@ describe('package versions page', () => {
expect(component.text()).toContain('3.x')
})
- const input = component.find('input[placeholder="Filter versions\u2026"]')
+ const input = component.find('input[autocomplete="off"]')
await input.setValue('1.0')
await vi.waitFor(() => {
diff --git a/test/unit/a11y-component-coverage.spec.ts b/test/unit/a11y-component-coverage.spec.ts
index a73b58dd6d..6100cc04dc 100644
--- a/test/unit/a11y-component-coverage.spec.ts
+++ b/test/unit/a11y-component-coverage.spec.ts
@@ -11,7 +11,6 @@
import fs from 'node:fs'
import path from 'node:path'
import { assert, describe, it } from 'vitest'
-import { fileURLToPath } from 'node:url'
/**
* Components explicitly skipped from a11y testing with reasons.
@@ -152,9 +151,9 @@ function getTestedComponents(
}
describe('a11y component test coverage', () => {
- const componentsDir = fileURLToPath(new URL('../../app/components', import.meta.url))
- const componentsDtsPath = fileURLToPath(new URL('../../.nuxt/components.d.ts', import.meta.url))
- const testFilePath = fileURLToPath(new URL('../nuxt/a11y.spec.ts', import.meta.url))
+ const componentsDir = path.join(import.meta.dirname, '../../app/components')
+ const componentsDtsPath = path.join(import.meta.dirname, '../../.nuxt/components.d.ts')
+ const testFilePath = path.join(import.meta.dirname, '../nuxt/a11y.spec.ts')
it('should have accessibility tests for all components (or be explicitly skipped)', () => {
// Get all Vue components
diff --git a/test/unit/app/utils/charts.spec.ts b/test/unit/app/utils/charts.spec.ts
index 6a82d7e82a..72c3d6c998 100644
--- a/test/unit/app/utils/charts.spec.ts
+++ b/test/unit/app/utils/charts.spec.ts
@@ -15,9 +15,6 @@ import {
sanitise,
insertLineBreaks,
applyEllipsis,
- createSeedNumber,
- createSeededSvgPattern,
- createChartPatternSlotMarkup,
type TrendLineConfig,
type TrendLineDataset,
type VersionsBarConfig,
@@ -1402,252 +1399,3 @@ describe('applyEllipsis', () => {
expect(applyEllipsis('you need to touch grass', 13)).toBe('you need to t...')
})
})
-
-describe('createSeedNumber', () => {
- it('returns the same hash for the same input', () => {
- expect(createSeedNumber('react')).toBe(createSeedNumber('react'))
- expect(createSeedNumber('vue')).toBe(createSeedNumber('vue'))
- })
-
- it('returns different hashes for different inputs', () => {
- expect(createSeedNumber('react')).not.toBe(createSeedNumber('vue'))
- expect(createSeedNumber('svelte')).not.toBe(createSeedNumber('solid'))
- })
-
- it('returns a 32 bit unsigned integer', () => {
- const result = createSeedNumber('react')
- expect(Number.isInteger(result)).toBe(true)
- expect(result).toBeGreaterThanOrEqual(0)
- expect(result).toBeLessThanOrEqual(4294967295)
- })
-
- it('handles an empty string', () => {
- const result = createSeedNumber('')
- expect(Number.isInteger(result)).toBe(true)
- expect(result).toBeGreaterThanOrEqual(0)
- expect(result).toBeLessThanOrEqual(4294967295)
- })
-
- it('is case sensitive', () => {
- expect(createSeedNumber('react')).not.toBe(createSeedNumber('React'))
- })
-})
-
-describe('createSeededSvgPattern', () => {
- it('returns deterministic output for the same seed', () => {
- const first = createSeededSvgPattern('react')
- const second = createSeededSvgPattern('react')
- expect(first).toEqual(second)
- })
-
- it('returns different output for different seeds', () => {
- const first = createSeededSvgPattern('react')
- const second = createSeededSvgPattern('vue')
- expect(second).not.toEqual(first)
- })
-
- it('returns a valid pattern object shape', () => {
- const result = createSeededSvgPattern('react')
- expect(typeof result.width).toBe('number')
- expect(typeof result.height).toBe('number')
- expect(typeof result.rotation).toBe('number')
- expect(typeof result.patternType).toBe('string')
- expect(typeof result.contentMarkup).toBe('string')
- })
-
- it('uses default options when none are provided', () => {
- const result = createSeededSvgPattern('react')
- expect(result.width).toBeGreaterThanOrEqual(8)
- expect(result.width).toBeLessThanOrEqual(20)
- expect(result.height).toBe(result.width)
- expect(result.contentMarkup.length).toBeGreaterThan(0)
- })
-
- it('uses the provided foreground and background colors', () => {
- const result = createSeededSvgPattern('react', {
- foregroundColor: '#ff0000',
- backgroundColor: '#00ff00',
- })
- expect(result.contentMarkup).toContain('#ff0000')
- expect(result.contentMarkup).toContain('#00ff00')
- expect(result.contentMarkup).toContain(' {
- const result = createSeededSvgPattern('react', {
- backgroundColor: 'transparent',
- })
- expect(result.contentMarkup).not.toContain(' {
- const result = createSeededSvgPattern('react', {
- minimumSize: 10,
- maximumSize: 16,
- })
- expect(result.width).toBeGreaterThanOrEqual(10)
- expect(result.width).toBeLessThanOrEqual(16)
- expect(result.height).toBe(result.width)
- })
-
- it('always returns one of the supported pattern types', () => {
- const allowedPatternTypes = [
- 'diagonalLines',
- 'verticalLines',
- 'horizontalLines',
- 'crosshatch',
- 'dots',
- 'grid',
- 'zigzag',
- ]
- const result = createSeededSvgPattern('react')
- expect(allowedPatternTypes).toContain(result.patternType)
- })
-
- it('returns a supported rotation value', () => {
- const allowedRotations = [0, 15, 30, 45, 60, 75, 90, 120, 135]
- const result = createSeededSvgPattern('react')
- expect(allowedRotations).toContain(result.rotation)
- })
-
- it('returns svg markup matching the selected pattern type', () => {
- const seeds = [
- 'react',
- 'vue',
- 'svelte',
- 'solid',
- 'angular',
- 'ember',
- 'preact',
- 'lit',
- 'alpine',
- 'nuxt',
- 'next',
- 'astro',
- 'qwik',
- 'backbone',
- ]
-
- const expectedTagByPatternType: Record<
- ReturnType['patternType'],
- string
- > = {
- diagonalLines: ' {
- const result = createSeededSvgPattern(12345)
- expect(typeof result.width).toBe('number')
- expect(typeof result.contentMarkup).toBe('string')
- expect(result.contentMarkup.length).toBeGreaterThan(0)
- })
-
- it('returns deterministic output for equivalent numeric and string seeds', () => {
- const numericSeedResult = createSeededSvgPattern(12345)
- const stringSeedResult = createSeededSvgPattern('12345')
- expect(numericSeedResult).toEqual(stringSeedResult)
- })
-})
-
-describe('createChartPatternSlotMarkup', () => {
- it('returns a pattern element with the provided id', () => {
- const result = createChartPatternSlotMarkup({
- id: 'pattern-1',
- seed: 7,
- color: '#ff0000',
- foregroundColor: '#ffffff',
- fallbackColor: 'transparent',
- maxSize: 24,
- minSize: 16,
- })
-
- expect(result).toContain('')
- })
-
- it('includes width, height, rotation, and content markup from the generated pattern', () => {
- const generatedPattern = createSeededSvgPattern(1, {
- foregroundColor: '#000',
- backgroundColor: 'transparent',
- minimumSize: 16,
- maximumSize: 24,
- })
-
- const result = createChartPatternSlotMarkup({
- id: 'pattern-1',
- seed: 1,
- foregroundColor: '#000',
- fallbackColor: 'transparent',
- maxSize: 24,
- minSize: 16,
- })
-
- expect(result).toContain(`width="${generatedPattern.width}"`)
- expect(result).toContain(`height="${generatedPattern.height}"`)
- expect(result).toContain(`patternTransform="rotate(${generatedPattern.rotation})"`)
- expect(result).toContain(generatedPattern.contentMarkup)
- })
-
- it('is deterministic for the same inputs', () => {
- const first = createChartPatternSlotMarkup({
- id: 'pattern-stable',
- seed: 'nuxt',
- color: '#00ff00',
- foregroundColor: '#000000',
- fallbackColor: 'transparent',
- maxSize: 40,
- minSize: 10,
- })
-
- const second = createChartPatternSlotMarkup({
- id: 'pattern-stable',
- seed: 'nuxt',
- color: '#00ff00',
- foregroundColor: '#000000',
- fallbackColor: 'transparent',
- maxSize: 40,
- minSize: 10,
- })
-
- expect(first).toBe(second)
- })
-
- it('changes when the id changes', () => {
- const first = createChartPatternSlotMarkup({
- id: 'pattern-a',
- seed: 1,
- color: '#00ff00',
- foregroundColor: '#000000',
- fallbackColor: 'transparent',
- maxSize: 40,
- minSize: 10,
- })
-
- const second = createChartPatternSlotMarkup({
- id: 'pattern-b',
- seed: 2,
- color: '#00ff00',
- foregroundColor: '#000000',
- fallbackColor: 'transparent',
- maxSize: 40,
- minSize: 10,
- })
-
- expect(first).not.toBe(second)
- })
-})
diff --git a/test/unit/app/utils/install-command.spec.ts b/test/unit/app/utils/install-command.spec.ts
index 8dd5c1bbab..9d69be4071 100644
--- a/test/unit/app/utils/install-command.spec.ts
+++ b/test/unit/app/utils/install-command.spec.ts
@@ -381,7 +381,7 @@ describe('install command generation', () => {
['pnpm', ['pnpm', 'create', 'vite']],
['yarn', ['yarn', 'create', 'vite']],
['bun', ['bun', 'create', 'vite']],
- ['deno', ['deno', 'run', 'vite']],
+ ['deno', ['deno', 'create', 'npm:vite']],
['vlt', ['vlx', 'vite']],
] as const)('%s โ %s', (pm, expected) => {
expect(
diff --git a/test/unit/modules/security-headers.spec.ts b/test/unit/modules/security-headers.spec.ts
new file mode 100644
index 0000000000..2ba961c1fe
--- /dev/null
+++ b/test/unit/modules/security-headers.spec.ts
@@ -0,0 +1,116 @@
+import { beforeEach, describe, expect, it, vi } from 'vitest'
+
+const { useNuxt } = vi.hoisted(() => ({
+ useNuxt: vi.fn(),
+}))
+
+vi.mock('nuxt/kit', () => ({
+ defineNuxtModule: (module: T) => module,
+ useNuxt,
+}))
+
+import securityHeadersModule from '../../../modules/security-headers'
+
+type RouteRule = {
+ headers?: Record
+ redirect?: string
+}
+
+type MockNuxt = {
+ options: {
+ app: {
+ head?: {
+ meta?: Array>
+ }
+ }
+ dev: boolean
+ devtools?: boolean | { enabled?: boolean }
+ routeRules: Record
+ }
+}
+
+function createNuxt(options: Partial = {}): MockNuxt {
+ return {
+ options: {
+ app: {},
+ dev: false,
+ devtools: false,
+ routeRules: {},
+ ...options,
+ },
+ }
+}
+
+function getCsp(nuxt: MockNuxt) {
+ return nuxt.options.app.head?.meta?.find(meta => meta['http-equiv'] === 'Content-Security-Policy')
+ ?.content
+}
+
+describe('security headers module', () => {
+ beforeEach(() => {
+ delete process.env.TEST
+ useNuxt.mockReset()
+ })
+
+ it('keeps security headers and only relaxes devtools-specific bits in dev', () => {
+ const nuxt = createNuxt({
+ dev: true,
+ devtools: { enabled: true },
+ routeRules: {
+ '/**': {
+ headers: {
+ 'Permissions-Policy': 'camera=()',
+ },
+ },
+ '/__nuxt_devtools__/**': {
+ headers: {
+ 'Cache-Control': 'no-store',
+ },
+ redirect: '/devtools',
+ },
+ },
+ })
+
+ useNuxt.mockReturnValue(nuxt)
+ securityHeadersModule.setup()
+
+ const csp = getCsp(nuxt)
+
+ expect(csp).toContain('ws://localhost:*')
+ expect(csp).toContain("frame-src https://bsky.app https://pdsmoover.com 'self'")
+ expect(nuxt.options.routeRules['/**']?.headers).toEqual(
+ expect.objectContaining({
+ 'Permissions-Policy': 'camera=()',
+ 'Referrer-Policy': 'strict-origin-when-cross-origin',
+ 'X-Content-Type-Options': 'nosniff',
+ 'X-Frame-Options': 'DENY',
+ }),
+ )
+ expect(nuxt.options.routeRules['/__nuxt_devtools__/**']).toEqual({
+ headers: {
+ 'Cache-Control': 'no-store',
+ 'Permissions-Policy': 'camera=()',
+ 'Referrer-Policy': 'strict-origin-when-cross-origin',
+ 'X-Content-Type-Options': 'nosniff',
+ 'X-Frame-Options': 'SAMEORIGIN',
+ },
+ redirect: '/devtools',
+ })
+ })
+
+ it('does not apply devtools relaxations when devtools are disabled via object config', () => {
+ const nuxt = createNuxt({
+ dev: true,
+ devtools: { enabled: false },
+ })
+
+ useNuxt.mockReturnValue(nuxt)
+ securityHeadersModule.setup()
+
+ const csp = getCsp(nuxt)
+
+ expect(csp).not.toContain('ws://localhost:*')
+ expect(csp).not.toContain("frame-src https://bsky.app https://pdsmoover.com 'self'")
+ expect(nuxt.options.routeRules['/__nuxt_devtools__/**']).toBeUndefined()
+ })
+})
diff --git a/test/unit/server/utils/atproto/lock.spec.ts b/test/unit/server/utils/atproto/lock.spec.ts
index adf018e855..0cf6abb037 100644
--- a/test/unit/server/utils/atproto/lock.spec.ts
+++ b/test/unit/server/utils/atproto/lock.spec.ts
@@ -1,3 +1,4 @@
+import { setTimeout } from 'node:timers/promises'
import { describe, expect, it, vi, beforeEach } from 'vitest'
const mockRedisSet = vi.fn()
@@ -145,7 +146,7 @@ describe('lock', () => {
const lock = getUpstashLock()
const result = await lock('async-key', async () => {
- await new Promise(resolve => setTimeout(resolve, 10))
+ await setTimeout(10)
return 'async-result'
})
diff --git a/test/unit/server/utils/readme.spec.ts b/test/unit/server/utils/readme.spec.ts
index 3269f01850..5d85902158 100644
--- a/test/unit/server/utils/readme.spec.ts
+++ b/test/unit/server/utils/readme.spec.ts
@@ -293,6 +293,13 @@ describe('Markdown File URL Resolution', () => {
expect(result.html).toContain('href="#user-content-installation"')
})
+
+ it('normalizes mixed-case heading fragments to lowercase slugs', async () => {
+ const markdown = `[Associations section](#Associations)`
+ const result = await renderReadmeHtml(markdown, 'test-pkg')
+
+ expect(result.html).toContain('href="#user-content-associations"')
+ })
})
describe('different git providers', () => {
diff --git a/test/unit/shared/utils/async.spec.ts b/test/unit/shared/utils/async.spec.ts
index 93dd1451fa..a0f7271cbe 100644
--- a/test/unit/shared/utils/async.spec.ts
+++ b/test/unit/shared/utils/async.spec.ts
@@ -1,3 +1,4 @@
+import { setTimeout } from 'node:timers/promises'
import { describe, expect, it, vi } from 'vitest'
import * as fc from 'fast-check'
import { mapWithConcurrency } from '#shared/utils/async'
@@ -21,7 +22,7 @@ describe('mapWithConcurrency', () => {
async () => {
concurrent++
maxConcurrent = Math.max(maxConcurrent, concurrent)
- await new Promise(resolve => setTimeout(resolve, 10))
+ await setTimeout(10)
concurrent--
},
3,
@@ -66,7 +67,7 @@ describe('mapWithConcurrency', () => {
await mapWithConcurrency(items, async () => {
concurrent++
maxConcurrent = Math.max(maxConcurrent, concurrent)
- await new Promise(resolve => setTimeout(resolve, 5))
+ await setTimeout(5)
concurrent--
})
@@ -84,7 +85,7 @@ describe('mapWithConcurrency', () => {
async () => {
concurrent++
maxConcurrent = Math.max(maxConcurrent, concurrent)
- await new Promise(resolve => setTimeout(resolve, 10))
+ await setTimeout(10)
concurrent--
},
10,
diff --git a/uno.config.ts b/uno.config.ts
index fae3f45785..1b9e92b7f0 100644
--- a/uno.config.ts
+++ b/uno.config.ts
@@ -6,9 +6,9 @@ import {
transformerDirectives,
transformerVariantGroup,
} from 'unocss'
-import type { Theme } from '@unocss/preset-wind4/theme'
import { presetRtl } from './uno-preset-rtl'
import { presetA11y } from './uno-preset-a11y'
+import { theme } from './uno.theme'
const customIcons = {
'agent-skills':
@@ -40,106 +40,12 @@ export default defineConfig({
...(process.env.CI ? [] : [presetRtl(), presetA11y()]),
].filter(Boolean),
transformers: [transformerDirectives(), transformerVariantGroup()],
- theme: {
- spacing: { DEFAULT: '4px' },
- font: {
- mono: "'Geist Mono', monospace",
- sans: "'Geist', system-ui, -apple-system, sans-serif",
- },
- text: {
- '2xs': { fontSize: '0.6875rem' }, // 11px
- '3xs': { fontSize: '0.625rem' }, // 10px
- '4xs': { fontSize: '0.5625rem' }, // 9px
- '5xs': { fontSize: '0.5rem' }, // 8px
- },
- colors: {
- // Minimal black & white palette with subtle grays
- bg: {
- DEFAULT: 'var(--bg)',
- subtle: 'var(--bg-subtle)',
- muted: 'var(--bg-muted)',
- elevated: 'var(--bg-elevated)',
- },
- fg: {
- DEFAULT: 'var(--fg)',
- muted: 'var(--fg-muted)',
- subtle: 'var(--fg-subtle)',
- },
- border: {
- DEFAULT: 'var(--border)',
- subtle: 'var(--border-subtle)',
- hover: 'var(--border-hover)',
- },
- accent: {
- DEFAULT: 'var(--accent)',
- fallback: 'var(--accent-muted)',
- },
- // Syntax highlighting colors (inspired by GitHub Dark)
- syntax: {
- fn: 'var(--syntax-fn)',
- str: 'var(--syntax-str)',
- kw: 'var(--syntax-kw)',
- comment: 'var(--syntax-comment)',
- },
- badge: {
- orange: 'var(--badge-orange)',
- yellow: 'var(--badge-yellow)',
- green: 'var(--badge-green)',
- cyan: 'var(--badge-cyan)',
- blue: 'var(--badge-blue)',
- indigo: 'var(--badge-indigo)',
- purple: 'var(--badge-purple)',
- pink: 'var(--badge-pink)',
- },
- // Playground provider brand colors
- provider: {
- stackblitz: '#1389FD',
- codesandbox: '#FFCC00',
- codepen: '#47CF73',
- replit: '#F26207',
- gitpod: '#FFAE33',
- vue: '#4FC08D',
- nuxt: '#00DC82',
- vite: '#646CFF',
- jsfiddle: '#0084FF',
- typescript: '#3178C6',
- solid: '#2C4F7C',
- svelte: '#FF3E00',
- tailwind: '#06B6D4',
- storybook: '#FF4785',
- marko: '#CC0067',
- },
- },
- animation: {
- keyframes: {
- 'skeleton-pulse': '{0%, 100% { opacity: 0.4 } 50% { opacity: 0.7 }}',
- 'fade-in': '{from { opacity: 0 } to { opacity: 1 }}',
- 'slide-up':
- '{from { opacity: 0; transform: translateY(8px) } to { opacity: 1; transform: translateY(0) }}',
- 'scale-in':
- '{from { opacity: 0; transform: scale(0.95) } to { opacity: 1; transform: scale(1) }}',
- },
- durations: {
- 'skeleton-pulse': '2s',
- 'fade-in': '0.3s',
- 'slide-up': '0.4s',
- 'scale-in': '0.2s',
- },
- timingFns: {
- 'skeleton-pulse': 'ease-in-out',
- 'fade-in': 'ease-out',
- 'slide-up': 'cubic-bezier(0.22, 1, 0.36, 1)',
- 'scale-in': 'cubic-bezier(0.22, 1, 0.36, 1)',
- },
- counts: {
- 'skeleton-pulse': 'infinite',
- },
- },
- } satisfies Theme,
+ theme,
shortcuts: [
// Layout
['container', 'max-w-6xl mx-auto px-4 sm:px-6'],
['container-sm', 'max-w-5xl mx-auto px-4 sm:px-6'],
+ ['flex-split', 'flex items-center justify-between'],
// Focus states - subtle but accessible
['focus-ring', 'outline-none focus-visible:(ring-2 ring-fg/50 ring-offset-2)'],
diff --git a/uno.theme.ts b/uno.theme.ts
new file mode 100644
index 0000000000..f0325dc810
--- /dev/null
+++ b/uno.theme.ts
@@ -0,0 +1,98 @@
+import type { Theme } from '@unocss/preset-wind4/theme'
+
+export const theme = {
+ spacing: { DEFAULT: '4px' },
+ font: {
+ mono: "'Geist Mono', 'IBM Plex Sans Arabic', monospace",
+ sans: "'Geist', 'IBM Plex Sans Arabic', system-ui, -apple-system, sans-serif",
+ },
+ text: {
+ '2xs': { fontSize: '0.6875rem' }, // 11px
+ '3xs': { fontSize: '0.625rem' }, // 10px
+ '4xs': { fontSize: '0.5625rem' }, // 9px
+ '5xs': { fontSize: '0.5rem' }, // 8px
+ },
+ colors: {
+ // Minimal black & white palette with subtle grays
+ bg: {
+ DEFAULT: 'var(--bg)',
+ subtle: 'var(--bg-subtle)',
+ muted: 'var(--bg-muted)',
+ elevated: 'var(--bg-elevated)',
+ },
+ fg: {
+ DEFAULT: 'var(--fg)',
+ muted: 'var(--fg-muted)',
+ subtle: 'var(--fg-subtle)',
+ },
+ border: {
+ DEFAULT: 'var(--border)',
+ subtle: 'var(--border-subtle)',
+ hover: 'var(--border-hover)',
+ },
+ accent: {
+ DEFAULT: 'var(--accent)',
+ fallback: 'var(--accent-muted)',
+ },
+ // Syntax highlighting colors (inspired by GitHub Dark)
+ syntax: {
+ fn: 'var(--syntax-fn)',
+ str: 'var(--syntax-str)',
+ kw: 'var(--syntax-kw)',
+ comment: 'var(--syntax-comment)',
+ },
+ badge: {
+ orange: 'var(--badge-orange)',
+ yellow: 'var(--badge-yellow)',
+ green: 'var(--badge-green)',
+ cyan: 'var(--badge-cyan)',
+ blue: 'var(--badge-blue)',
+ indigo: 'var(--badge-indigo)',
+ purple: 'var(--badge-purple)',
+ pink: 'var(--badge-pink)',
+ },
+ // Playground provider brand colors
+ provider: {
+ stackblitz: '#1389FD',
+ codesandbox: '#FFCC00',
+ codepen: '#47CF73',
+ replit: '#F26207',
+ gitpod: '#FFAE33',
+ vue: '#4FC08D',
+ nuxt: '#00DC82',
+ vite: '#646CFF',
+ jsfiddle: '#0084FF',
+ typescript: '#3178C6',
+ solid: '#2C4F7C',
+ svelte: '#FF3E00',
+ tailwind: '#06B6D4',
+ storybook: '#FF4785',
+ marko: '#CC0067',
+ },
+ },
+ animation: {
+ keyframes: {
+ 'skeleton-pulse': '{0%, 100% { opacity: 0.4 } 50% { opacity: 0.7 }}',
+ 'fade-in': '{from { opacity: 0 } to { opacity: 1 }}',
+ 'slide-up':
+ '{from { opacity: 0; transform: translateY(8px) } to { opacity: 1; transform: translateY(0) }}',
+ 'scale-in':
+ '{from { opacity: 0; transform: scale(0.95) } to { opacity: 1; transform: scale(1) }}',
+ },
+ durations: {
+ 'skeleton-pulse': '2s',
+ 'fade-in': '0.3s',
+ 'slide-up': '0.4s',
+ 'scale-in': '0.2s',
+ },
+ timingFns: {
+ 'skeleton-pulse': 'ease-in-out',
+ 'fade-in': 'ease-out',
+ 'slide-up': 'cubic-bezier(0.22, 1, 0.36, 1)',
+ 'scale-in': 'cubic-bezier(0.22, 1, 0.36, 1)',
+ },
+ counts: {
+ 'skeleton-pulse': 'infinite',
+ },
+ },
+} satisfies Theme
diff --git a/vite.config.ts b/vite.config.ts
index 2f8ffcdfe7..e34f71b121 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,9 +1,8 @@
-import { fileURLToPath } from 'node:url'
import { defineConfig } from 'vite-plus'
import { defineVitestProject } from '@nuxt/test-utils/config'
import { playwright } from 'vite-plus/test/browser-playwright'
-const rootDir = fileURLToPath(new URL('.', import.meta.url))
+const rootDir = import.meta.dirname
export default defineConfig({
run: {
@@ -187,7 +186,7 @@ export default defineConfig({
environment: 'nuxt',
environmentOptions: {
nuxt: {
- rootDir: fileURLToPath(new URL('.', import.meta.url)),
+ rootDir,
overrides: {
vue: {
runtimeCompiler: true,