Merge branch 'develop'

This commit is contained in:
John McLear 2023-06-20 15:54:10 +01:00
commit a562d44d9b
195 changed files with 11863 additions and 6201 deletions

View File

@ -19,6 +19,7 @@ Dockerfile
.git/ORIG_HEAD
.git/packed-refs
.git/refs/remotes/
.git/rr-cache/
.gitignore
settings.json

View File

@ -1,5 +1,3 @@
IMPORTANT: Please disable plugins prior to posting a bug report. If you have a problem with a plugin please post on the plugin repository. Thanks!
---
name: Bug report
about: Create a report to help us improve
@ -9,6 +7,8 @@ assignees: ''
---
<!-- IMPORTANT: Please disable plugins prior to posting a bug report. If you have a problem with a plugin please post on the plugin repository. Thanks! -->
**Describe the bug**
A clear and concise description of what the bug is.

21
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,21 @@
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "npm"
directory: "/src"
schedule:
interval: "daily"
versioning-strategy: "increase"
- package-ecosystem: "npm"
directory: "/src/bin/doc"
schedule:
interval: "daily"
versioning-strategy: "increase"

24
.github/stale.yml vendored
View File

@ -1,24 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
- Bug
- Serious Bug
- Minor bug
- Black hole bug
- Special case Bug
- Upstream bug
- Feature Request
# Label to use when marking an issue as stale
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View File

@ -3,6 +3,9 @@ name: "Backend tests"
# any branch is useful for testing before a PR is submitted
on: [push, pull_request]
permissions:
contents: read
jobs:
withoutpluginsLinux:
# run on pushes to any branch
@ -15,11 +18,11 @@ jobs:
strategy:
fail-fast: false
matrix:
node: [12, 14, 16]
node: [14, 16, 18]
steps:
-
name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
-
uses: actions/setup-node@v3
with:
@ -52,11 +55,11 @@ jobs:
strategy:
fail-fast: false
matrix:
node: [12, 14, 16]
node: [14, 16, 18]
steps:
-
name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
-
uses: actions/setup-node@v3
with:
@ -117,11 +120,11 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
-
uses: actions/setup-node@v3
with:
node-version: 12
node-version: 14
cache: 'npm'
cache-dependency-path: |
src/package-lock.json
@ -150,11 +153,11 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
-
uses: actions/setup-node@v3
with:
node-version: 12
node-version: 14
cache: 'npm'
cache-dependency-path: |
src/package-lock.json

View File

@ -9,14 +9,21 @@ on:
schedule:
- cron: '0 13 * * 1'
permissions:
contents: read
jobs:
analyze:
permissions:
actions: read # for github/codeql-action/init to get workflow details
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/autobuild to send a status report
name: Analyze
runs-on: ubuntu-latest
steps:
-
name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
@ -28,10 +35,10 @@ jobs:
if: ${{ github.event_name == 'pull_request' }}
-
name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
-
name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@v2
-
name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2

20
.github/workflows/dependency-review.yml vendored Normal file
View File

@ -0,0 +1,20 @@
# Dependency Review Action
#
# This Action will scan dependency manifest files that change as part of a Pull Reqest, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging.
#
# Source repository: https://github.com/actions/dependency-review-action
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
name: 'Dependency Review'
on: [pull_request]
permissions:
contents: read
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
uses: actions/checkout@v3
- name: 'Dependency Review'
uses: actions/dependency-review-action@v1

View File

@ -8,19 +8,26 @@ on:
- 'v?[0-9]+.[0-9]+.[0-9]+'
env:
TEST_TAG: etherpad/etherpad:test
permissions:
contents: read
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Check out
uses: actions/checkout@v2
uses: actions/checkout@v3
-
name: Set up QEMU
if: github.event_name == 'push'
uses: docker/setup-qemu-action@v2
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
uses: docker/setup-buildx-action@v2
-
name: Build and export to Docker
uses: docker/build-push-action@v2
uses: docker/build-push-action@v4
with:
context: .
load: true
@ -39,16 +46,25 @@ jobs:
-
name: Test
run: |
docker run --rm -d -p 9001:9001 ${{ env.TEST_TAG }}
docker run --rm -d -p 9001:9001 --name test ${{ env.TEST_TAG }}
docker logs -f test &
./src/bin/installDeps.sh
sleep 3
while true; do
echo "Waiting for Docker container to start..."
status=$(docker container inspect -f '{{.State.Health.Status}}' test) || exit 1
case ${status} in
healthy) break;;
starting) sleep 2;;
*) printf %s\\n "unexpected status: ${status}" >&2; exit 1;;
esac
done
(cd src && npm run test-container)
git clean -dxf .
-
name: Docker meta
if: github.event_name == 'push'
id: meta
uses: docker/metadata-action@v3
uses: docker/metadata-action@v4
with:
images: etherpad/etherpad
tags: |
@ -59,16 +75,17 @@ jobs:
-
name: Log in to Docker Hub
if: github.event_name == 'push'
uses: docker/login-action@v1
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
if: github.event_name == 'push'
uses: docker/build-push-action@v2
uses: docker/build-push-action@v4
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@ -3,6 +3,9 @@ name: "Frontend admin tests powered by Sauce Labs"
on: [push]
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
withplugins:
name: with plugins
@ -11,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
node: [12, 14, 16]
node: [14, 16, 18]
steps:
-
@ -33,7 +36,7 @@ jobs:
printf %s\\n '::set-output name=tunnel_id::${{ github.run_id }}-${{ github.run_number }}-${{ github.job }}-node${{ matrix.node }}'
-
name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
-
uses: actions/setup-node@v3
with:

View File

@ -3,6 +3,9 @@ name: "Frontend tests powered by Sauce Labs"
on: [push]
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
withoutplugins:
name: without plugins
@ -27,11 +30,11 @@ jobs:
printf %s\\n '::set-output name=tunnel_id::${{ github.run_id }}-${{ github.run_number }}-${{ github.job }}'
-
name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
-
uses: actions/setup-node@v3
with:
node-version: 12
node-version: 14
cache: 'npm'
cache-dependency-path: |
src/package-lock.json
@ -91,11 +94,11 @@ jobs:
printf %s\\n '::set-output name=tunnel_id::${{ github.run_id }}-${{ github.run_number }}-${{ github.job }}'
-
name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
-
uses: actions/setup-node@v3
with:
node-version: 12
node-version: 14
cache: 'npm'
cache-dependency-path: |
src/package-lock.json

View File

@ -3,6 +3,9 @@ name: "Lint"
# any branch is useful for testing before a PR is submitted
on: [push, pull_request]
permissions:
contents: read
jobs:
lint-package-lock:
# run on pushes to any branch
@ -15,11 +18,11 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
-
uses: actions/setup-node@v3
with:
node-version: 12
node-version: 14
cache: 'npm'
cache-dependency-path: |
src/package-lock.json

View File

@ -3,6 +3,9 @@ name: "Loadtest"
# any branch is useful for testing before a PR is submitted
on: [push, pull_request]
permissions:
contents: read
jobs:
withoutplugins:
# run on pushes to any branch
@ -15,11 +18,11 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
-
uses: actions/setup-node@v3
with:
node-version: 12
node-version: 14
cache: 'npm'
cache-dependency-path: |
src/package-lock.json
@ -45,11 +48,11 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
-
uses: actions/setup-node@v3
with:
node-version: 12
node-version: 14
cache: 'npm'
cache-dependency-path: |
src/package-lock.json
@ -102,11 +105,11 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
-
uses: actions/setup-node@v3
with:
node-version: 12
node-version: 14
cache: 'npm'
cache-dependency-path: |
src/package-lock.json

View File

@ -3,6 +3,9 @@ name: "rate limit"
# any branch is useful for testing before a PR is submitted
on: [push, pull_request]
permissions:
contents: read
jobs:
ratelimit:
# run on pushes to any branch
@ -15,11 +18,11 @@ jobs:
steps:
-
name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
-
uses: actions/setup-node@v3
with:
node-version: 12
node-version: 14
cache: 'npm'
cache-dependency-path: |
src/package-lock.json

18
.github/workflows/stale.yml vendored Normal file
View File

@ -0,0 +1,18 @@
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '30 6 * * *'
permissions:
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v7
with:
close-issue-label: wontfix
close-pr-label: wontfix
days-before-close: -1
exempt-issue-labels: 'pinned,security,Bug,Serious Bug,Minor bug,Black hole bug,Special case Bug,Upstream bug,Feature Request'
exempt-pr-labels: 'pinned,security,Bug,Serious Bug,Minor bug,Black hole bug,Special case Bug,Upstream bug,Feature Request'

View File

@ -3,6 +3,9 @@ name: "Upgrade from latest release"
# any branch is useful for testing before a PR is submitted
on: [push, pull_request]
permissions:
contents: read
jobs:
withpluginsLinux:
# run on pushes to any branch
@ -15,11 +18,11 @@ jobs:
strategy:
fail-fast: false
matrix:
node: [12, 14, 16]
node: [14, 16, 18]
steps:
-
name: Check out latest release
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
ref: master
-
@ -64,7 +67,7 @@ jobs:
-
name: Run the backend tests
run: cd src && npm test
# Because actions/checkout@v2 is called with "ref: master" and without
# Because actions/checkout@v3 is called with "ref: master" and without
# "fetch-depth: 0", the local clone does not have the ${GITHUB_SHA}
# commit. Fetch ${GITHUB_REF} to get the ${GITHUB_SHA} commit. Note that a
# plain "git fetch" only fetches "normal" references (refs/heads/* and
@ -87,11 +90,10 @@ jobs:
run: cd src && npm test
-
name: Install Cypress
run: npm install cypress -g
run: cd src && npm install cypress
-
name: Run Etherpad & Test Frontend
run: |
node src/node/server.js &
curl --connect-timeout 10 --max-time 20 --retry 5 --retry-delay 10 --retry-max-time 60 --retry-connrefused http://127.0.0.1:9001/p/test
cd src/tests/frontend
cypress run --spec cypress/integration/test.js --config-file cypress/cypress.json
./src/node_modules/cypress/bin/cypress run --config-file src/tests/frontend/cypress/cypress.config.js

View File

@ -1,64 +0,0 @@
name: "Windows Installer"
# any branch is useful for testing before a PR is submitted
on: [push, pull_request]
jobs:
build:
# run on pushes to any branch
# run on PRs from external forks
if: |
(github.event_name != 'pull_request')
|| (github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id)
name: Build Zip & Exe
runs-on: windows-latest
steps:
-
uses: msys2/setup-msys2@v2
with:
path-type: inherit
install: >-
zip
-
name: Checkout repository
uses: actions/checkout@v2
-
uses: actions/setup-node@v3
with:
node-version: 12
cache: 'npm'
cache-dependency-path: |
src/package-lock.json
src/bin/doc/package-lock.json
-
name: Install all dependencies and symlink for ep_etherpad-lite
shell: msys2 {0}
run: src/bin/installDeps.sh
-
name: Run the backend tests
shell: msys2 {0}
run: cd src && npm test
-
name: Build the .zip
shell: msys2 {0}
run: src/bin/buildForWindows.sh
-
name: Extract the .zip into folder
run: 7z x etherpad-lite-win.zip -oetherpad-lite-new
-
name: Grab nsis config
run: git clone https://github.com/ether/etherpad_nsis.git
-
name: Create installer
uses: joncloud/makensis-action@v3.6
with:
script-file: 'etherpad_nsis/etherpad.nsi'
-
name: Check something..
run: ls etherpad_nsis
-
name: Archive production artifacts
uses: actions/upload-artifact@v2
with:
name: etherpad-server-windows.exe
path: etherpad_nsis/etherpad-server-windows.exe

View File

@ -1,16 +1,19 @@
name: "Windows Zip"
name: "Windows Build"
# any branch is useful for testing before a PR is submitted
on: [push, pull_request]
permissions:
contents: read
jobs:
build:
build-zip:
# run on pushes to any branch
# run on PRs from external forks
if: |
(github.event_name != 'pull_request')
|| (github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id)
name: Build
name: Build .zip
runs-on: windows-latest
steps:
-
@ -21,11 +24,11 @@ jobs:
zip
-
name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
-
uses: actions/setup-node@v3
with:
node-version: 12
node-version: 14
cache: 'npm'
cache-dependency-path: |
src/package-lock.json
@ -44,45 +47,79 @@ jobs:
run: src/bin/buildForWindows.sh
-
name: Archive production artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: etherpad-lite-win.zip
path: etherpad-lite-win.zip
name: etherpad-win.zip
path: etherpad-win.zip
deploy:
build-exe:
if: |
(github.event_name != 'pull_request')
|| (github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id)
name: Build .exe
needs: build-zip
runs-on: windows-latest
steps:
-
name: Checkout repository
uses: actions/checkout@v3
-
name: Download .zip
uses: actions/download-artifact@v3
with:
name: etherpad-win.zip
path: ..
-
name: Extract .zip
working-directory: ..
run: 7z x etherpad-win.zip -oetherpad-zip
-
name: Create installer
uses: joncloud/makensis-action@v3.6
with:
script-file: 'src/bin/nsis/etherpad.nsi'
-
name: Archive production artifacts
uses: actions/upload-artifact@v3
with:
name: etherpad-win.exe
path: etherpad-win.exe
deploy-zip:
# run on pushes to any branch
# run on PRs from external forks
permissions:
contents: none
if: |
(github.event_name != 'pull_request')
|| (github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id)
name: Deploy
needs: build
needs: build-zip
runs-on: windows-latest
steps:
-
name: Download zip
uses: actions/download-artifact@v2
uses: actions/download-artifact@v3
with:
name: etherpad-lite-win.zip
name: etherpad-win.zip
-
name: Extract Etherpad
run: 7z x etherpad-lite-win.zip -oetherpad
run: 7z x etherpad-win.zip -oetherpad
-
uses: actions/setup-node@v3
with:
node-version: 12
node-version: 14
cache: 'npm'
cache-dependency-path: |
etherpad/src/package-lock.json
etherpad/src/bin/doc/package-lock.json
-
name: Install Cypress
run: npm install cypress -g
run: cd src && npm install cypress
-
name: Run Etherpad
run: |
cd etherpad
node node_modules\ep_etherpad-lite\node\server.js &
curl --connect-timeout 10 --max-time 20 --retry 5 --retry-delay 10 --retry-max-time 60 --retry-connrefused http://127.0.0.1:9001/p/test
cd src\tests\frontend
cypress run --spec cypress\integration\test.js --config-file cypress\cypress.json
src\node_modules\cypress\bin\cypress run --config-file src\tests\frontendcypress\cypress.config.js

3
.gitignore vendored
View File

@ -1,9 +1,10 @@
/etherpad-win.exe
/etherpad-win.zip
node_modules
/settings.json
!settings.json.template
APIKEY.txt
SESSIONKEY.txt
etherpad-lite-win.zip
var/dirty.db
*~
*.patch

View File

@ -1,3 +1,123 @@
# 1.9.0
### Notable enhancements and fixes
* Windows build:
* The bundled `node.exe` was upgraded from v12 to v16.
* The bundled `node.exe` is now a 64-bit executable. If you need the 32-bit
version you must download and install Node.js yourself.
* Improvements to login session management:
* `express_sid` cookies and `sessionstorage:*` database records are no longer
created unless `requireAuthentication` is `true` (or a plugin causes them to
be created).
* Login sessions now have a finite lifetime by default (10 days after
leaving).
* `sessionstorage:*` database records are automatically deleted when the login
session expires (with some exceptions that will be fixed in the future).
* Requests for static content (e.g., `/robots.txt`) and special pages (e.g.,
the HTTP API, `/stats`) no longer create login session state.
* The following settings from `settings.json` are now applied as expected (they
were unintentionally ignored before):
* `padOptions.lang`
* `padOptions.showChat`
* `padOptions.userColor`
* `padOptions.userName`
* HTTP API:
* Fixed the return value of `getText` when called with a specific revision.
* Fixed a potential attribute pool corruption bug with
`copyPadWithoutHistory`.
* Mappings created by `createGroupIfNotExistsFor` are now removed from the
database when the group is deleted.
* Fixed race conditions in the `setText`, `appendText`, and `restoreRevision`
functions.
* Added an optional `authorId` parameter to `appendText`,
`copyPadWithoutHistory`, `createGroupPad`, `createPad`, `restoreRevision`,
`setHTML`, and `setText`, and bumped the latest API version to 1.3.0.
* Fixed a crash if the database is busy enough to cause a query timeout.
* New `/health` endpoint for getting information about Etherpad's health (see
[draft-inadarei-api-health-check-06](https://www.ietf.org/archive/id/draft-inadarei-api-health-check-06.html)).
* Docker now uses the new `/health` endpoint for health checks, which avoids
issues when authentication is enabled. It also avoids the unnecessary creation
of database records for managing browser sessions.
* When copying a pad, the pad's records are copied in batches to avoid database
timeouts with large pads.
* Exporting a large pad to `.etherpad` format should be faster thanks to bulk
database record fetches.
* When importing an `.etherpad` file, records are now saved to the database in
batches to avoid database timeouts with large pads.
#### For plugin authors
* New `expressPreSession` server-side hook.
* Pad server-side hook changes:
* `padCheck`: New hook.
* `padCopy`: New `srcPad` and `dstPad` context properties.
* `padDefaultContent`: New hook.
* `padRemove`: New `pad` context property.
* The `db` property on Pad objects is now public.
* New `getAuthorId` server-side hook.
* New APIs for processing attributes: `ep_etherpad-lite/static/js/attributes`
(low-level API) and `ep_etherpad-lite/static/js/AttributeMap` (high-level
API).
* The `import` server-side hook has a new `ImportError` context property.
* New `exportEtherpad` and `importEtherpad` server-side hooks.
* The `handleMessageSecurity` and `handleMessage` server-side hooks have a new
`sessionInfo` context property that includes the user's author ID, the pad ID,
and whether the user only has read-only access.
* The `handleMessageSecurity` server-side hook can now be used to grant write
access for the current message only.
* The `init_<pluginName>` server-side hooks have a new `logger` context
property that plugins can use to log messages.
* Prevent infinite loop when exiting the server
* Bump dependencies
### Compatibility changes
* Node.js v14.15.0 or later is now required.
* The default login session expiration (applicable if `requireAuthentication` is
`true`) changed from never to 10 days after the user leaves.
#### For plugin authors
* The `client` context property for the `handleMessageSecurity` and
`handleMessage` server-side hooks is deprecated; use the `socket` context
property instead.
* Pad server-side hook changes:
* `padCopy`:
* The `originalPad` context property is deprecated; use `srcPad` instead.
* The `destinationID` context property is deprecated; use `dstPad.id`
instead.
* `padCreate`: The `author` context property is deprecated; use the new
`authorId` context property instead. Also, the hook now runs asynchronously.
* `padLoad`: Now runs when a temporary Pad object is created during import.
Also, it now runs asynchronously.
* `padRemove`: The `padID` context property is deprecated; use `pad.id`
instead.
* `padUpdate`: The `author` context property is deprecated; use the new
`authorId` context property instead. Also, the hook now runs asynchronously.
* Returning `true` from a `handleMessageSecurity` hook function is deprecated;
return `'permitOnce'` instead.
* Changes to the `src/static/js/Changeset.js` library:
* The following attribute processing functions are deprecated (use the new
attribute APIs instead):
* `attribsAttributeValue()`
* `eachAttribNumber()`
* `makeAttribsString()`
* `opAttributeValue()`
* `opIterator()`: Deprecated in favor of the new `deserializeOps()` generator
function.
* `appendATextToAssembler()`: Deprecated in favor of the new `opsFromAText()`
generator function.
* `newOp()`: Deprecated in favor of the new `Op` class.
* The `AuthorManager.getAuthor4Token()` function is deprecated; use the new
`AuthorManager.getAuthorId()` function instead.
* The exported database records covered by the `exportEtherpadAdditionalContent`
server-side hook now include keys like `${customPrefix}:${padId}:*`, not just
`${customPrefix}:${padId}`.
* Plugin locales should overwrite core's locales Stale
* Plugin locales overwrite core locales
# 1.8.18
Released: 2022-05-05

View File

@ -4,9 +4,16 @@
#
# Author: muxator
FROM node:14-buster-slim
FROM node:lts-slim
LABEL maintainer="Etherpad team, https://github.com/ether/etherpad-lite"
ARG TIMEZONE=
RUN \
[ -z "${TIMEZONE}" ] || { \
ln -sf /usr/share/zoneinfo/"${TIMEZONE#/usr/share/zoneinfo/}" /etc/localtime; \
dpkg-reconfigure -f noninteractive tzdata; \
}
# plugins to install while building the container. By default no plugins are
# installed.
# If given a value, it has to be a space-separated, quoted list of plugin names.
@ -60,12 +67,12 @@ RUN mkdir -p "${EP_DIR}" && chown etherpad:etherpad "${EP_DIR}"
RUN export DEBIAN_FRONTEND=noninteractive; \
mkdir -p /usr/share/man/man1 && \
apt-get -qq update && \
apt-get -qq dist-upgrade && \
apt-get -qq --no-install-recommends install \
ca-certificates \
git \
curl \
${INSTALL_ABIWORD:+abiword} \
${INSTALL_SOFFICE:+libreoffice} \
${INSTALL_SOFFICE:+libreoffice default-jre libreoffice-java-common} \
&& \
apt-get -qq clean && \
rm -rf /var/lib/apt/lists/*
@ -85,7 +92,7 @@ COPY --chown=etherpad:etherpad ./ ./
# seems to confuse tools such as `npm outdated`, `npm update`, and some ESLint
# rules.
RUN { [ -z "${ETHERPAD_PLUGINS}" ] || \
npm install --no-save ${ETHERPAD_PLUGINS}; } && \
npm install --no-save --legacy-peer-deps ${ETHERPAD_PLUGINS}; } && \
src/bin/installDeps.sh && \
rm -rf ~/.npm
@ -95,7 +102,11 @@ COPY --chown=etherpad:etherpad ./settings.json.docker "${EP_DIR}"/settings.json
# Fix group permissions
RUN chmod -R g=u .
HEALTHCHECK --interval=20s --timeout=3s CMD curl -f http://localhost:9001 || exit 1
USER root
RUN cd src && npm link
USER etherpad
HEALTHCHECK --interval=20s --timeout=3s CMD ["etherpad-healthcheck"]
EXPOSE 9001
CMD ["node", "src/node/server.js"]
CMD ["etherpad"]

325
README.md
View File

@ -1,43 +1,78 @@
# A real-time collaborative editor for the web
# Etherpad: A real-time collaborative editor for the web
![Demo Etherpad Animated Jif](doc/images/etherpad_demo.gif "Etherpad in action")
# About
Etherpad is a real-time collaborative editor [scalable to thousands of simultaneous real time users](http://scale.etherpad.org/). It provides [full data export](https://github.com/ether/etherpad-lite/wiki/Understanding-Etherpad's-Full-Data-Export-capabilities) capabilities, and runs on _your_ server, under _your_ control.
## About
# Try it out
Etherpad is extremely flexible providing you the means to modify it to solve whatever problem your community has. We provide some demo instances for you try different experiences available within Etherpad. Pad content is automatically removed after 24 hours.
Etherpad is a real-time collaborative editor [scalable to thousands of
simultaneous real time users](http://scale.etherpad.org/). It provides [full
data
export](https://github.com/ether/etherpad-lite/wiki/Understanding-Etherpad's-Full-Data-Export-capabilities)
capabilities, and runs on _your_ server, under _your_ control.
* [Rich Editing](https://rich.etherpad.com) - A full rich text WYSIWYG editor.
* [Minimalist editor](https://minimalist.etherpad.com) - A minimalist editor that can be embedded within your tool.
* [Dark Mode](https://dark.etherpad.com) - Theme settings to have Etherpad start in dark mode, ideal for using Etherpad at night or for long durations.
* [Images](https://image.etherpad.com) - Plugins to improve provide Image support within a pad.
* [Video Chat](https://video.etherpad.com) - Plugins to enable Video and Audio chat in a pad.
* [Collaboration++](https://collab.etherpad.com) - Plugins to improve the really-real time collaboration experience, suitable for busy pads.
* [Document Analysis](https://analysis.etherpad.com) - Plugins to improve author and document analysis during and post creation.
* [Scale](https://shard.etherpad.com) - Etherpad running at scale with pad sharding which allows Etherpad to scale to ∞ number of Active Pads with up to ~20,000 edits per second, per pad.
## Try it out
# Project Status
Etherpad is extremely flexible providing you the means to modify it to solve
whatever problem your community has. We provide some demo instances for you try
different experiences available within Etherpad. Pad content is automatically
removed after 24 hours.
* [Rich Editing](https://rich.etherpad.com) - A full rich text WYSIWYG editor.
* [Minimalist editor](https://minimalist.etherpad.com) - A minimalist editor
that can be embedded within your tool.
* [Dark Mode](https://dark.etherpad.com) - Theme settings to have Etherpad
start in dark mode, ideal for using Etherpad at night or for long durations.
* [Images](https://image.etherpad.com) - Plugins to improve provide Image
support within a pad.
* [Video Chat](https://video.etherpad.com) - Plugins to enable Video and Audio
chat in a pad.
* [Collaboration++](https://collab.etherpad.com) - Plugins to improve the
really-real time collaboration experience, suitable for busy pads.
* [Document Analysis](https://analysis.etherpad.com) - Plugins to improve
author and document analysis during and post creation.
* [Scale](https://shard.etherpad.com) - Etherpad running at scale with pad
sharding which allows Etherpad to scale to ∞ number of Active Pads with up
to ~20,000 edits per second, per pad.
## Project Status
We're looking for maintainers and have some funding available. Please contact John McLear if you can help.
### Code Quality
[![Code Quality](https://github.com/ether/etherpad-lite/actions/workflows/codeql-analysis.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/codeql-analysis.yml) [![Total alerts](https://img.shields.io/lgtm/alerts/g/ether/etherpad-lite.svg?logo=lgtm&logoWidth=18&color=%2344b492)](https://lgtm.com/projects/g/ether/etherpad-lite/alerts/) [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/ether/etherpad-lite.svg?logo=lgtm&logoWidth=18&color=%2344b492)](https://lgtm.com/projects/g/ether/etherpad-lite/context:javascript) [![package.lock](https://github.com/ether/etherpad-lite/actions/workflows/lint-package-lock.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/lint-package-lock.yml)
[![Code Quality](https://github.com/ether/etherpad-lite/actions/workflows/codeql-analysis.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/codeql-analysis.yml)
[![package.lock](https://github.com/ether/etherpad-lite/actions/workflows/lint-package-lock.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/lint-package-lock.yml)
### Testing
[![Backend tests](https://github.com/ether/etherpad-lite/actions/workflows/backend-tests.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/backend-tests.yml) [![Simulated Load](https://github.com/ether/etherpad-lite/actions/workflows/load-test.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/load-test.yml) [![Rate Limit](https://github.com/ether/etherpad-lite/actions/workflows/rate-limit.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/rate-limit.yml) [![Windows Zip](https://github.com/ether/etherpad-lite/actions/workflows/windows-zip.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/windows-zip.yml) [![Docker file](https://github.com/ether/etherpad-lite/actions/workflows/dockerfile.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/dockerfile.yml)
[![Frontend admin tests powered by Sauce Labs](https://github.com/ether/etherpad-lite/actions/workflows/frontend-admin-tests.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/frontend-admin-tests.yml) [![Frontend tests powered by Sauce Labs](https://github.com/ether/etherpad-lite/actions/workflows/frontend-tests.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/frontend-tests.yml) [![Sauce Test Status](https://saucelabs.com/buildstatus/etherpad.svg)](https://saucelabs.com/u/etherpad) [![Windows Installer](https://github.com/ether/etherpad-lite/actions/workflows/windows-installer.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/windows-installer.yml)
[![Backend tests](https://github.com/ether/etherpad-lite/actions/workflows/backend-tests.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/backend-tests.yml)
[![Simulated Load](https://github.com/ether/etherpad-lite/actions/workflows/load-test.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/load-test.yml)
[![Rate Limit](https://github.com/ether/etherpad-lite/actions/workflows/rate-limit.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/rate-limit.yml)
[![Docker file](https://github.com/ether/etherpad-lite/actions/workflows/dockerfile.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/dockerfile.yml)
[![Frontend admin tests powered by Sauce Labs](https://github.com/ether/etherpad-lite/actions/workflows/frontend-admin-tests.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/frontend-admin-tests.yml)
[![Frontend tests powered by Sauce Labs](https://github.com/ether/etherpad-lite/actions/workflows/frontend-tests.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/frontend-tests.yml)
[![Sauce Test Status](https://saucelabs.com/buildstatus/etherpad.svg)](https://saucelabs.com/u/etherpad)
[![Windows Build](https://github.com/ether/etherpad-lite/actions/workflows/windows.yml/badge.svg?color=%2344b492)](https://github.com/ether/etherpad-lite/actions/workflows/windows.yml)
### Engagement
<a href="https://hub.docker.com/r/etherpad/etherpad"><img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/etherpad/etherpad?color=%2344b492"></a> [![Discord](https://img.shields.io/discord/741309013593030667?color=%2344b492)](https://discord.com/invite/daEjfhw) [![Etherpad plugins](https://img.shields.io/endpoint?url=https%3A%2F%2Fstatic.etherpad.org%2Fshields.json&color=%2344b492 "Etherpad plugins")](https://static.etherpad.org/index.html) ![Languages](https://img.shields.io/static/v1?label=Languages&message=105&color=%2344b492) ![Translation Coverage](https://img.shields.io/static/v1?label=Languages&message=98%&color=%2344b492)
# Installation
[![Docker Pulls](https://img.shields.io/docker/pulls/etherpad/etherpad?color=%2344b492)](https://hub.docker.com/r/etherpad/etherpad)
[![Discord](https://img.shields.io/discord/741309013593030667?color=%2344b492)](https://discord.com/invite/daEjfhw)
[![Etherpad plugins](https://img.shields.io/endpoint?url=https%3A%2F%2Fstatic.etherpad.org%2Fshields.json&color=%2344b492 "Etherpad plugins")](https://static.etherpad.org/index.html)
![Languages](https://img.shields.io/static/v1?label=Languages&message=105&color=%2344b492)
![Translation Coverage](https://img.shields.io/static/v1?label=Languages&message=98%&color=%2344b492)
## Requirements
- [Node.js](https://nodejs.org/) >= **12.13.0**.
## Installation
## GNU/Linux and other UNIX-like systems
### Requirements
### Quick install on Debian/Ubuntu
```
[Node.js](https://nodejs.org/) >= **14.0.0**.
### GNU/Linux and other UNIX-like systems
#### Quick install on Debian/Ubuntu
```sh
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt install -y nodejs
git clone --branch master https://github.com/ether/etherpad-lite.git &&
@ -45,103 +80,172 @@ cd etherpad-lite &&
src/bin/run.sh
```
### Manual install
#### Manual install
You'll need Git and [Node.js](https://nodejs.org/) installed.
**As any user (we recommend creating a separate user called etherpad):**
1. Move to a folder where you want to install Etherpad. Clone the git repository: `git clone --branch master git://github.com/ether/etherpad-lite.git`
2. Change into the new directory containing the cloned source code: `cd etherpad-lite`
3. run `src/bin/run.sh` and open <http://127.0.0.1:9001> in your browser.
1. Move to a folder where you want to install Etherpad.
2. Clone the Git repository: `git clone --branch master
https://github.com/ether/etherpad-lite.git`
3. Change into the new directory containing the cloned source code: `cd
etherpad-lite`
4. Run `src/bin/run.sh` and open http://127.0.0.1:9001 in your browser.
To update to the latest released version, execute `git pull origin`. The next
start with `src/bin/run.sh` will update the dependencies.
[Next steps](#next-steps).
### Windows
## Windows
#### Prebuilt Windows package
### Prebuilt Windows package
This package runs on any Windows machine. You can perform a manual installation via git for development purposes, but as this uses symlinks which performs unreliably on Windows, please stick to the prebuilt package if possible.
This package runs on any Windows machine. You can perform a manual installation
via git for development purposes, but as this uses symlinks which performs
unreliably on Windows, please stick to the prebuilt package if possible.
1. [Download the latest Windows package](https://etherpad.org/#download)
2. Extract the folder
1. [Download the latest Windows package](https://etherpad.org/#download)
2. Extract the folder
Run `start.bat` and open <http://localhost:9001> in your browser. You like it? [Next steps](#next-steps).
Run `start.bat` and open <http://localhost:9001> in your browser.
### Manually install on Windows
You'll need [node.js](https://nodejs.org) and (optionally, though recommended) git.
#### Manually install on Windows
1. Grab the source, either
- download <https://github.com/ether/etherpad-lite/zipball/master>
- or `git clone --branch master https://github.com/ether/etherpad-lite.git`
2. With a "Run as administrator" command prompt execute
`src\bin\installOnWindows.bat`
You'll need [Node.js](https://nodejs.org) and (optionally, though recommended)
git.
Now, run `start.bat` and open <http://localhost:9001> in your browser.
1. Grab the source, either:
* download <https://github.com/ether/etherpad-lite/zipball/master>
* or `git clone --branch master
https://github.com/ether/etherpad-lite.git`
2. With a "Run as administrator" command prompt execute
`src\bin\installOnWindows.bat`
Now, run `start.bat` and open http://localhost:9001 in your browser.
Update to the latest version with `git pull origin`, then run
`src\bin\installOnWindows.bat`, again.
If cloning to a subdirectory within another project, you may need to do the following:
If cloning to a subdirectory within another project, you may need to do the
following:
1. Start the server manually (e.g. `node src/node/server.js`)
2. Edit the db `filename` in `settings.json` to the relative directory with the file (e.g. `application/lib/etherpad-lite/var/dirty.db`)
3. Add auto-generated files to the main project `.gitignore`
1. Start the server manually (e.g. `node src/node/server.js`)
2. Edit the db `filename` in `settings.json` to the relative directory with
the file (e.g. `application/lib/etherpad-lite/var/dirty.db`)
3. Add auto-generated files to the main project `.gitignore`
## Docker container
### Docker container
Find [here](doc/docker.md) information on running Etherpad in a container.
# Next Steps
## Plugins
## Tweak the settings
You can modify the settings in `settings.json`.
If you need to handle multiple settings files, you can pass the path to a
settings file to `src/bin/run.sh` using the `-s|--settings` option: this allows
you to run multiple Etherpad instances from the same installation.
Similarly, `--credentials` can be used to give a settings override file, `--apikey` to give a different APIKEY.txt file and `--sessionkey` to give a non-default SESSIONKEY.txt.
**Each configuration parameter can also be set via an environment variable**, using the syntax `"${ENV_VAR}"` or `"${ENV_VAR:default_value}"`. For details, refer to `settings.json.template`.
Once you have access to your `/admin` section settings can be modified through the web browser.
If you are planning to use Etherpad in a production environment, you should use a dedicated database such as `mysql`, since the `dirtyDB` database driver is only for testing and/or development purposes.
## Secure your installation
If you have enabled authentication in `users` section in `settings.json`, it is a good security practice to **store hashes instead of plain text passwords** in that file. This is _especially_ advised if you are running a production installation.
Please install [ep_hash_auth plugin](https://www.npmjs.com/package/ep_hash_auth) and configure it.
If you prefer, `ep_hash_auth` also gives you the option of storing the users in a custom directory in the file system, without having to edit `settings.json` and restart Etherpad each time.
## Customize functionalities with plugins
Etherpad is very customizable through plugins.
![Basic install](doc/images/etherpad_basic.png "Basic Installation")
![Full Features](doc/images/etherpad_full_features.png "You can add a lot of plugins !")
Etherpad is very customizable through plugins. Instructions for installing themes and plugins can be found in [the plugin wiki article](https://github.com/ether/etherpad-lite/wiki/Available-Plugins).
### Available Plugins
## Getting the full features
Run the following command in your Etherpad folder to get all of the features visible in the demo gif:
For a list of available plugins, see the [plugins
site](https://static.etherpad.org).
```
npm install --no-save --legacy-peer-deps ep_headings2 ep_markdown ep_comments_page ep_align ep_font_color ep_webrtc ep_embedded_hyperlinks2
### Plugin Installation
You can install plugins from the admin web interface (e.g.,
http://127.0.0.1:9001/admin/plugins).
Alternatively, you can install plugins from the command line:
```sh
cd /path/to/etherpad-lite
# The `--no-save` and `--legacy-peer-deps` arguments are necessary to work
# around npm quirks.
npm install --no-save --legacy-peer-deps ep_${plugin_name}
```
## Customize the style with skin variants
Also see [the plugin wiki
article](https://github.com/ether/etherpad-lite/wiki/Available-Plugins).
Open <http://127.0.0.1:9001/p/test#skinvariantsbuilder> in your browser and start playing !
### Suggested Plugins
Run the following command in your Etherpad folder to get all of the features
visible in the above demo gif:
```sh
npm install --no-save --legacy-peer-deps \
ep_align \
ep_comments_page \
ep_embedded_hyperlinks2 \
ep_font_color \
ep_headings2 \
ep_markdown \
ep_webrtc
```
For user authentication, you are encouraged to run an [OpenID
Connect](https://openid.net/connect/) identity provider (OP) and install the
following plugins:
* [ep_openid_connect](https://github.com/ether/ep_openid_connect#readme) to
authenticate against your OP.
* [ep_guest](https://github.com/ether/ep_guest#readme) to create a
"guest" account that has limited access (e.g., read-only access).
* [ep_user_displayname](https://github.com/ether/ep_user_displayname#readme)
to automatically populate each user's displayed name from your OP.
* [ep_stable_authorid](https://github.com/ether/ep_stable_authorid#readme) so
that each user's chosen color, display name, comment ownership, etc. is
strongly linked to their account.
## Next Steps
### Tweak the settings
You can modify the settings in `settings.json`. If you need to handle multiple
settings files, you can pass the path to a settings file to `src/bin/run.sh`
using the `-s|--settings` option: this allows you to run multiple Etherpad
instances from the same installation. Similarly, `--credentials` can be used to
give a settings override file, `--apikey` to give a different APIKEY.txt file
and `--sessionkey` to give a non-default `SESSIONKEY.txt`. **Each configuration
parameter can also be set via an environment variable**, using the syntax
`"${ENV_VAR}"` or `"${ENV_VAR:default_value}"`. For details, refer to
`settings.json.template`. Once you have access to your `/admin` section,
settings can be modified through the web browser.
If you are planning to use Etherpad in a production environment, you should use
a dedicated database such as `mysql`, since the `dirtyDB` database driver is
only for testing and/or development purposes.
### Secure your installation
If you have enabled authentication in `users` section in `settings.json`, it is
a good security practice to **store hashes instead of plain text passwords** in
that file. This is _especially_ advised if you are running a production
installation.
Please install [ep_hash_auth plugin](https://www.npmjs.com/package/ep_hash_auth)
and configure it. If you prefer, `ep_hash_auth` also gives you the option of
storing the users in a custom directory in the file system, without having to
edit `settings.json` and restart Etherpad each time.
### Customize the style with skin variants
Open http://127.0.0.1:9001/p/test#skinvariantsbuilder in your browser and start
playing!
![Skin Variant](doc/images/etherpad_skin_variants.gif "Skin variants")
## Helpful resources
The [wiki](https://github.com/ether/etherpad-lite/wiki) is your one-stop resource for Tutorials and How-to's.
The [wiki](https://github.com/ether/etherpad-lite/wiki) is your one-stop
resource for Tutorials and How-to's.
Documentation can be found in `doc/`.
# Development
## Development
## Things you should know
### Things you should know
You can debug Etherpad using `src/bin/debugRun.sh`.
@ -150,36 +254,63 @@ developers and advanced users. Be aware that it will skip the dependencies
update, so remember to run `src/bin/installDeps.sh` after installing a new
dependency or upgrading version.
If you want to find out how Etherpad's `Easysync` works (the library that makes it really realtime), start with this [PDF](https://github.com/ether/etherpad-lite/raw/master/doc/easysync/easysync-full-description.pdf) (complex, but worth reading).
If you want to find out how Etherpad's `Easysync` works (the library that makes
it really realtime), start with this
[PDF](https://github.com/ether/etherpad-lite/raw/master/doc/easysync/easysync-full-description.pdf)
(complex, but worth reading).
## Contributing
Read our [**Developer Guidelines**](https://github.com/ether/etherpad-lite/blob/master/CONTRIBUTING.md)
### Contributing
# Get in touch
The official channel for contacting the development team is via the [Github issues](https://github.com/ether/etherpad-lite/issues).
Read our [**Developer
Guidelines**](https://github.com/ether/etherpad-lite/blob/master/CONTRIBUTING.md)
For **responsible disclosure of vulnerabilities**, please write a mail to the maintainers (a.mux@inwind.it and contact@etherpad.org).
Join the official [Etherpad Discord Channel](https://discord.com/invite/daEjfhw)
### HTTP API
# HTTP API
Etherpad is designed to be easily embeddable and provides a [HTTP API](https://github.com/ether/etherpad-lite/wiki/HTTP-API)
that allows your web application to manage pads, users and groups. It is recommended to use the [available client implementations](https://github.com/ether/etherpad-lite/wiki/HTTP-API-client-libraries) in order to interact with this API.
Etherpad is designed to be easily embeddable and provides a [HTTP
API](https://github.com/ether/etherpad-lite/wiki/HTTP-API) that allows your web
application to manage pads, users and groups. It is recommended to use the
[available client
implementations](https://github.com/ether/etherpad-lite/wiki/HTTP-API-client-libraries)
in order to interact with this API.
OpenAPI (previously swagger) definitions for the API are exposed under `/api/openapi.json`.
OpenAPI (previously swagger) definitions for the API are exposed under
`/api/openapi.json`.
# jQuery plugin
There is a [jQuery plugin](https://github.com/ether/etherpad-lite-jquery-plugin) that helps you to embed Pads into your website.
### jQuery plugin
# Plugin Framework
Etherpad offers a plugin framework, allowing you to easily add your own features. By default your Etherpad is extremely light-weight and it's up to you to customize your experience. Once you have Etherpad installed you should [visit the plugin page](https://static.etherpad.org/) and take control.
There is a [jQuery plugin](https://github.com/ether/etherpad-lite-jquery-plugin)
that helps you to embed Pads into your website.
# Translations / Localizations (i18n / l10n)
Etherpad comes with translations into all languages thanks to the team at [TranslateWiki](https://translatewiki.net/).
### Plugin Framework
If you require translations in [plugins](https://static.etherpad.org/) please send pull request to each plugin individually.
Etherpad offers a plugin framework, allowing you to easily add your own
features. By default your Etherpad is extremely light-weight and it's up to you
to customize your experience. Once you have Etherpad installed you should [visit
the plugin page](https://static.etherpad.org/) and take control.
### Translations / Localizations (i18n / l10n)
Etherpad comes with translations into all languages thanks to the team at
[TranslateWiki](https://translatewiki.net/).
If you require translations in [plugins](https://static.etherpad.org/) please
send pull request to each plugin individually.
## FAQ
# FAQ
Visit the **[FAQ](https://github.com/ether/etherpad-lite/wiki/FAQ)**.
# License
## Get in touch
The official channel for contacting the development team is via the [GitHub
issues](https://github.com/ether/etherpad-lite/issues).
For **responsible disclosure of vulnerabilities**, please write a mail to the
maintainers (a.mux@inwind.it and contact@etherpad.org).
Join the official [Etherpad Discord
Channel](https://discord.com/invite/daEjfhw).
## License
[Apache License v2](http://www.apache.org/licenses/LICENSE-2.0.html)

View File

@ -56,26 +56,68 @@ Called from: `src/static/js/pluginfw/plugins.js`
Run during startup after the named plugin is initialized.
Context properties: None
Context properties:
## expressConfigure
Called from: src/node/hooks/express.js
* `logger`: An object with the following `console`-like methods: `debug`,
`info`, `log`, `warn`, `error`.
Things in context:
## `expressPreSession`
1. app - the main application object
Called from: `src/node/hooks/express.js`
This is a helpful hook for changing the behavior and configuration of the application. It's called right after the application gets configured.
Called during server startup just before the
[`express-session`](https://www.npmjs.com/package/express-session) middleware is
added to the Express Application object. Use this hook to add route handlers or
middleware that executes before `express-session` state is created and
authentication is performed. This is useful for creating public endpoints that
don't spam the database with new `express-session` records or trigger
authentication.
## expressCreateServer
Called from: src/node/hooks/express.js
**WARNING:** All handlers registered during this hook run before the built-in
authentication checks, so any handled endpoints will be public unless the
handler itself authenticates the user.
Things in context:
Context properties:
1. app - the main express application object (helpful for adding new paths and such)
2. server - the http server object
* `app`: The Express [Application](https://expressjs.com/en/4x/api.html#app)
object.
This hook gets called after the application object has been created, but before it starts listening. This is similar to the expressConfigure hook, but it's not guaranteed that the application object will have all relevant configuration variables.
Example:
```javascript
exports.expressPreSession = async (hookName, {app}) => {
app.get('/hello-world', (req, res) => res.send('hello world'));
};
```
## `expressConfigure`
Called from: `src/node/hooks/express.js`
Called during server startup just after the
[`express-session`](https://www.npmjs.com/package/express-session) middleware is
added to the Express Application object. Use this hook to add route handlers or
middleware that executes after `express-session` state is created and
authentication is performed.
Context properties:
* `app`: The Express [Application](https://expressjs.com/en/4x/api.html#app)
object.
## `expressCreateServer`
Called from: `src/node/hooks/express.js`
Identical to the `expressConfigure` hook (the two run in parallel with each
other) except this hook's context includes the HTTP Server object.
Context properties:
* `app`: The Express [Application](https://expressjs.com/en/4x/api.html#app)
object.
* `server`: The [http.Server](https://nodejs.org/api/http.html#class-httpserver)
or [https.Server](https://nodejs.org/api/https.html#class-httpsserver) object.
## expressCloseServer
@ -165,15 +207,98 @@ Things in context:
This hook gets called when the access to the concrete pad is being checked.
Return `false` to deny access.
## padCreate
Called from: src/node/db/Pad.js
## `getAuthorId`
Things in context:
Called from `src/node/db/AuthorManager.js`
1. pad - the pad instance
2. author - the id of the author who created the pad
Called when looking up (or creating) the author ID for a user, except for author
IDs obtained via the HTTP API. Registered hook functions are called until one
returns a non-`undefined` value. If a truthy value is returned by a hook
function, it is used as the user's author ID. Otherwise, the value of the
`dbKey` context property is used to look up the author ID. If there is no such
author ID at that key, a new author ID is generated and associated with that
key.
This hook gets called when a new pad was created.
Context properties:
* `dbKey`: Database key to use when looking up the user's author ID if no hook
function returns an author ID. This is initialized to the user-supplied token
value (see the `token` context property), but hook functions can modify this
to control how author IDs are allocated to users. If no author ID is
associated with this database key, a new author ID will be randomly generated
and associated with the key. For security reasons, if this is modified it
should be modified to not look like a valid token (see the `token` context
property) unless the plugin intentionally wants the user to be able to
impersonate another user.
* `token`: The user-supplied token, or nullish for an anonymous user. Tokens are
secret values that must not be disclosed to others. If non-null, the token is
guaranteed to be a string with the form `t.<base64url>` where `<base64url>` is
any valid non-empty base64url string (RFC 4648 section 5 with padding).
Example: `t.twim3X2_KGiRj8cJ-3602g==`.
* `user`: If the user has authenticated, this is an object from `settings.users`
(or similar from an authentication plugin). Etherpad core and all good
authentication plugins set the `username` property of this object to a string
that uniquely identifies the authenticated user. This object is nullish if the
user has not authenticated.
Example:
```javascript
exports.getAuthorId = async (hookName, context) => {
const {username} = context.user || {};
// If the user has not authenticated, or has "authenticated" as the guest
// user, do the default behavior (try another plugin if any, falling through
// to using the token as the database key).
if (!username || username === 'guest') return;
// The user is authenticated and has a username. Give the user a stable author
// ID so that they appear to be the same author even after clearing cookies or
// accessing the pad from another device. Note that this string is guaranteed
// to never have the form of a valid token; without that guarantee an
// unauthenticated user might be able to impersonate an authenticated user.
context.dbKey = `username=${username}`;
// Return a falsy but non-undefined value to stop Etherpad from calling any
// more getAuthorId hook functions and look up the author ID using the
// username-derived database key.
return '';
};
```
## `padCreate`
Called from: `src/node/db/Pad.js`
Called when a new pad is created.
Context properties:
* `pad`: The Pad object.
* `authorId`: The ID of the author who created the pad.
* `author` (**deprecated**): Synonym of `authorId`.
## `padDefaultContent`
Called from `src/node/db/Pad.js`
Called to obtain a pad's initial content, unless the pad is being created with
specific content. The return value is ignored; to change the content, modify the
`content` context property.
This hook is run asynchronously. All registered hook functions are run
concurrently (via `Promise.all()`), so be careful to avoid race conditions when
reading and modifying the context properties.
Context properties:
* `pad`: The newly created Pad object.
* `authorId`: The author ID of the user that is creating the pad.
* `type`: String identifying the content type. Currently this is `'text'` and
must not be changed. Future versions of Etherpad may add support for HTML,
jsdom objects, or other formats, so plugins must assert that this matches a
supported content type before reading `content`.
* `content`: The pad's initial content. Change this property to change the pad's
initial content. If the content type is changed, the `type` property must also
be updated to match. Plugins must check the value of the `type` property
before reading this value.
## `padLoad`
@ -185,44 +310,73 @@ Context properties:
* `pad`: The Pad object.
## padUpdate
Called from: src/node/db/Pad.js
## `padUpdate`
Things in context:
Called from: `src/node/db/Pad.js`
1. pad - the pad instance
2. author - the id of the author who updated the pad
3. revs - the index of the new revision
4. changeset - the changeset of this revision (see [Changeset Library](#index_changeset_library))
Called when an existing pad is updated.
This hook gets called when an existing pad was updated.
Context properties:
## padCopy
Called from: src/node/db/Pad.js
* `pad`: The Pad object.
* `authorId`: The ID of the author who updated the pad.
* `author` (**deprecated**): Synonym of `authorId`.
* `revs`: The index of the new revision.
* `changeset`: The changeset of this revision (see [Changeset
Library](#index_changeset_library)).
Things in context:
## `padCopy`
1. originalPad - the source pad instance
2. destinationID - the id of the pad copied from originalPad
Called from: `src/node/db/Pad.js`
This hook gets called when an existing pad was copied.
Called when a pad is copied so that plugins can copy plugin-specific database
records or perform some other plugin-specific initialization.
Order of events when a pad is copied:
1. Destination pad is deleted if it exists and overwrite is permitted. This
causes the `padRemove` hook to run.
2. Pad-specific database records are copied in the database, except for
records with plugin-specific database keys.
3. A new Pad object is created for the destination pad. This causes the
`padLoad` hook to run.
4. This hook runs.
Context properties:
* `srcPad`: The source Pad object.
* `dstPad`: The destination Pad object.
Usage examples:
* https://github.com/ether/ep_comments
* https://github.com/ether/ep_comments_page
## padRemove
Called from: src/node/db/Pad.js
## `padRemove`
Things in context:
Called from: `src/node/db/Pad.js`
1. padID
Called when an existing pad is removed/deleted. Plugins should use this to clean
up any plugin-specific pad records from the database.
This hook gets called when an existing pad was removed/deleted.
Context properties:
* `pad`: Pad object for the pad that is being deleted.
Usage examples:
* https://github.com/ether/ep_comments
* https://github.com/ether/ep_comments_page
## `padCheck`
Called from: `src/node/db/Pad.js`
Called when a consistency check is run on a pad, after the core checks have
completed successfully. An exception should be thrown if the pad is faulty in
some way.
Context properties:
* `pad`: The Pad object that is being checked.
## socketio
Called from: src/node/hooks/express/socketio.js
@ -235,47 +389,52 @@ Things in context:
I have no idea what this is useful for, someone else will have to add this description.
## preAuthorize
Called from: src/node/hooks/express/webaccess.js
## `preAuthorize`
Things in context:
Called from: `src/node/hooks/express/webaccess.js`
1. req - the request object
2. res - the response object
3. next - bypass callback. If this is called instead of the normal callback then
all remaining access checks are skipped.
Called for each HTTP request before any authentication checks are performed. The
registered `preAuthorize` hook functions are called one at a time until one
explicitly grants or denies the request by returning `true` or `false`,
respectively. If none of the hook functions return anything, the access decision
is deferred to the normal authentication and authorization checks.
This hook is called for each HTTP request before any authentication checks are
performed. Example uses:
Example uses:
* Always grant access to static content.
* Process an OAuth callback.
* Drop requests from IP addresses that have failed N authentication checks
within the past X minutes.
A preAuthorize function is always called for each request unless a preAuthorize
function from another plugin (if any) has already explicitly granted or denied
the request.
Return values:
You can pass the following values to the provided callback:
* `undefined` (or `[]`) defers the access decision to the next registered
`preAuthorize` hook function, or to the normal authentication and
authorization checks if no more `preAuthorize` hook functions remain.
* `true` (or `[true]`) immediately grants access to the requested resource,
unless the request is for an `/admin` page in which case it is treated the
same as returning `undefined`. (This prevents buggy plugins from accidentally
granting admin access to the general public.)
* `false` (or `[false]`) immediately denies the request. The `preAuthnFailure`
hook will be called to handle the failure.
* `[]` defers the access decision to the normal authentication and authorization
checks (or to a preAuthorize function from another plugin, if one exists).
* `[true]` immediately grants access to the requested resource, unless the
request is for an `/admin` page in which case it is treated the same as `[]`.
(This prevents buggy plugins from accidentally granting admin access to the
general public.)
* `[false]` immediately denies the request. The preAuthnFailure hook will be
called to handle the failure.
Context properties:
* `req`: The Express [Request](https://expressjs.com/en/4x/api.html#req) object.
* `res`: The Express [Response](https://expressjs.com/en/4x/api.html#res)
object.
* `next`: Callback to immediately hand off handling to the next Express
middleware/handler, or to the next matching route if `'route'` is passed as
the first argument. Do not call this unless you understand the consequences.
Example:
```
exports.preAuthorize = (hookName, context, cb) => {
if (ipAddressIsFirewalled(context.req)) return cb([false]);
if (requestIsForStaticContent(context.req)) return cb([true]);
if (requestIsForOAuthCallback(context.req)) return cb([true]);
return cb([]);
```javascript
exports.preAuthorize = async (hookName, {req}) => {
if (await ipAddressIsFirewalled(req)) return false;
if (requestIsForStaticContent(req)) return true;
if (requestIsForOAuthCallback(req)) return true;
// Defer the decision to the next step by returning undefined.
};
```
@ -530,26 +689,29 @@ exports.authzFailure = (hookName, context, cb) => {
};
```
## handleMessage
Called from: src/node/handler/PadMessageHandler.js
## `handleMessage`
Things in context:
1. message - the message being handled
2. socket - the socket.io Socket object
3. client - **deprecated** synonym of socket
Called from: `src/node/handler/PadMessageHandler.js`
This hook allows plugins to drop or modify incoming socket.io messages from
clients, before Etherpad processes them.
clients, before Etherpad processes them. If any hook function returns `null`
then the message will not be subject to further processing.
The handleMessage function must return a Promise. If the Promise resolves to
`null`, the message is dropped. Returning `callback(value)` will return a
Promise that is resolved to `value`.
Context properties:
Examples:
* `message`: The message being handled.
* `sessionInfo`: Object describing the socket.io session with the following
properties:
* `authorId`: The user's author ID.
* `padId`: The real (not read-only) ID of the pad.
* `readOnly`: Whether the client has read-only access (true) or read/write
access (false).
* `socket`: The socket.io Socket object.
* `client`: (**Deprecated**; use `socket` instead.) Synonym of `socket`.
```
// Using an async function:
Example:
```javascript
exports.handleMessage = async (hookName, {message, socket}) => {
if (message.type === 'USERINFO_UPDATE') {
// Force the display name to the name associated with the account.
@ -557,51 +719,47 @@ exports.handleMessage = async (hookName, {message, socket}) => {
if (user.name) message.data.userInfo.name = user.name;
}
};
// Using a regular function:
exports.handleMessage = (hookName, {message, socket}, callback) => {
if (message.type === 'USERINFO_UPDATE') {
// Force the display name to the name associated with the account.
const user = socket.client.request.session.user || {};
if (user.name) message.data.userInfo.name = user.name;
}
return callback();
};
```
## handleMessageSecurity
Called from: src/node/handler/PadMessageHandler.js
## `handleMessageSecurity`
Things in context:
Called from: `src/node/handler/PadMessageHandler.js`
1. message - the message being handled
2. socket - the socket.io Socket object
3. client - **deprecated** synonym of socket
Called for each incoming message from a client. Allows plugins to grant
temporary write access to a pad.
This hook allows plugins to grant temporary write access to a pad. It is called
for each incoming message from a client. If write access is granted, it applies
to the current message and all future messages from the same socket.io
connection until the next `CLIENT_READY` message. Read-only access is reset
**after** each `CLIENT_READY` message, so granting write access has no effect
for those message types.
Supported return values:
The handleMessageSecurity function must return a Promise. If the Promise
resolves to `true`, write access is granted as described above. Returning
`callback(value)` will return a Promise that is resolved to `value`.
* `undefined`: No change in access status.
* `'permitOnce'`: Override the user's read-only access for the current
`COLLABROOM` message only. Has no effect if the current message is not a
`COLLABROOM` message, or if the user already has write access to the pad.
* `true`: (**Deprecated**; return `'permitOnce'` instead.) Override the user's
read-only access for all `COLLABROOM` messages from the same socket.io
connection (including the current message, if applicable) until the client's
next `CLIENT_READY` message. Has no effect if the user already has write
access to the pad. Read-only access is reset **after** each `CLIENT_READY`
message, so returning `true` has no effect for `CLIENT_READY` messages.
Examples:
Context properties:
```
// Using an async function:
exports.handleMessageSecurity = async (hookName, {message, socket}) => {
if (shouldGrantWriteAccess(message, socket)) return true;
return;
};
* `message`: The message being handled.
* `sessionInfo`: Object describing the socket.io connection with the following
properties:
* `authorId`: The user's author ID.
* `padId`: The real (not read-only) ID of the pad.
* `readOnly`: Whether the client has read-only access (true) or read/write
access (false).
* `socket`: The socket.io Socket object.
* `client`: (**Deprecated**; use `socket` instead.) Synonym of `socket`.
// Using a regular function:
exports.handleMessageSecurity = (hookName, {message, socket}, callback) => {
if (shouldGrantWriteAccess(message, socket)) return callback(true);
return callback();
Example:
```javascript
exports.handleMessageSecurity = async (hookName, context) => {
const {message, sessionInfo: {readOnly}} = context;
if (!readOnly || message.type !== 'COLLABROOM') return;
if (await messageIsBenign(message)) return 'permitOnce';
};
```
@ -647,39 +805,36 @@ exports.clientVars = (hookName, context, callback) => {
};
```
## getLineHTMLForExport
Called from: src/node/utils/ExportHtml.js
## `getLineHTMLForExport`
Things in context:
Called from: `src/node/utils/ExportHtml.js`
1. apool - pool object
2. attribLine - line attributes
3. text - line text
This hook will allow a plug-in developer to re-write each line when exporting to
HTML.
This hook will allow a plug-in developer to re-write each line when exporting to HTML.
Context properties:
* `apool`: Pool object.
* `attribLine`: Line attributes.
* `line`:
* `lineContent`:
* `text`: Line text.
* `padId`: Writable (not read-only) pad identifier.
Example:
```
var Changeset = require("ep_etherpad-lite/static/js/Changeset");
exports.getLineHTMLForExport = function (hook, context) {
var header = _analyzeLine(context.attribLine, context.apool);
if (header) {
return "<" + header + ">" + context.lineContent + "</" + header + ">";
}
}
```javascript
const AttributeMap = require('ep_etherpad-lite/static/js/AttributeMap');
const Changeset = require('ep_etherpad-lite/static/js/Changeset');
function _analyzeLine(alineAttrs, apool) {
var header = null;
if (alineAttrs) {
var opIter = Changeset.opIterator(alineAttrs);
if (opIter.hasNext()) {
var op = opIter.next();
header = Changeset.opAttributeValue(op, 'heading', apool);
}
}
return header;
}
exports.getLineHTMLForExport = async (hookName, context) => {
if (!context.attribLine) return;
const [op] = Changeset.deserializeOps(context.attribLine);
if (op == null) return;
const heading = AttributeMap.fromString(op.attribs, context.apool).get('heading');
if (!heading) return;
context.lineContent = `<${heading}>${context.lineContent}</${heading}>`;
};
```
## exportHTMLAdditionalContent
@ -790,17 +945,19 @@ exports.exportHtmlAdditionalTagsWithData = function(hook, pad, cb){
};
```
## exportEtherpadAdditionalContent
Called from src/node/utils/ExportEtherpad.js and
src/node/utils/ImportEtherpad.js
## `exportEtherpadAdditionalContent`
Things in context: Nothing
Called from `src/node/utils/ExportEtherpad.js` and
`src/node/utils/ImportEtherpad.js`.
Useful for exporting and importing pad metadata that is stored in the database
but not in the pad's content or attributes. For example, in ep_comments_page the
comments are stored as `comments:padId:uniqueIdOfComment` so a complete export
of all pad data to an `.etherpad` file must include the `comments:padId:*`
records.
Called when exporting to an `.etherpad` file or when importing from an
`.etherpad` file. The hook function should return prefixes for pad-specific
records that should be included in the export/import. On export, all
`${prefix}:${padId}` and `${prefix}:${padId}:*` records are included in the
generated `.etherpad` file. On import, all `${prefix}:${padId}` and
`${prefix}:${padId}:*` records are loaded into the database.
Context properties: None.
Example:
@ -809,6 +966,48 @@ Example:
exports.exportEtherpadAdditionalContent = () => ['comments'];
```
## `exportEtherpad`
Called from `src/node/utils/ExportEtherpad.js`.
Called when exporting to an `.etherpad` file.
Context properties:
* `pad`: The exported pad's Pad object.
* `data`: JSONable output object. This is pre-populated with records from core
Etherpad as well as pad-specific records with prefixes from the
`exportEtherpadAdditionalContent` hook. Registered hook functions can modify
this object (but not replace the object) to perform any desired
transformations to the exported data (such as the inclusion of
plugin-specific records). All registered hook functions are executed
concurrently, so care should be taken to avoid race conditions with other
plugins.
* `dstPadId`: The pad ID that should be used when writing pad-specific records
to `data` (instead of `pad.id`). This avoids leaking the writable pad ID
when a user exports a read-only pad. This might be a dummy value; plugins
should not assume that it is either the pad's real writable ID or its
read-only ID.
## `importEtherpad`
Called from `src/node/utils/ImportEtherpad.js`.
Called when importing from an `.etherpad` file.
Context properties:
* `pad`: Temporary Pad object containing the pad's data read from the imported
`.etherpad` file. The `pad.db` object is a temporary in-memory database
whose records will be copied to the real database after they are validated
(see the `padCheck` hook). Registered hook functions MUST NOT use the real
database to access (read or write) pad-specific records; they MUST instead
use `pad.db`. All registered hook functions are executed concurrently, so
care should be taken to avoid race conditions with other plugins.
* `data`: Raw JSONable object from the `.etherpad` file. This data must not be
modified.
* `srcPadId`: The pad ID used for the pad-specific information in `data`.
## `import`
Called from: `src/node/handler/ImportHandler.js`
@ -824,6 +1023,19 @@ Context properties:
period** (examples: `'.docx'`, `'.html'`, `'.etherpad'`).
* `padId`: The identifier of the destination pad.
* `srcFile`: The document to convert.
* `ImportError`: Subclass of Error that can be thrown to provide a specific
error message to the user. The constructor's first argument must be a string
matching one of the [known error
identifiers](https://github.com/ether/etherpad-lite/blob/1.8.16/src/static/js/pad_impexp.js#L80-L86).
Example:
```javascript
exports.import = async (hookName, {fileEnding, ImportError}) => {
// Reject all *.etherpad imports with a permission denied message.
if (fileEnding === '.etherpad') throw new ImportError('permission');
};
```
## `userJoin`

View File

@ -65,7 +65,7 @@ Portal submits content into new blog post
## Usage
### API version
The latest version is `1.2.14`
The latest version is `1.2.15`
The current version can be queried via /api.
@ -173,14 +173,15 @@ returns all pads of this group
* `{code: 0, message:"ok", data: {padIDs : ["g.s8oes9dhwrvt0zif$test", "g.s8oes9dhwrvt0zif$test2"]}`
* `{code: 1, message:"groupID does not exist", data: null}`
#### createGroupPad(groupID, padName [, text])
#### createGroupPad(groupID, padName, [text], [authorId])
* API >= 1
* `authorId` in API >= 1.3.0
creates a new pad in this group
*Example returns:*
* `{code: 0, message:"ok", data: null}`
* `{code: 1, message:"pad does already exist", data: null}`
* `{code: 0, message:"ok", data: {padID: "g.s8oes9dhwrvt0zif$test"}`
* `{code: 1, message:"padName does already exist", data: null}`
* `{code: 1, message:"groupID does not exist", data: null}`
#### listAllGroups()
@ -293,8 +294,9 @@ returns the text of a pad
* `{code: 0, message:"ok", data: {text:"Welcome Text"}}`
* `{code: 1, message:"padID does not exist", data: null}`
#### setText(padID, text)
#### setText(padID, text, [authorId])
* API >= 1
* `authorId` in API >= 1.3.0
Sets the text of a pad.
@ -305,8 +307,9 @@ If your text is long (>8 KB), please invoke via POST and include `text` paramete
* `{code: 1, message:"padID does not exist", data: null}`
* `{code: 1, message:"text too long", data: null}`
#### appendText(padID, text)
#### appendText(padID, text, [authorId])
* API >= 1.2.13
* `authorId` in API >= 1.3.0
Appends text to a pad.
@ -326,8 +329,9 @@ returns the text of a pad formatted as HTML
* `{code: 0, message:"ok", data: {html:"Welcome Text<br>More Text"}}`
* `{code: 1, message:"padID does not exist", data: null}`
#### setHTML(padID, html)
#### setHTML(padID, html, [authorId])
* API >= 1
* `authorId` in API >= 1.3.0
sets the text of a pad based on HTML, HTML must be well-formed. Malformed HTML will send a warning to the API log.
@ -387,8 +391,9 @@ returns an object of diffs from 2 points in a pad
* `{"code":0,"message":"ok","data":{"html":"<style>\n.authora_HKIv23mEbachFYfH {background-color: #a979d9}\n.authora_n4gEeMLsv1GivNeh {background-color: #a9b5d9}\n.removed {text-decoration: line-through; -ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)'; filter: alpha(opacity=80); opacity: 0.8; }\n</style>Welcome to Etherpad!<br><br>This pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!<br><br>Get involved with Etherpad at <a href=\"http&#x3a;&#x2F;&#x2F;etherpad&#x2e;org\">http:&#x2F;&#x2F;etherpad.org</a><br><span class=\"authora_HKIv23mEbachFYfH\">aw</span><br><br>","authors":["a.HKIv23mEbachFYfH",""]}}`
* `{"code":4,"message":"no or wrong API Key","data":null}`
#### restoreRevision(padId, rev)
#### restoreRevision(padId, rev, [authorId])
* API >= 1.2.11
* `authorId` in API >= 1.3.0
Restores revision from past as new changeset
@ -437,8 +442,9 @@ creates a chat message, saves it to the database and sends it to all connected c
### Pad
Group pads are normal pads, but with the name schema GROUPID$PADNAME. A security manager controls access of them and it's forbidden for normal pads to include a $ in the name.
#### createPad(padID [, text])
#### createPad(padID, [text], [authorId])
* API >= 1
* `authorId` in API >= 1.3.0
creates a new (non-group) pad. Note that if you need to create a group Pad, you should call **createGroupPad**.
You get an error message if you use one of the following characters in the padID: "/", "?", "&" or "#".
@ -519,8 +525,9 @@ copies a pad with full history and chat. If force is true and the destination pa
* `{code: 0, message:"ok", data: null}`
* `{code: 1, message:"padID does not exist", data: null}`
#### copyPadWithoutHistory(sourceID, destinationID[, force=false])
#### copyPadWithoutHistory(sourceID, destinationID, [force=false], [authorId])
* API >= 1.2.15
* `authorId` in API >= 1.3.0
copies a pad without copying the history and chat. If force is true and the destination pad exists, it will be overwritten.
Note that all the revisions will be lost! In most of the cases one should use `copyPad` API instead.
@ -559,11 +566,12 @@ returns the id of a pad which is assigned to the readOnlyID
#### setPublicStatus(padID, publicStatus)
* API >= 1
sets a boolean for the public status of a pad
sets a boolean for the public status of a group pad
*Example returns:*
* `{code: 0, message:"ok", data: null}`
* `{code: 1, message:"padID does not exist", data: null}`
* `{code: 1, message:"You can only get/set the publicStatus of pads that belong to a group", data: null}`
#### getPublicStatus(padID)
* API >= 1
@ -573,6 +581,7 @@ return true of false
*Example returns:*
* `{code: 0, message:"ok", data: {publicStatus: true}}`
* `{code: 1, message:"padID does not exist", data: null}`
* `{code: 1, message:"You can only get/set the publicStatus of pads that belong to a group", data: null}`
#### listAuthorsOfPad(padID)
* API >= 1

View File

@ -116,12 +116,12 @@ If your database needs additional settings, you will have to use a personalized
| `PAD_OPTIONS_SHOW_CHAT` | | `true` |
| `PAD_OPTIONS_SHOW_LINE_NUMBERS` | | `true` |
| `PAD_OPTIONS_USE_MONOSPACE_FONT` | | `false` |
| `PAD_OPTIONS_USER_NAME` | | `false` |
| `PAD_OPTIONS_USER_COLOR` | | `false` |
| `PAD_OPTIONS_USER_NAME` | | `null` |
| `PAD_OPTIONS_USER_COLOR` | | `null` |
| `PAD_OPTIONS_RTL` | | `false` |
| `PAD_OPTIONS_ALWAYS_SHOW_CHAT` | | `false` |
| `PAD_OPTIONS_CHAT_AND_USERS` | | `false` |
| `PAD_OPTIONS_LANG` | | `en-gb` |
| `PAD_OPTIONS_LANG` | | `null` |
### Shortcuts
@ -185,36 +185,39 @@ For the editor container, you can also make it full width by adding `full-width-
### Advanced
| Variable | Description | Default |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ |
| `SHOW_SETTINGS_IN_ADMIN_PAGE` | hide/show the settings.json in admin page | `true` |
| `TRUST_PROXY` | set to `true` if you are using a reverse proxy in front of Etherpad (for example: Traefik for SSL termination via Let's Encrypt). This will affect security and correctness of the logs if not done | `false` |
| `IMPORT_MAX_FILE_SIZE` | maximum allowed file size when importing a pad, in bytes. | `52428800` (50 MB) |
| `IMPORT_EXPORT_MAX_REQ_PER_IP` | maximum number of import/export calls per IP. | `10` |
| `IMPORT_EXPORT_RATE_LIMIT_WINDOW` | the call rate for import/export requests will be estimated in this time window (in milliseconds) | `90000` |
| `COMMIT_RATE_LIMIT_DURATION` | duration of the rate limit window for commits by individual users/IPs (in seconds) | `1` |
| `COMMIT_RATE_LIMIT_POINTS` | maximum number of changes per IP to allow during the rate limit window | `10` |
| `SUPPRESS_ERRORS_IN_PAD_TEXT` | Should we suppress errors from being visible in the default Pad Text? | `false` |
| `REQUIRE_SESSION` | If this option is enabled, a user must have a session to access pads. This effectively allows only group pads to be accessed. | `false` |
| `EDIT_ONLY` | Users may edit pads but not create new ones. Pad creation is only via the API. This applies both to group pads and regular pads. | `false` |
| `MINIFY` | If true, all css & js will be minified before sending to the client. This will improve the loading performance massively, but makes it difficult to debug the javascript/css | `true` |
| `MAX_AGE` | How long may clients use served javascript code (in seconds)? Not setting this may cause problems during deployment. Set to 0 to disable caching. | `21600` (6 hours) |
| `ABIWORD` | Absolute path to the Abiword executable. Abiword is needed to get advanced import/export features of pads. Setting it to null disables Abiword and will only allow plain text and HTML import/exports. | `null` |
| `SOFFICE` | This is the absolute path to the soffice executable. LibreOffice can be used in lieu of Abiword to export pads. Setting it to null disables LibreOffice exporting. | `null` |
| `TIDY_HTML` | Path to the Tidy executable. Tidy is used to improve the quality of exported pads. Setting it to null disables Tidy. | `null` |
| `ALLOW_UNKNOWN_FILE_ENDS` | Allow import of file types other than the supported ones: txt, doc, docx, rtf, odt, html & htm | `true` |
| `REQUIRE_AUTHENTICATION` | This setting is used if you require authentication of all users. Note: "/admin" always requires authentication. | `false` |
| `REQUIRE_AUTHORIZATION` | Require authorization by a module, or a user with is_admin set, see below. | `false` |
| `AUTOMATIC_RECONNECTION_TIMEOUT` | Time (in seconds) to automatically reconnect pad when a "Force reconnect" message is shown to user. Set to 0 to disable automatic reconnection. | `0` |
| `FOCUS_LINE_PERCENTAGE_ABOVE` | Percentage of viewport height to be additionally scrolled. e.g. 0.5, to place caret line in the middle of viewport, when user edits a line above of the viewport. Set to 0 to disable extra scrolling | `0` |
| `FOCUS_LINE_PERCENTAGE_BELOW` | Percentage of viewport height to be additionally scrolled. e.g. 0.5, to place caret line in the middle of viewport, when user edits a line below of the viewport. Set to 0 to disable extra scrolling | `0` |
| `FOCUS_LINE_PERCENTAGE_ARROW_UP` | Percentage of viewport height to be additionally scrolled when user presses arrow up in the line of the top of the viewport. Set to 0 to let the scroll to be handled as default by Etherpad | `0` |
| `FOCUS_LINE_DURATION` | Time (in milliseconds) used to animate the scroll transition. Set to 0 to disable animation | `0` |
| `FOCUS_LINE_CARET_SCROLL` | Flag to control if it should scroll when user places the caret in the last line of the viewport | `false` |
| `SOCKETIO_MAX_HTTP_BUFFER_SIZE` | The maximum size (in bytes) of a single message accepted via Socket.IO. If a client sends a larger message, its connection gets closed to prevent DoS (memory exhaustion) attacks. | `10000` |
| `LOAD_TEST` | Allow Load Testing tools to hit the Etherpad Instance. WARNING: this will disable security on the instance. | `false` |
| `DUMP_ON_UNCLEAN_EXIT` | Enable dumping objects preventing a clean exit of Node.js. WARNING: this has a significant performance impact. | `false` |
| `EXPOSE_VERSION` | Expose Etherpad version in the web interface and in the Server http header. Do not enable on production machines. | `false` |
| Variable | Description | Default |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ |
| `COOKIE_SAME_SITE` | Value of the SameSite cookie property. | `"Lax"` |
| `COOKIE_SESSION_LIFETIME` | How long (ms) a user can be away before they must log in again. | `864000000` (10 days) |
| `COOKIE_SESSION_REFRESH_INTERVAL` | How often (ms) to write the latest cookie expiration time. | `86400000` (1 day) |
| `SHOW_SETTINGS_IN_ADMIN_PAGE` | hide/show the settings.json in admin page | `true` |
| `TRUST_PROXY` | set to `true` if you are using a reverse proxy in front of Etherpad (for example: Traefik for SSL termination via Let's Encrypt). This will affect security and correctness of the logs if not done | `false` |
| `IMPORT_MAX_FILE_SIZE` | maximum allowed file size when importing a pad, in bytes. | `52428800` (50 MB) |
| `IMPORT_EXPORT_MAX_REQ_PER_IP` | maximum number of import/export calls per IP. | `10` |
| `IMPORT_EXPORT_RATE_LIMIT_WINDOW` | the call rate for import/export requests will be estimated in this time window (in milliseconds) | `90000` |
| `COMMIT_RATE_LIMIT_DURATION` | duration of the rate limit window for commits by individual users/IPs (in seconds) | `1` |
| `COMMIT_RATE_LIMIT_POINTS` | maximum number of changes per IP to allow during the rate limit window | `10` |
| `SUPPRESS_ERRORS_IN_PAD_TEXT` | Should we suppress errors from being visible in the default Pad Text? | `false` |
| `REQUIRE_SESSION` | If this option is enabled, a user must have a session to access pads. This effectively allows only group pads to be accessed. | `false` |
| `EDIT_ONLY` | Users may edit pads but not create new ones. Pad creation is only via the API. This applies both to group pads and regular pads. | `false` |
| `MINIFY` | If true, all css & js will be minified before sending to the client. This will improve the loading performance massively, but makes it difficult to debug the javascript/css | `true` |
| `MAX_AGE` | How long may clients use served javascript code (in seconds)? Not setting this may cause problems during deployment. Set to 0 to disable caching. | `21600` (6 hours) |
| `ABIWORD` | Absolute path to the Abiword executable. Abiword is needed to get advanced import/export features of pads. Setting it to null disables Abiword and will only allow plain text and HTML import/exports. | `null` |
| `SOFFICE` | This is the absolute path to the soffice executable. LibreOffice can be used in lieu of Abiword to export pads. Setting it to null disables LibreOffice exporting. | `null` |
| `TIDY_HTML` | Path to the Tidy executable. Tidy is used to improve the quality of exported pads. Setting it to null disables Tidy. | `null` |
| `ALLOW_UNKNOWN_FILE_ENDS` | Allow import of file types other than the supported ones: txt, doc, docx, rtf, odt, html & htm | `true` |
| `REQUIRE_AUTHENTICATION` | This setting is used if you require authentication of all users. Note: "/admin" always requires authentication. | `false` |
| `REQUIRE_AUTHORIZATION` | Require authorization by a module, or a user with is_admin set, see below. | `false` |
| `AUTOMATIC_RECONNECTION_TIMEOUT` | Time (in seconds) to automatically reconnect pad when a "Force reconnect" message is shown to user. Set to 0 to disable automatic reconnection. | `0` |
| `FOCUS_LINE_PERCENTAGE_ABOVE` | Percentage of viewport height to be additionally scrolled. e.g. 0.5, to place caret line in the middle of viewport, when user edits a line above of the viewport. Set to 0 to disable extra scrolling | `0` |
| `FOCUS_LINE_PERCENTAGE_BELOW` | Percentage of viewport height to be additionally scrolled. e.g. 0.5, to place caret line in the middle of viewport, when user edits a line below of the viewport. Set to 0 to disable extra scrolling | `0` |
| `FOCUS_LINE_PERCENTAGE_ARROW_UP` | Percentage of viewport height to be additionally scrolled when user presses arrow up in the line of the top of the viewport. Set to 0 to let the scroll to be handled as default by Etherpad | `0` |
| `FOCUS_LINE_DURATION` | Time (in milliseconds) used to animate the scroll transition. Set to 0 to disable animation | `0` |
| `FOCUS_LINE_CARET_SCROLL` | Flag to control if it should scroll when user places the caret in the last line of the viewport | `false` |
| `SOCKETIO_MAX_HTTP_BUFFER_SIZE` | The maximum size (in bytes) of a single message accepted via Socket.IO. If a client sends a larger message, its connection gets closed to prevent DoS (memory exhaustion) attacks. | `10000` |
| `LOAD_TEST` | Allow Load Testing tools to hit the Etherpad Instance. WARNING: this will disable security on the instance. | `false` |
| `DUMP_ON_UNCLEAN_EXIT` | Enable dumping objects preventing a clean exit of Node.js. WARNING: this has a significant performance impact. | `false` |
| `EXPOSE_VERSION` | Expose Etherpad version in the web interface and in the Server http header. Do not enable on production machines. | `false` |
### Examples

View File

@ -225,7 +225,7 @@ publish your plugin.
"author": "USERNAME (REAL NAME) <MAIL@EXAMPLE.COM>",
"contributors": [],
"dependencies": {"MODULE": "0.3.20"},
"engines": {"node": ">=12.13.0"}
"engines": {"node": ">=12.17.0"}
}
```

View File

@ -234,12 +234,12 @@
"showChat": "${PAD_OPTIONS_SHOW_CHAT:true}",
"showLineNumbers": "${PAD_OPTIONS_SHOW_LINE_NUMBERS:true}",
"useMonospaceFont": "${PAD_OPTIONS_USE_MONOSPACE_FONT:false}",
"userName": "${PAD_OPTIONS_USER_NAME:false}",
"userColor": "${PAD_OPTIONS_USER_COLOR:false}",
"userName": "${PAD_OPTIONS_USER_NAME:null}",
"userColor": "${PAD_OPTIONS_USER_COLOR:null}",
"rtl": "${PAD_OPTIONS_RTL:false}",
"alwaysShowChat": "${PAD_OPTIONS_ALWAYS_SHOW_CHAT:false}",
"chatAndUsers": "${PAD_OPTIONS_CHAT_AND_USERS:false}",
"lang": "${PAD_OPTIONS_LANG:en-gb}"
"lang": "${PAD_OPTIONS_LANG:null}"
},
/*
@ -374,7 +374,51 @@
* significant usability drawbacks vs. "Lax". See
* https://stackoverflow.com/q/41841880 for discussion.
*/
"sameSite": "${COOKIE_SAME_SITE:Lax}"
"sameSite": "${COOKIE_SAME_SITE:Lax}",
/*
* How long (in milliseconds) after navigating away from Etherpad before the
* user is required to log in again. (The express_sid cookie is set to
* expire at time now + sessionLifetime when first created, and its
* expiration time is periodically refreshed to a new now + sessionLifetime
* value.) If requireAuthentication is false then this value does not really
* matter.
*
* The "best" value depends on your users' usage patterns and the amount of
* convenience you desire. A long lifetime is more convenient (users won't
* have to log back in as often) but has some drawbacks:
* - It increases the amount of state kept in the database.
* - It might weaken security somewhat: The cookie expiration is refreshed
* indefinitely without consulting authentication or authorization
* hooks, so once a user has accessed a pad, the user can continue to
* use the pad until the user leaves for longer than sessionLifetime.
*
* Session lifetime can be set to infinity (not recommended) by setting this
* to null or 0. Note that if the session does not expire, most browsers
* will delete the cookie when the browser exits, but a session record is
* kept in the database forever.
*/
// 864000000 = 10d * 24h/d * 60m/h * 60s/m * 1000ms/s
"sessionLifetime": "${COOKIE_SESSION_LIFETIME:864000000}",
/*
* How long (in milliseconds) before the expiration time of an active user's
* session is refreshed (to now + sessionLifetime). This setting affects the
* following:
* - How often a new session expiration time will be written to the
* database.
* - How often each user's browser will ping the Etherpad server to
* refresh the expiration time of the session cookie.
*
* High values reduce the load on the database and the load from browsers,
* but can shorten the effective session lifetime if Etherpad is restarted
* or the user navigates away.
*
* Automatic session refreshes can be disabled (not recommended) by setting
* this to null.
*/
// 86400000 = 1d * 24h/d * 60m/h * 60s/m * 1000ms/s
"sessionRefreshInterval": "${COOKIE_SESSION_REFRESH_INTERVAL:86400000}"
},
/*
@ -587,5 +631,8 @@
"loglevel": "${LOGLEVEL:INFO}",
/* Override any strings found in locale directories */
"customLocaleStrings": {}
"customLocaleStrings": {},
/* Disable Admin UI tests */
"enableAdminUITests": false
}

View File

@ -235,12 +235,12 @@
"showChat": true,
"showLineNumbers": true,
"useMonospaceFont": false,
"userName": false,
"userColor": false,
"userName": null,
"userColor": null,
"rtl": false,
"alwaysShowChat": false,
"chatAndUsers": false,
"lang": "en-gb"
"lang": null
},
/*
@ -375,7 +375,49 @@
* significant usability drawbacks vs. "Lax". See
* https://stackoverflow.com/q/41841880 for discussion.
*/
"sameSite": "Lax"
"sameSite": "Lax",
/*
* How long (in milliseconds) after navigating away from Etherpad before the
* user is required to log in again. (The express_sid cookie is set to
* expire at time now + sessionLifetime when first created, and its
* expiration time is periodically refreshed to a new now + sessionLifetime
* value.) If requireAuthentication is false then this value does not really
* matter.
*
* The "best" value depends on your users' usage patterns and the amount of
* convenience you desire. A long lifetime is more convenient (users won't
* have to log back in as often) but has some drawbacks:
* - It increases the amount of state kept in the database.
* - It might weaken security somewhat: The cookie expiration is refreshed
* indefinitely without consulting authentication or authorization
* hooks, so once a user has accessed a pad, the user can continue to
* use the pad until the user leaves for longer than sessionLifetime.
*
* Session lifetime can be set to infinity (not recommended) by setting this
* to null or 0. Note that if the session does not expire, most browsers
* will delete the cookie when the browser exits, but a session record is
* kept in the database forever.
*/
"sessionLifetime": 864000000, // = 10d * 24h/d * 60m/h * 60s/m * 1000ms/s
/*
* How long (in milliseconds) before the expiration time of an active user's
* session is refreshed (to now + sessionLifetime). This setting affects the
* following:
* - How often a new session expiration time will be written to the
* database.
* - How often each user's browser will ping the Etherpad server to
* refresh the expiration time of the session cookie.
*
* High values reduce the load on the database and the load from browsers,
* but can shorten the effective session lifetime if Etherpad is restarted
* or the user navigates away.
*
* Automatic session refreshes can be disabled (not recommended) by setting
* this to null.
*/
"sessionRefreshInterval": 86400000 // = 1d * 24h/d * 60m/h * 60s/m * 1000ms/s
},
/*
@ -550,7 +592,6 @@
"points": 10
},
/*
* Toolbar buttons configuration.
*

141
src/.eslintrc.cjs Normal file
View File

@ -0,0 +1,141 @@
'use strict';
// This is a workaround for https://github.com/eslint/eslint/issues/3458
require('eslint-config-etherpad/patch/modern-module-resolution');
module.exports = {
ignorePatterns: [
'/static/js/admin/jquery.autosize.js',
'/static/js/admin/minify.json.js',
'/static/js/vendors/browser.js',
'/static/js/vendors/farbtastic.js',
'/static/js/vendors/gritter.js',
'/static/js/vendors/html10n.js',
'/static/js/vendors/jquery.js',
'/static/js/vendors/nice-select.js',
'/tests/frontend/lib/',
],
overrides: [
{
files: [
'**/.eslintrc.*',
],
extends: 'etherpad/node',
},
{
files: [
'**/*',
],
excludedFiles: [
'**/.eslintrc.*',
'tests/frontend/**/*',
],
extends: 'etherpad/node',
},
{
files: [
'static/**/*',
'tests/frontend/helper.js',
'tests/frontend/helper/**/*',
],
excludedFiles: [
'**/.eslintrc.*',
],
extends: 'etherpad/browser',
env: {
'shared-node-browser': true,
},
overrides: [
{
files: [
'tests/frontend/helper/**/*',
],
globals: {
helper: 'readonly',
},
},
],
},
{
files: [
'tests/**/*',
],
excludedFiles: [
'**/.eslintrc.*',
'tests/frontend/cypress/**/*',
'tests/frontend/helper.js',
'tests/frontend/helper/**/*',
'tests/frontend/travis/**/*',
'tests/ratelimit/**/*',
],
extends: 'etherpad/tests',
rules: {
'mocha/no-exports': 'off',
'mocha/no-top-level-hooks': 'off',
},
},
{
files: [
'tests/backend/**/*',
],
excludedFiles: [
'**/.eslintrc.*',
],
extends: 'etherpad/tests/backend',
overrides: [
{
files: [
'tests/backend/**/*',
],
excludedFiles: [
'tests/backend/specs/**/*',
],
rules: {
'mocha/no-exports': 'off',
'mocha/no-top-level-hooks': 'off',
},
},
],
},
{
files: [
'tests/frontend/**/*',
],
excludedFiles: [
'**/.eslintrc.*',
'tests/frontend/cypress/**/*',
'tests/frontend/helper.js',
'tests/frontend/helper/**/*',
'tests/frontend/travis/**/*',
],
extends: 'etherpad/tests/frontend',
overrides: [
{
files: [
'tests/frontend/**/*',
],
excludedFiles: [
'tests/frontend/specs/**/*',
],
rules: {
'mocha/no-exports': 'off',
'mocha/no-top-level-hooks': 'off',
},
},
],
},
{
files: [
'tests/frontend/cypress/**/*',
],
extends: 'etherpad/tests/cypress',
},
{
files: [
'tests/frontend/travis/**/*',
],
extends: 'etherpad/node',
},
],
root: true,
};

View File

@ -1,62 +1,57 @@
#!/bin/sh
set -e
pecho() { printf %s\\n "$*"; }
log() { pecho "$@"; }
error() { log "ERROR: $@" >&2; }
fatal() { error "$@"; exit 1; }
try() { "$@" || fatal "'$@' failed"; }
is_cmd() { command -v "$@" >/dev/null 2>&1; }
# Move to the folder where ep-lite is installed
cd "$(cd "${0%/*}" && pwd -P)/../.."
for x in git unzip wget zip; do
is_cmd "${x}" || fatal "Please install ${x}"
done
# Is wget installed?
is_cmd wget || fatal "Please install wget"
# Move to the folder where Etherpad is checked out
try cd "${0%/*}"
workdir=$(try git rev-parse --show-toplevel) || exit 1
try cd "${workdir}"
[ -f src/package.json ] || fatal "failed to cd to etherpad root directory"
# Is zip installed?
is_cmd zip || fatal "Please install zip"
OUTPUT=${workdir}/etherpad-win.zip
# Is zip installed?
is_cmd unzip || fatal "Please install unzip"
START_FOLDER=$(pwd);
TMP_FOLDER=$(mktemp -d)
TMP_FOLDER=$(try mktemp -d) || exit 1
trap 'exit 1' HUP INT TERM
trap 'log "cleaning up..."; try cd / && try rm -rf "${TMP_FOLDER}"' EXIT
log "create a clean environment in $TMP_FOLDER..."
cp -ar . "$TMP_FOLDER"
cd "$TMP_FOLDER"
rm -rf node_modules
rm -f etherpad-lite-win.zip
try git archive --format=tar HEAD | (try cd "${TMP_FOLDER}" && try tar xf -) \
|| fatal "failed to copy etherpad to temporary folder"
try mkdir "${TMP_FOLDER}"/.git
try git rev-parse HEAD >${TMP_FOLDER}/.git/HEAD
try cd "${TMP_FOLDER}"
[ -f src/package.json ] || fatal "failed to copy etherpad to temporary folder"
# setting NODE_ENV=production ensures that dev dependencies are not installed,
# making the windows package smaller
export NODE_ENV=production
log "do a normal unix install first..."
src/bin/installDeps.sh || exit 1
try ./src/bin/installDeps.sh
log "copy the windows settings template..."
cp settings.json.template settings.json
try cp settings.json.template settings.json
log "resolve symbolic links..."
cp -rL node_modules node_modules_resolved
rm -rf node_modules
mv node_modules_resolved node_modules
try cp -rL node_modules node_modules_resolved
try rm -rf node_modules
try mv node_modules_resolved node_modules
log "download windows node..."
wget "https://nodejs.org/dist/latest-erbium/win-x86/node.exe" -O node.exe
log "remove git history to reduce folder size"
rm -rf .git/objects
log "remove windows jsdom-nocontextify/test folder"
rm -rf "$TMP_FOLDER"/src/node_modules/wd/node_modules/request/node_modules/form-data/node_modules/combined-stream/test
rm -rf "$TMP_FOLDER"/src/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib/node_modules/encoding/node_modules/iconv-lite/encodings/tables
try wget "https://nodejs.org/dist/latest-v16.x/win-x64/node.exe" -O node.exe
log "create the zip..."
cd "$TMP_FOLDER"
zip -9 -r "$START_FOLDER"/etherpad-lite-win.zip ./* -x var
try zip -9 -r "${OUTPUT}" ./*
log "clean up..."
rm -rf "$TMP_FOLDER"
log "Finished. You can find the zip in the Etherpad root folder, it's called etherpad-lite-win.zip"
log "Finished. You can find the zip at ${OUTPUT}"

View File

@ -145,12 +145,12 @@ function push_builds {
cd $TMP_DIR/etherpad-lite/
echo "Copying windows build and docs to website repo..."
GIT_SHA=$(git rev-parse HEAD | cut -c1-10)
mv etherpad-lite-win.zip $TMP_DIR/ether.github.com/downloads/etherpad-lite-win-$VERSION-$GIT_SHA.zip
mv etherpad-win.zip $TMP_DIR/ether.github.com/downloads/etherpad-win-$VERSION-$GIT_SHA.zip
mv out/doc $TMP_DIR/ether.github.com/doc/v$VERSION
cd $TMP_DIR/ether.github.com/
sed -i "s/etherpad-lite-win.*\.zip/etherpad-lite-win-$VERSION-$GIT_SHA.zip/" index.html
sed -i "s/etherpad-win.*\.zip/etherpad-win-$VERSION-$GIT_SHA.zip/" index.html
sed -i "s/$LATEST_GIT_TAG/$VERSION/g" index.html
git checkout -b release_$VERSION
[[ $? != 0 ]] && echo "Aborting: Error creating new release branch" && exit 1

View File

@ -5,9 +5,9 @@
"requires": true,
"dependencies": {
"marked": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz",
"integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA=="
"version": "4.2.12",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.2.12.tgz",
"integrity": "sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw=="
}
}
}

View File

@ -4,10 +4,10 @@
"description": "Internal tool for generating Node.js API docs",
"version": "0.0.0",
"engines": {
"node": ">=12.13.0"
"node": ">=12.17.0"
},
"dependencies": {
"marked": "^2.0.0"
"marked": "^4.2.12"
},
"devDependencies": {},
"optionalDependencies": {},

26
src/bin/etherpad-healthcheck Executable file
View File

@ -0,0 +1,26 @@
#!/usr/bin/env node
// Checks the health of Etherpad by visiting http://localhost:9001/health. Returns 0 on success, 1
// on error as required by the Dockerfile HEALTHCHECK instruction.
'use strict';
// As of v14, Node.js does not exit when there is an unhandled Promise rejection. Convert an
// unhandled rejection into an uncaught exception, which does cause Node.js to exit.
process.on('unhandledRejection', (err) => { throw err; });
const assert = require('assert').strict;
const superagent = require('superagent');
(async () => {
const res = await superagent.get('http://localhost:9001/health')
.accept('application/health+json')
.buffer(true)
.parse(superagent.parse['application/json']);
assert(res.ok, `Unexpected HTTP status: ${res.status}`);
assert.equal(res.type, 'application/health+json');
const {body: {status} = {}} = res;
assert(status != null);
assert.equal(typeof status, 'string');
assert(['pass', 'ok', 'up'].includes(status.toLowerCase()), `Unexpected status: ${status}`);
})();

View File

@ -30,9 +30,7 @@ const padId = process.argv[2];
// initialize output database
const dirty = dirtyDB(`${padId}.db`);
// Promise wrapped get and set function
const wrapped = db.db.db.wrappedDB;
const get = util.promisify(wrapped.get.bind(wrapped));
// Promise set function
const set = util.promisify(dirty.set.bind(dirty));
// array in which required key values will be accumulated
@ -55,7 +53,7 @@ const padId = process.argv[2];
}
for (const dbkey of neededDBValues) {
let dbvalue = await get(dbkey);
let dbvalue = await db.get(dbkey);
if (dbvalue && typeof dbvalue !== 'object') {
dbvalue = JSON.parse(dbvalue);
}

9
src/bin/nsis/README.md Normal file
View File

@ -0,0 +1,9 @@
A simple NSIS script to Install Etherpad (Server) on Windows and start it.
# TODO
1. i18n
1. Run as Service
1. Display messages during install
# License
Apache 2

BIN
src/bin/nsis/brand.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

55
src/bin/nsis/etherpad.nsi Normal file
View File

@ -0,0 +1,55 @@
;Include Modern UI
!include "MUI2.nsh"
!include x64.nsh
;--------------------------------
;Styling
!define MUI_ICON "brand.ico"
Icon "brand.ico"
BrandingText "Etherpad Foundation"
Name "Etherpad Server"
OutFile "..\..\..\etherpad-win.exe"
!insertmacro MUI_LANGUAGE "English"
Page directory
Page instfiles
; The default installation directory
InstallDir "$PROGRAMFILES64\Etherpad Foundation\Etherpad Server"
Section
SectionIn RO
${If} ${RunningX64}
DetailPrint "Installer running on x64 host"
${Else}
Abort "Unsupported CPU architecture (only x64 is supported)"
${Endif}
; Set output path to the installation directory.
SetOutPath $INSTDIR
; Put files there
File /r "..\..\..\..\etherpad-zip\*"
SectionEnd
Section
CreateDirectory "$SMPROGRAMS\Etherpad Foundation"
CreateShortCut "$SMPROGRAMS\Etherpad Foundation\Etherpad Server.lnk" "$INSTDIR\start.bat" "brand.ico" "Etherpad Server"
CreateShortCut "$SMPROGRAMS\Etherpad Foundation\Etherpad.lnk" "http://127.0.0.1:9001" "brand.ico" "Etherpad"
CreateShortCut "$SMPROGRAMS\Etherpad Foundation\Etherpad Admin.lnk" "http://127.0.0.1:9001/admin" "brand.ico" "Etherpad Admin"
CreateShortCut "$SMPROGRAMS\Etherpad Foundation\Uninstall Etherpad Server.lnk" "$INSTDIR\uninstall.exe"
WriteUninstaller "$INSTDIR\uninstall.exe"
Exec '$INSTDIR\start.bat'
SectionEnd
UninstPage instfiles
Section Uninstall
Delete "$INSTDIR\*"
Delete "$INSTDIR\uninstall.exe"
RMDir "$INSTDIR"
SetAutoClose false
SectionEnd

View File

@ -21,12 +21,18 @@ node src/bin/plugins/checkPlugin.js ep_webrtc
node src/bin/plugins/checkPlugin.js ep_whatever autofix
```
## Autocommitting, push, npm minor patch and npm publish (highly dangerous)
## Autocommitting - fix issues and commit
```
node src/bin/plugins/checkPlugin.js ep_whatever autocommit
```
## Autopush - fix issues, commit, push, and publish (highly dangerous)
```
node src/bin/plugins/checkPlugin.js ep_whatever autopush
```
# All the plugins
Replace johnmclear with your github username

View File

@ -5,423 +5,377 @@
*
* Normal usage: node src/bin/plugins/checkPlugin.js ep_whatever
* Auto fix the things it can: node src/bin/plugins/checkPlugin.js ep_whatever autofix
* Auto commit, push and publish to npm (highly dangerous):
* node src/bin/plugins/checkPlugin.js ep_whatever autocommit
* Auto fix and commit: node src/bin/plugins/checkPlugin.js ep_whatever autocommit
* Auto fix, commit, push and publish to npm (highly dangerous):
* node src/bin/plugins/checkPlugin.js ep_whatever autopush
*/
const process = require('process');
// As of v14, Node.js does not exit when there is an unhandled Promise rejection. Convert an
// unhandled rejection into an uncaught exception, which does cause Node.js to exit.
process.on('unhandledRejection', (err) => { throw err; });
const assert = require('assert').strict;
const fs = require('fs');
const fsp = fs.promises;
const childProcess = require('child_process');
const log4js = require('log4js');
const path = require('path');
// get plugin name & path from user input
const pluginName = process.argv[2];
const logger = log4js.getLogger('checkPlugin');
if (!pluginName) throw new Error('no plugin name specified');
(async () => {
// get plugin name & path from user input
const pluginName = process.argv[2];
const pluginPath = `node_modules/${pluginName}`;
if (!pluginName) throw new Error('no plugin name specified');
logger.info(`Checking the plugin: ${pluginName}`);
console.log(`Checking the plugin: ${pluginName}`);
const epRootDir = await fsp.realpath(path.join(await fsp.realpath(__dirname), '../../..'));
logger.info(`Etherpad root directory: ${epRootDir}`);
process.chdir(epRootDir);
const pluginPath = await fsp.realpath(`node_modules/${pluginName}`);
logger.info(`Plugin directory: ${pluginPath}`);
const epSrcDir = await fsp.realpath(path.join(epRootDir, 'src'));
const optArgs = process.argv.slice(3);
const autoCommit = optArgs.indexOf('autocommit') !== -1;
const autoFix = autoCommit || optArgs.indexOf('autofix') !== -1;
const optArgs = process.argv.slice(3);
const autoPush = optArgs.includes('autopush');
const autoCommit = autoPush || optArgs.includes('autocommit');
const autoFix = autoCommit || optArgs.includes('autofix');
const execSync = (cmd, opts = {}) => (childProcess.execSync(cmd, {
cwd: `${pluginPath}/`,
...opts,
}) || '').toString().replace(/\n+$/, '');
const execSync = (cmd, opts = {}) => (childProcess.execSync(cmd, {
cwd: `${pluginPath}/`,
...opts,
}) || '').toString().replace(/\n+$/, '');
const writePackageJson = (obj) => {
let s = JSON.stringify(obj, null, 2);
if (s.length && s.slice(s.length - 1) !== '\n') s += '\n';
return fs.writeFileSync(`${pluginPath}/package.json`, s);
};
const writePackageJson = async (obj) => {
let s = JSON.stringify(obj, null, 2);
if (s.length && s.slice(s.length - 1) !== '\n') s += '\n';
return await fsp.writeFile(`${pluginPath}/package.json`, s);
};
const updateDeps = (parsedPackageJson, key, wantDeps) => {
const {[key]: deps = {}} = parsedPackageJson;
let changed = false;
for (const [pkg, verInfo] of Object.entries(wantDeps)) {
const {ver, overwrite = true} = typeof verInfo === 'string' ? {ver: verInfo} : verInfo;
if (deps[pkg] === ver) continue;
if (deps[pkg] == null) {
console.warn(`Missing dependency in ${key}: '${pkg}': '${ver}'`);
} else {
if (!overwrite) continue;
console.warn(`Dependency mismatch in ${key}: '${pkg}': '${ver}' (current: ${deps[pkg]})`);
const checkEntries = (got, want) => {
let changed = false;
for (const [key, val] of Object.entries(want)) {
try {
assert.deepEqual(got[key], val);
} catch (err) {
logger.warn(`${key} possibly outdated.`);
logger.warn(err.message);
if (autoFix) {
got[key] = val;
changed = true;
}
}
}
if (autoFix) {
deps[pkg] = ver;
changed = true;
return changed;
};
const updateDeps = async (parsedPackageJson, key, wantDeps) => {
const {[key]: deps = {}} = parsedPackageJson;
let changed = false;
for (const [pkg, verInfo] of Object.entries(wantDeps)) {
const {ver, overwrite = true} =
typeof verInfo === 'string' || verInfo == null ? {ver: verInfo} : verInfo;
if (deps[pkg] === ver || (deps[pkg] == null && ver == null)) continue;
if (deps[pkg] == null) {
logger.warn(`Missing dependency in ${key}: '${pkg}': '${ver}'`);
} else {
if (!overwrite) continue;
logger.warn(`Dependency mismatch in ${key}: '${pkg}': '${ver}' (current: ${deps[pkg]})`);
}
if (autoFix) {
if (ver == null) delete deps[pkg];
else deps[pkg] = ver;
changed = true;
}
}
}
if (changed) {
parsedPackageJson[key] = deps;
writePackageJson(parsedPackageJson);
}
};
if (changed) {
parsedPackageJson[key] = deps;
await writePackageJson(parsedPackageJson);
}
};
const prepareRepo = () => {
let branch = execSync('git symbolic-ref HEAD');
if (branch !== 'refs/heads/master' && branch !== 'refs/heads/main') {
throw new Error('master/main must be checked out');
}
branch = branch.replace(/^refs\/heads\//, '');
execSync('git rev-parse --verify -q HEAD^0 || ' +
`{ echo "Error: no commits on ${branch}" >&2; exit 1; }`);
execSync('git rev-parse --verify @{u}'); // Make sure there's a remote tracking branch.
const modified = execSync('git diff-files --name-status');
if (modified !== '') throw new Error(`working directory has modifications:\n${modified}`);
const untracked = execSync('git ls-files -o --exclude-standard');
if (untracked !== '') throw new Error(`working directory has untracked files:\n${untracked}`);
const indexStatus = execSync('git diff-index --cached --name-status HEAD');
if (indexStatus !== '') throw new Error(`uncommitted staged changes to files:\n${indexStatus}`);
execSync('git pull --ff-only', {stdio: 'inherit'});
if (execSync('git rev-list @{u}...') !== '') throw new Error('repo contains unpushed commits');
if (autoCommit) {
execSync('git config --get user.name');
execSync('git config --get user.email');
}
};
const prepareRepo = () => {
const modified = execSync('git diff-files --name-status');
if (modified !== '') throw new Error(`working directory has modifications:\n${modified}`);
const untracked = execSync('git ls-files -o --exclude-standard');
if (untracked !== '') throw new Error(`working directory has untracked files:\n${untracked}`);
const indexStatus = execSync('git diff-index --cached --name-status HEAD');
if (indexStatus !== '') throw new Error(`uncommitted staged changes to files:\n${indexStatus}`);
let br;
if (autoCommit) {
br = execSync('git symbolic-ref HEAD');
if (!br.startsWith('refs/heads/')) throw new Error('detached HEAD');
br = br.replace(/^refs\/heads\//, '');
execSync('git rev-parse --verify -q HEAD^0 || ' +
`{ echo "Error: no commits on ${br}" >&2; exit 1; }`);
execSync('git config --get user.name');
execSync('git config --get user.email');
}
if (autoPush) {
if (!['master', 'main'].includes(br)) throw new Error('master/main not checked out');
execSync('git rev-parse --verify @{u}');
execSync('git pull --ff-only', {stdio: 'inherit'});
if (execSync('git rev-list @{u}...') !== '') throw new Error('repo contains unpushed commits');
}
};
if (autoCommit) {
console.warn('Auto commit is enabled, I hope you know what you are doing...');
}
const checkFile = async (srcFn, dstFn, overwrite = true) => {
const outFn = path.join(pluginPath, dstFn);
const wantContents = await fsp.readFile(srcFn, {encoding: 'utf8'});
let gotContents = null;
try {
gotContents = await fsp.readFile(outFn, {encoding: 'utf8'});
} catch (err) { /* treat as if the file doesn't exist */ }
try {
assert.equal(gotContents, wantContents);
} catch (err) {
logger.warn(`File ${dstFn} does not match the default`);
logger.warn(err.message);
if (!overwrite && gotContents != null) {
logger.warn('Leaving existing contents alone.');
return;
}
if (autoFix) {
await fsp.mkdir(path.dirname(outFn), {recursive: true});
await fsp.writeFile(outFn, wantContents);
}
}
};
fs.readdir(pluginPath, (err, rootFiles) => {
// handling error
if (err) {
return console.log(`Unable to scan directory: ${err}`);
if (autoPush) {
logger.warn('Auto push is enabled, I hope you know what you are doing...');
}
// rewriting files to lower case
const files = [];
const files = await fsp.readdir(pluginPath);
// some files we need to know the actual file name. Not compulsory but might help in the future.
let readMeFileName;
let repository;
const readMeFileName = files.filter((f) => f === 'README' || f === 'README.md')[0];
for (let i = 0; i < rootFiles.length; i++) {
if (rootFiles[i].toLowerCase().indexOf('readme') !== -1) readMeFileName = rootFiles[i];
files.push(rootFiles[i].toLowerCase());
}
if (files.indexOf('.git') === -1) throw new Error('No .git folder, aborting');
if (!files.includes('.git')) throw new Error('No .git folder, aborting');
prepareRepo();
try {
const path = `${pluginPath}/.github/workflows/npmpublish.yml`;
if (!fs.existsSync(path)) {
console.log('no .github/workflows/npmpublish.yml');
console.log('create one and set npm secret to auto publish to npm on commit');
if (autoFix) {
const npmpublish =
fs.readFileSync('src/bin/plugins/lib/npmpublish.yml', {encoding: 'utf8', flag: 'r'});
fs.mkdirSync(`${pluginPath}/.github/workflows`, {recursive: true});
fs.writeFileSync(path, npmpublish);
console.log("If you haven't already, setup autopublish for this plugin https://github.com/ether/etherpad-lite/wiki/Plugins:-Automatically-publishing-to-npm-on-commit-to-Github-Repo");
} else {
console.log('Setup autopublish for this plugin https://github.com/ether/etherpad-lite/wiki/Plugins:-Automatically-publishing-to-npm-on-commit-to-Github-Repo');
}
} else {
// autopublish exists, we should check the version..
// checkVersion takes two file paths and checks for a version string in them.
const currVersionFile = fs.readFileSync(path, {encoding: 'utf8', flag: 'r'});
const existingConfigLocation = currVersionFile.indexOf('##ETHERPAD_NPM_V=');
const existingValue = parseInt(
currVersionFile.substr(existingConfigLocation + 17, existingConfigLocation.length));
const workflows = ['backend-tests.yml', 'frontend-tests.yml', 'npmpublish.yml'];
await Promise.all(workflows.map(async (fn) => {
await checkFile(`src/bin/plugins/lib/${fn}`, `.github/workflows/${fn}`);
}));
await checkFile('src/bin/plugins/lib/dependabot.yml', '.github/dependabot.yml');
const reqVersionFile =
fs.readFileSync('src/bin/plugins/lib/npmpublish.yml', {encoding: 'utf8', flag: 'r'});
const reqConfigLocation = reqVersionFile.indexOf('##ETHERPAD_NPM_V=');
const reqValue =
parseInt(reqVersionFile.substr(reqConfigLocation + 17, reqConfigLocation.length));
if (!existingValue || (reqValue > existingValue)) {
const npmpublish =
fs.readFileSync('src/bin/plugins/lib/npmpublish.yml', {encoding: 'utf8', flag: 'r'});
fs.mkdirSync(`${pluginPath}/.github/workflows`, {recursive: true});
fs.writeFileSync(path, npmpublish);
}
}
} catch (err) {
console.error(err);
}
try {
const path = `${pluginPath}/.github/workflows/backend-tests.yml`;
if (!fs.existsSync(path)) {
console.log('no .github/workflows/backend-tests.yml');
console.log('create one and set npm secret to auto publish to npm on commit');
if (autoFix) {
const backendTests =
fs.readFileSync('src/bin/plugins/lib/backend-tests.yml', {encoding: 'utf8', flag: 'r'});
fs.mkdirSync(`${pluginPath}/.github/workflows`, {recursive: true});
fs.writeFileSync(path, backendTests);
}
} else {
// autopublish exists, we should check the version..
// checkVersion takes two file paths and checks for a version string in them.
const currVersionFile = fs.readFileSync(path, {encoding: 'utf8', flag: 'r'});
const existingConfigLocation = currVersionFile.indexOf('##ETHERPAD_NPM_V=');
const existingValue = parseInt(
currVersionFile.substr(existingConfigLocation + 17, existingConfigLocation.length));
const reqVersionFile =
fs.readFileSync('src/bin/plugins/lib/backend-tests.yml', {encoding: 'utf8', flag: 'r'});
const reqConfigLocation = reqVersionFile.indexOf('##ETHERPAD_NPM_V=');
const reqValue =
parseInt(reqVersionFile.substr(reqConfigLocation + 17, reqConfigLocation.length));
if (!existingValue || (reqValue > existingValue)) {
const backendTests =
fs.readFileSync('src/bin/plugins/lib/backend-tests.yml', {encoding: 'utf8', flag: 'r'});
fs.mkdirSync(`${pluginPath}/.github/workflows`, {recursive: true});
fs.writeFileSync(path, backendTests);
}
}
} catch (err) {
console.error(err);
}
if (files.indexOf('package.json') === -1) {
console.warn('no package.json, please create');
}
if (files.indexOf('package.json') !== -1) {
if (!files.includes('package.json')) {
logger.warn('no package.json, please create');
} else {
const packageJSON =
fs.readFileSync(`${pluginPath}/package.json`, {encoding: 'utf8', flag: 'r'});
await fsp.readFile(`${pluginPath}/package.json`, {encoding: 'utf8', flag: 'r'});
const parsedPackageJSON = JSON.parse(packageJSON);
if (autoFix) {
let updatedPackageJSON = false;
if (!parsedPackageJSON.funding) {
updatedPackageJSON = true;
parsedPackageJSON.funding = {
type: 'individual',
url: 'https://etherpad.org/',
};
}
if (updatedPackageJSON) {
writePackageJson(parsedPackageJSON);
}
}
if (packageJSON.toLowerCase().indexOf('repository') === -1) {
console.warn('No repository in package.json');
if (autoFix) {
console.warn('Repository not detected in package.json. Add repository section.');
}
} else {
// useful for creating README later.
repository = parsedPackageJSON.repository.url;
}
updateDeps(parsedPackageJSON, 'devDependencies', {
'eslint': '^7.28.0',
'eslint-config-etherpad': '^2.0.0',
'eslint-plugin-cypress': '^2.11.3',
'eslint-plugin-eslint-comments': '^3.2.0',
'eslint-plugin-mocha': '^9.0.0',
'eslint-plugin-node': '^11.1.0',
'eslint-plugin-prefer-arrow': '^1.2.3',
'eslint-plugin-promise': '^5.1.0',
'eslint-plugin-you-dont-need-lodash-underscore': '^6.12.0',
await updateDeps(parsedPackageJSON, 'devDependencies', {
'eslint': '^8.14.0',
'eslint-config-etherpad': '^3.0.13',
// Changing the TypeScript version can break plugin code, so leave it alone if present.
'typescript': {ver: '^4.6.4', overwrite: false},
// These were moved to eslint-config-etherpad's dependencies so they can be removed:
'@typescript-eslint/eslint-plugin': null,
'@typescript-eslint/parser': null,
'eslint-import-resolver-typescript': null,
'eslint-plugin-cypress': null,
'eslint-plugin-eslint-comments': null,
'eslint-plugin-import': null,
'eslint-plugin-mocha': null,
'eslint-plugin-node': null,
'eslint-plugin-prefer-arrow': null,
'eslint-plugin-promise': null,
'eslint-plugin-you-dont-need-lodash-underscore': null,
});
updateDeps(parsedPackageJSON, 'peerDependencies', {
await updateDeps(parsedPackageJSON, 'peerDependencies', {
// Some plugins require a newer version of Etherpad so don't overwrite if already set.
'ep_etherpad-lite': {ver: '>=1.8.6', overwrite: false},
});
if (packageJSON.toLowerCase().indexOf('eslintconfig') === -1) {
console.warn('No esLintConfig in package.json');
if (autoFix) {
const eslintConfig = {
root: true,
extends: 'etherpad/plugin',
};
parsedPackageJSON.eslintConfig = eslintConfig;
writePackageJson(parsedPackageJSON);
}
}
await updateDeps(parsedPackageJSON, 'engines', {
node: '>=12.17.0',
});
if (packageJSON.toLowerCase().indexOf('scripts') === -1) {
console.warn('No scripts in package.json');
if (autoFix) {
const scripts = {
'lint': 'eslint .',
'lint:fix': 'eslint --fix .',
};
parsedPackageJSON.scripts = scripts;
writePackageJson(parsedPackageJSON);
}
if (parsedPackageJSON.eslintConfig != null && autoFix) {
delete parsedPackageJSON.eslintConfig;
await writePackageJson(parsedPackageJSON);
}
if ((packageJSON.toLowerCase().indexOf('engines') === -1) || !parsedPackageJSON.engines.node) {
console.warn('No engines or node engine in package.json');
if (autoFix) {
const engines = {
node: '>=12.13.0',
};
parsedPackageJSON.engines = engines;
writePackageJson(parsedPackageJSON);
}
}
}
if (files.indexOf('package-lock.json') === -1) {
console.warn('package-lock.json not found');
if (!autoFix) {
console.warn('Run npm install in the plugin folder and commit the package-lock.json file.');
}
}
if (files.indexOf('readme') === -1 && files.indexOf('readme.md') === -1) {
console.warn('README.md file not found, please create');
if (autoFix) {
console.log('Autofixing missing README.md file');
console.log('please edit the README.md file further to include plugin specific details.');
let readme = fs.readFileSync('src/bin/plugins/lib/README.md', {encoding: 'utf8', flag: 'r'});
readme = readme.replace(/\[plugin_name\]/g, pluginName);
if (repository) {
const org = repository.split('/')[3];
const name = repository.split('/')[4];
readme = readme.replace(/\[org_name\]/g, org);
readme = readme.replace(/\[repo_url\]/g, name);
fs.writeFileSync(`${pluginPath}/README.md`, readme);
if (files.includes('.eslintrc.js')) {
const [from, to] = [`${pluginPath}/.eslintrc.js`, `${pluginPath}/.eslintrc.cjs`];
if (!files.includes('.eslintrc.cjs')) {
if (autoFix) {
await fsp.rename(from, to);
} else {
logger.warn(`please rename ${from} to ${to}`);
}
} else {
console.warn('Unable to find repository in package.json, aborting.');
logger.error(`both ${from} and ${to} exist; delete ${from}`);
}
} else {
checkFile('src/bin/plugins/lib/eslintrc.cjs', '.eslintrc.cjs', false);
}
if (checkEntries(parsedPackageJSON, {
funding: {
type: 'individual',
url: 'https://etherpad.org/',
},
})) await writePackageJson(parsedPackageJSON);
if (parsedPackageJSON.scripts == null) parsedPackageJSON.scripts = {};
if (checkEntries(parsedPackageJSON.scripts, {
'lint': 'eslint .',
'lint:fix': 'eslint --fix .',
})) await writePackageJson(parsedPackageJSON);
}
if (!files.includes('package-lock.json')) {
logger.warn('package-lock.json not found');
if (!autoFix) {
logger.warn('Run npm install in the plugin folder and commit the package-lock.json file.');
}
}
if (files.indexOf('contributing') === -1 && files.indexOf('contributing.md') === -1) {
console.warn('CONTRIBUTING.md file not found, please create');
const fillTemplate = async (templateFilename, outputFilename) => {
const contents = (await fsp.readFile(templateFilename, 'utf8'))
.replace(/\[name of copyright owner\]/g, execSync('git config user.name'))
.replace(/\[plugin_name\]/g, pluginName)
.replace(/\[yyyy\]/g, new Date().getFullYear());
await fsp.writeFile(outputFilename, contents);
};
if (!readMeFileName) {
logger.warn('README.md file not found, please create');
if (autoFix) {
console.log('Autofixing missing CONTRIBUTING.md file, please edit the CONTRIBUTING.md ' +
logger.info('Autofixing missing README.md file');
logger.info('please edit the README.md file further to include plugin specific details.');
await fillTemplate('src/bin/plugins/lib/README.md', `${pluginPath}/README.md`);
}
}
if (!files.includes('CONTRIBUTING') && !files.includes('CONTRIBUTING.md')) {
logger.warn('CONTRIBUTING.md file not found, please create');
if (autoFix) {
logger.info('Autofixing missing CONTRIBUTING.md file, please edit the CONTRIBUTING.md ' +
'file further to include plugin specific details.');
let contributing =
fs.readFileSync('src/bin/plugins/lib/CONTRIBUTING.md', {encoding: 'utf8', flag: 'r'});
contributing = contributing.replace(/\[plugin_name\]/g, pluginName);
fs.writeFileSync(`${pluginPath}/CONTRIBUTING.md`, contributing);
await fillTemplate('src/bin/plugins/lib/CONTRIBUTING.md', `${pluginPath}/CONTRIBUTING.md`);
}
}
if (readMeFileName) {
let readme =
fs.readFileSync(`${pluginPath}/${readMeFileName}`, {encoding: 'utf8', flag: 'r'});
if (readme.toLowerCase().indexOf('license') === -1) {
console.warn('No license section in README');
await fsp.readFile(`${pluginPath}/${readMeFileName}`, {encoding: 'utf8', flag: 'r'});
if (!readme.toLowerCase().includes('license')) {
logger.warn('No license section in README');
if (autoFix) {
console.warn('Please add License section to README manually.');
logger.warn('Please add License section to README manually.');
}
}
// eslint-disable-next-line max-len
const publishBadge = `![Publish Status](https://github.com/ether/${pluginName}/workflows/Node.js%20Package/badge.svg)`;
// eslint-disable-next-line max-len
const testBadge = `![Backend Tests Status](https://github.com/ether/${pluginName}/workflows/Backend%20tests/badge.svg)`;
if (readme.toLowerCase().indexOf('travis') !== -1) {
console.warn('Remove Travis badges');
if (readme.toLowerCase().includes('travis')) {
logger.warn('Remove Travis badges');
}
if (readme.indexOf('workflows/Node.js%20Package/badge.svg') === -1) {
console.warn('No Github workflow badge detected');
if (!readme.includes('workflows/Node.js%20Package/badge.svg')) {
logger.warn('No Github workflow badge detected');
if (autoFix) {
readme = `${publishBadge} ${testBadge}\n\n${readme}`;
// write readme to file system
fs.writeFileSync(`${pluginPath}/${readMeFileName}`, readme);
console.log('Wrote Github workflow badges to README');
await fsp.writeFile(`${pluginPath}/${readMeFileName}`, readme);
logger.info('Wrote Github workflow badges to README');
}
}
}
if (files.indexOf('license') === -1 && files.indexOf('license.md') === -1) {
console.warn('LICENSE.md file not found, please create');
if (!files.includes('LICENSE') && !files.includes('LICENSE.md')) {
logger.warn('LICENSE file not found, please create');
if (autoFix) {
console.log('Autofixing missing LICENSE.md file, including Apache 2 license.');
let license =
fs.readFileSync('src/bin/plugins/lib/LICENSE.md', {encoding: 'utf8', flag: 'r'});
license = license.replace('[yyyy]', new Date().getFullYear());
license = license.replace('[name of copyright owner]', execSync('git config user.name'));
fs.writeFileSync(`${pluginPath}/LICENSE.md`, license);
logger.info('Autofixing missing LICENSE file (Apache 2.0).');
await fsp.copyFile('src/bin/plugins/lib/LICENSE', `${pluginPath}/LICENSE`);
}
}
if (files.indexOf('.gitignore') === -1) {
console.warn('.gitignore file not found, please create. .gitignore files are useful to ' +
if (!files.includes('.gitignore')) {
logger.warn('.gitignore file not found, please create. .gitignore files are useful to ' +
"ensure files aren't incorrectly commited to a repository.");
if (autoFix) {
console.log('Autofixing missing .gitignore file');
logger.info('Autofixing missing .gitignore file');
const gitignore =
fs.readFileSync('src/bin/plugins/lib/gitignore', {encoding: 'utf8', flag: 'r'});
fs.writeFileSync(`${pluginPath}/.gitignore`, gitignore);
await fsp.readFile('src/bin/plugins/lib/gitignore', {encoding: 'utf8', flag: 'r'});
await fsp.writeFile(`${pluginPath}/.gitignore`, gitignore);
}
} else {
let gitignore =
fs.readFileSync(`${pluginPath}/.gitignore`, {encoding: 'utf8', flag: 'r'});
if (gitignore.indexOf('node_modules/') === -1) {
console.warn('node_modules/ missing from .gitignore');
await fsp.readFile(`${pluginPath}/.gitignore`, {encoding: 'utf8', flag: 'r'});
if (!gitignore.includes('node_modules/')) {
logger.warn('node_modules/ missing from .gitignore');
if (autoFix) {
gitignore += 'node_modules/';
fs.writeFileSync(`${pluginPath}/.gitignore`, gitignore);
await fsp.writeFile(`${pluginPath}/.gitignore`, gitignore);
}
}
}
// if we include templates but don't have translations...
if (files.indexOf('templates') !== -1 && files.indexOf('locales') === -1) {
console.warn('Translations not found, please create. ' +
if (files.includes('templates') && !files.includes('locales')) {
logger.warn('Translations not found, please create. ' +
'Translation files help with Etherpad accessibility.');
}
if (files.indexOf('.ep_initialized') !== -1) {
console.warn(
if (files.includes('.ep_initialized')) {
logger.warn(
'.ep_initialized found, please remove. .ep_initialized should never be commited to git ' +
'and should only exist once the plugin has been executed one time.');
if (autoFix) {
console.log('Autofixing incorrectly existing .ep_initialized file');
fs.unlinkSync(`${pluginPath}/.ep_initialized`);
logger.info('Autofixing incorrectly existing .ep_initialized file');
await fsp.unlink(`${pluginPath}/.ep_initialized`);
}
}
if (files.indexOf('npm-debug.log') !== -1) {
console.warn('npm-debug.log found, please remove. npm-debug.log should never be commited to ' +
if (files.includes('npm-debug.log')) {
logger.warn('npm-debug.log found, please remove. npm-debug.log should never be commited to ' +
'your repository.');
if (autoFix) {
console.log('Autofixing incorrectly existing npm-debug.log file');
fs.unlinkSync(`${pluginPath}/npm-debug.log`);
logger.info('Autofixing incorrectly existing npm-debug.log file');
await fsp.unlink(`${pluginPath}/npm-debug.log`);
}
}
if (files.indexOf('static') !== -1) {
fs.readdir(`${pluginPath}/static`, (errRead, staticFiles) => {
if (staticFiles.indexOf('tests') === -1) {
console.warn('Test files not found, please create tests. https://github.com/ether/etherpad-lite/wiki/Creating-a-plugin#writing-and-running-front-end-tests-for-your-plugin');
}
});
if (files.includes('static')) {
const staticFiles = await fsp.readdir(`${pluginPath}/static`);
if (!staticFiles.includes('tests')) {
logger.warn('Test files not found, please create tests. https://github.com/ether/etherpad-lite/wiki/Creating-a-plugin#writing-and-running-front-end-tests-for-your-plugin');
}
} else {
console.warn('Test files not found, please create tests. https://github.com/ether/etherpad-lite/wiki/Creating-a-plugin#writing-and-running-front-end-tests-for-your-plugin');
logger.warn('Test files not found, please create tests. https://github.com/ether/etherpad-lite/wiki/Creating-a-plugin#writing-and-running-front-end-tests-for-your-plugin');
}
// Install dependencies so we can run ESLint. This should also create or update package-lock.json
// if autoFix is enabled.
const npmInstall = `npm install${autoFix ? '' : ' --no-package-lock'}`;
execSync(npmInstall, {stdio: 'inherit'});
// The ep_etherpad-lite peer dep must be installed last otherwise `npm install` will nuke it. An
// absolute path to etherpad-lite/src is used here so that pluginPath can be a symlink.
execSync(
`${npmInstall} --no-save ep_etherpad-lite@file:${__dirname}/../../`, {stdio: 'inherit'});
// Create the ep_etherpad-lite symlink if necessary. This must be done after running `npm install`
// because that command nukes the symlink.
try {
const d = await fsp.realpath(path.join(pluginPath, 'node_modules/ep_etherpad-lite'));
assert.equal(d, epSrcDir);
} catch (err) {
execSync(`${npmInstall} --no-save ep_etherpad-lite@file:${epSrcDir}`, {stdio: 'inherit'});
}
// linting begins
try {
console.log('Linting...');
logger.info('Linting...');
const lintCmd = autoFix ? 'npx eslint --fix .' : 'npx eslint';
execSync(lintCmd, {stdio: 'inherit'});
} catch (e) {
// it is gonna throw an error anyway
console.log('Manual linting probably required, check with: npm run lint');
logger.info('Manual linting probably required, check with: npm run lint');
}
// linting ends.
@ -436,24 +390,31 @@ fs.readdir(pluginPath, (err, rootFiles) => {
env: {...process.env, GIT_INDEX_FILE: '.git/checkPlugin.index'},
stdio: 'inherit',
});
fs.unlinkSync(`${pluginPath}/.git/checkPlugin.index`);
await fsp.unlink(`${pluginPath}/.git/checkPlugin.index`);
const cmd = [
const commitCmd = [
'git add -A',
'git commit -m "autofixes from Etherpad checkPlugin.js"',
'git push',
].join(' && ');
if (autoCommit) {
console.log('Attempting autocommit and auto publish to npm');
execSync(cmd, {stdio: 'inherit'});
logger.info('Committing changes...');
execSync(commitCmd, {stdio: 'inherit'});
} else {
console.log('Fixes applied. Check the above git diff then run the following command:');
console.log(`(cd node_modules/${pluginName} && ${cmd})`);
logger.info('Fixes applied. Check the above git diff then run the following command:');
logger.info(`(cd node_modules/${pluginName} && ${commitCmd})`);
}
const pushCmd = 'git push';
if (autoPush) {
logger.info('Pushing new commit...');
execSync(pushCmd, {stdio: 'inherit'});
} else {
logger.info('Changes committed. To push, run the following command:');
logger.info(`(cd node_modules/${pluginName} && ${pushCmd})`);
}
} else {
console.log('No changes.');
logger.info('No changes.');
}
}
console.log('Finished');
});
logger.info('Finished');
})();

View File

@ -1,4 +1,39 @@
cd node_modules/
GHUSER=ether; curl "https://api.github.com/users/$GHUSER/repos?per_page=100" | grep -o 'git@[^"]*' | grep /ep_ | xargs -L1 git clone
GHUSER=ether; curl "https://api.github.com/users/$GHUSER/repos?per_page=100&page=2&" | grep -o 'git@[^"]*' | grep /ep_ | xargs -L1 git clone
GHUSER=ether; curl "https://api.github.com/users/$GHUSER/repos?per_page=100&page=3&" | grep -o 'git@[^"]*' | grep /ep_ | xargs -L1 git clone
#!/bin/sh
set -e
newline='
'
pecho () { printf %s\\n "$*"; }
log () { pecho "$@"; }
error () { log "ERROR: $@" >&2; }
fatal () { error "$@"; exit 1; }
mydir=$(cd "${0%/*}" && pwd -P) || exit 1
cd "${mydir}/../../.."
pdir=$(cd .. && pwd -P) || exit 1
plugins=$("${mydir}/listOfficialPlugins") || exit 1
for d in ${plugins}; do
log "============================================================"
log "${d}"
log "============================================================"
fd=${pdir}/${d}
repo=git@github.com:ether/${plugin}.git
[ -d "${fd}" ] || {
log "Cloning ${repo} to ${fd}..."
(cd "${pdir}" && git clone "${repo}" "${d}") || exit 1
} || exit 1
log "Fetching latest commits..."
(cd "${fd}" && git pull --ff-only) || exit 1
log "Getting plugin name..."
pn=$(cd "${fd}" && npx -c 'printf %s\\n "${npm_package_name}"') || exit 1
[ -n "${pn}" ] || fatal "Unable to determine plugin name for ${d}"
md=node_modules/${pn}
[ -d "${md}" ] || {
log "Installing plugin to ${md}..."
ln -s ../../"${d}" "${md}"
} || exit 1
[ "${md}" -ef "${fd}" ] || fatal "${md} is not a symlink to ${fd}"
done

201
src/bin/plugins/lib/LICENSE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,13 +0,0 @@
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,32 +1,47 @@
[![Travis (.com)](https://api.travis-ci.com/[org_name]/[repo_url].svg?branch=develop)](https://travis-ci.com/github/[org_name]/[repo_url])
# [plugin_name]
# My awesome plugin README example
Explain what your plugin does and who it's useful for.
TODO: Describe the plugin.
## Example animated gif of usage if appropriate
![screenshot](https://user-images.githubusercontent.com/220864/99979953-97841d80-2d9f-11eb-9782-5f65817c58f4.PNG)
## Installing
## Installation
```
From the Etherpad working directory, run:
```shell
npm install --no-save --legacy-peer-deps [plugin_name]
```
or Use the Etherpad ``/admin`` interface.
Or, install from Etherpad's `/admin/plugins` page.
## Settings
Document settings if any
## Configuration
TODO
## Testing
Document how to run backend / frontend tests.
### Frontend
To run the backend tests, run the following from the Etherpad working directory:
Visit http://whatever/tests/frontend/ to run the frontend tests.
```shell
(cd src && npm test)
```
### backend
To run the frontend tests, visit: http://localhost:9001/tests/frontend/
Type ``cd src && npm run test`` to run the backend tests.
## Copyright and License
## LICENSE
Apache 2.0
Copyright © [yyyy] [name of copyright owner]
and the [plugin_name] authors and contributors
Licensed under the [Apache License, Version 2.0](LICENSE) (the "License"); you
may not use this file except in compliance with the License. You may obtain a
copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

View File

@ -1,6 +1,3 @@
# You need to change lines 38 and 46 in case the plugin's name on npmjs.com is different
# from the repository name
name: "Backend tests"
# any branch is useful for testing before a PR is submitted
@ -11,40 +8,68 @@ jobs:
# run on pushes to any branch
# run on PRs from external forks
if: |
(github.event_name != 'pull_request')
|| (github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id)
(github.event_name != 'pull_request')
|| (github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id)
name: with Plugins
runs-on: ubuntu-latest
steps:
- name: Install libreoffice
run: |
sudo add-apt-repository -y ppa:libreoffice/ppa
sudo apt update
sudo apt install -y --no-install-recommends libreoffice libreoffice-pdfimport
# clone etherpad-lite
- name: Install etherpad core
uses: actions/checkout@v2
with:
repository: ether/etherpad-lite
- name: Install all dependencies and symlink for ep_etherpad-lite
run: src/bin/installDeps.sh
# clone this repository into node_modules/ep_plugin-name
- name: Checkout plugin repository
uses: actions/checkout@v2
with:
path: ./node_modules/${{github.event.repository.name}}
- name: Install plugin dependencies
run: |
cd node_modules/${{github.event.repository.name}}
npm ci
- name: Run the backend tests
run: cd src && npm test
##ETHERPAD_NPM_V=2
## NPM configuration automatically created using src/bin/plugins/updateAllPluginsScript.sh
-
name: Install libreoffice
run: |
sudo add-apt-repository -y ppa:libreoffice/ppa
sudo apt update
sudo apt install -y --no-install-recommends libreoffice libreoffice-pdfimport
-
name: Install etherpad core
uses: actions/checkout@v3
with:
repository: ether/etherpad-lite
-
name: Checkout plugin repository
uses: actions/checkout@v3
with:
path: ./node_modules/__tmp
-
name: Determine plugin name
id: plugin_name
run: |
cd ./node_modules/__tmp
npx -c 'printf %s\\n "::set-output name=plugin_name::${npm_package_name}"'
-
name: Rename plugin directory
run: |
mv ./node_modules/__tmp ./node_modules/"${PLUGIN_NAME}"
env:
PLUGIN_NAME: ${{ steps.plugin_name.outputs.plugin_name }}
-
uses: actions/setup-node@v3
with:
node-version: 12
cache: 'npm'
cache-dependency-path: |
src/package-lock.json
src/bin/doc/package-lock.json
node_modules/${{ steps.plugin_name.outputs.plugin_name }}/package-lock.json
-
name: Install plugin dependencies
run: |
cd ./node_modules/"${PLUGIN_NAME}"
npm ci
env:
PLUGIN_NAME: ${{ steps.plugin_name.outputs.plugin_name }}
# Etherpad core dependencies must be installed after installing the
# plugin's dependencies, otherwise npm will try to hoist common
# dependencies by removing them from src/node_modules and installing them
# in the top-level node_modules. As of v6.14.10, npm's hoist logic appears
# to be buggy, because it sometimes removes dependencies from
# src/node_modules but fails to add them to the top-level node_modules.
# Even if npm correctly hoists the dependencies, the hoisting seems to
# confuse tools such as `npm outdated`, `npm update`, and some ESLint
# rules.
-
name: Install Etherpad core dependencies
run: src/bin/installDeps.sh
-
name: Run the backend tests
run: cd src && npm test

View File

@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"
versioning-strategy: "increase"

View File

@ -0,0 +1,9 @@
'use strict';
// This is a workaround for https://github.com/eslint/eslint/issues/3458
require('eslint-config-etherpad/patch/modern-module-resolution');
module.exports = {
root: true,
extends: 'etherpad/plugin',
};

View File

@ -0,0 +1,110 @@
# Publicly credit Sauce Labs because they generously support open source
# projects.
name: "frontend tests powered by Sauce Labs"
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
-
name: Fail if Dependabot
if: github.actor == 'dependabot[bot]'
run: |
cat <<EOF >&2
Frontend tests skipped because Dependabot can't access secrets.
Manually re-run the jobs to run the frontend tests.
For more information, see:
https://github.blog/changelog/2021-02-19-github-actions-workflows-triggered-by-dependabot-prs-will-run-with-read-only-permissions/
EOF
exit 1
-
name: Generate Sauce Labs strings
id: sauce_strings
run: |
printf %s\\n '::set-output name=name::${{github.event.repository.name}} ${{ github.workflow }} - ${{ github.job }}'
printf %s\\n '::set-output name=tunnel_id::${{ github.run_id }}-${{ github.run_number }}-${{ github.job }}'
-
name: Check out Etherpad core
uses: actions/checkout@v3
with:
repository: ether/etherpad-lite
-
uses: actions/setup-node@v3
with:
node-version: 12
cache: 'npm'
cache-dependency-path: |
src/package-lock.json
src/bin/doc/package-lock.json
-
name: Check out the plugin
uses: actions/checkout@v3
with:
path: ./node_modules/__tmp
-
name: export GIT_HASH to env
id: environment
run: |
cd ./node_modules/__tmp
echo "::set-output name=sha_short::$(git rev-parse --short ${{ github.sha }})"
-
name: Determine plugin name
id: plugin_name
run: |
cd ./node_modules/__tmp
npx -c 'printf %s\\n "::set-output name=plugin_name::${npm_package_name}"'
-
name: Rename plugin directory
env:
PLUGIN_NAME: ${{ steps.plugin_name.outputs.plugin_name }}
run: |
mv ./node_modules/__tmp ./node_modules/"${PLUGIN_NAME}"
-
name: Install plugin dependencies
env:
PLUGIN_NAME: ${{ steps.plugin_name.outputs.plugin_name }}
run: |
cd ./node_modules/"${PLUGIN_NAME}"
npm ci
# Etherpad core dependencies must be installed after installing the
# plugin's dependencies, otherwise npm will try to hoist common
# dependencies by removing them from src/node_modules and installing them
# in the top-level node_modules. As of v6.14.10, npm's hoist logic appears
# to be buggy, because it sometimes removes dependencies from
# src/node_modules but fails to add them to the top-level node_modules.
# Even if npm correctly hoists the dependencies, the hoisting seems to
# confuse tools such as `npm outdated`, `npm update`, and some ESLint
# rules.
-
name: Install Etherpad core dependencies
run: src/bin/installDeps.sh
-
name: Create settings.json
run: cp settings.json.template settings.json
-
name: Disable import/export rate limiting
run: |
sed -e '/^ *"importExportRateLimiting":/,/^ *\}/ s/"max":.*/"max": 0/' -i settings.json
-
name: Remove standard frontend test files
run: rm -rf src/tests/frontend/specs
-
uses: saucelabs/sauce-connect-action@v2.1.1
with:
username: ${{ secrets.SAUCE_USERNAME }}
accessKey: ${{ secrets.SAUCE_ACCESS_KEY }}
tunnelIdentifier: ${{ steps.sauce_strings.outputs.tunnel_id }}
-
name: Run the frontend tests
shell: bash
env:
SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }}
SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }}
SAUCE_NAME: ${{ steps.sauce_strings.outputs.name }}
TRAVIS_JOB_NUMBER: ${{ steps.sauce_strings.outputs.tunnel_id }}
GIT_HASH: ${{ steps.environment.outputs.sha_short }}
run: |
src/tests/frontend/travis/runner.sh

View File

@ -21,50 +21,86 @@ jobs:
# cloned to etherpad-lite then moved to ../etherpad-lite. To avoid
# conflicts with this plugin's clone, etherpad-lite must be cloned and
# moved out before this plugin's repo is cloned to $GITHUB_WORKSPACE.
- uses: actions/checkout@v2
-
uses: actions/checkout@v3
with:
repository: ether/etherpad-lite
path: etherpad-lite
- run: mv etherpad-lite ..
-
run: mv etherpad-lite ..
# etherpad-lite has been moved outside of $GITHUB_WORKSPACE, so it is now
# safe to clone this plugin's repo to $GITHUB_WORKSPACE.
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
-
uses: actions/checkout@v3
# This is necessary for actions/setup-node because '..' can't be used in
# cache-dependency-path.
-
name: Create ep_etherpad-lite symlink
run: |
mkdir -p node_modules
ln -s ../../etherpad-lite/src node_modules/ep_etherpad-lite
-
uses: actions/setup-node@v3
with:
node-version: 12
cache: 'npm'
cache-dependency-path: |
node_modules/ep_etherpad-lite/package-lock.json
node_modules/ep_etherpad-lite/bin/doc/package-lock.json
package-lock.json
# All of ep_etherpad-lite's devDependencies are installed because the
# plugin might do `require('ep_etherpad-lite/node_modules/${devDep}')`.
# Eventually it would be nice to create an ESLint plugin that prohibits
# Etherpad plugins from piggybacking off of ep_etherpad-lite's
# devDependencies. If we had that, we could change this line to only
# install production dependencies.
- run: cd ../etherpad-lite/src && npm ci
- run: npm ci
-
run: cd ../etherpad-lite/src && npm ci
-
run: npm ci
# This runs some sanity checks and creates a symlink at
# node_modules/ep_etherpad-lite that points to ../../etherpad-lite/src.
# This step must be done after `npm ci` installs the plugin's dependencies
# because npm "helpfully" cleans up such symlinks. :( Installing
# ep_etherpad-lite in the plugin's node_modules prevents lint errors and
# unit test failures if the plugin does `require('ep_etherpad-lite/foo')`.
- run: npm install --no-save ep_etherpad-lite@file:../etherpad-lite/src
- run: npm test
- run: npm run lint
-
run: npm install --no-save ep_etherpad-lite@file:../etherpad-lite/src
-
run: npm test
-
run: npm run lint
publish-npm:
if: github.event_name == 'push'
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
-
uses: actions/checkout@v3
with:
fetch-depth: 0
-
uses: actions/setup-node@v3
with:
node-version: 12
registry-url: https://registry.npmjs.org/
- run: git config user.name 'github-actions[bot]'
- run: git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
- run: npm ci
- run: npm version patch
- run: git push --follow-tags
cache: 'npm'
-
name: Bump version (patch)
run: |
LATEST_TAG=$(git describe --tags --abbrev=0) || exit 1
NEW_COMMITS=$(git rev-list --count "${LATEST_TAG}"..) || exit 1
[ "${NEW_COMMITS}" -gt 0 ] || exit 0
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
npm ci
npm version patch
git push --follow-tags
# This is required if the package has a prepare script that uses something
# in dependencies or devDependencies.
-
run: npm ci
# `npm publish` must come after `git push` otherwise there is a race
# condition: If two PRs are merged back-to-back then master/main will be
# updated with the commits from the second PR before the first PR's
@ -75,9 +111,12 @@ jobs:
# already-used version number. By running `npm publish` after `git push`,
# back-to-back merges will cause the first merge's workflow to fail but
# the second's will succeed.
- run: npm publish
-
run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
-
name: Add package to etherpad organization
run: npm access grant read-write etherpad:developers
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
##ETHERPAD_NPM_V=2
## NPM configuration automatically created using src/bin/plugins/updateAllPluginsScript.sh

View File

@ -0,0 +1,14 @@
#!/bin/sh
set -e
newline='
'
mydir=$(cd "${0%/*}" && pwd -P) || exit 1
cd "${mydir}/../../.."
pdir=$(cd .. && pwd -P) || exit 1
plugins=
for p in "" "&page=2" "&page=3"; do
curlOut=$(curl "https://api.github.com/users/ether/repos?per_page=100${p}") || exit 1
plugins=${plugins}${newline}$(printf %s\\n "${curlOut}" \
| sed -n -e 's;.*git@github.com:ether/\(ep_[^"]*\)\.git.*;\1;p');
done
printf %s\\n "${plugins}" | sort -u | grep -v '^[[:space:]]*$'

View File

@ -4,7 +4,7 @@ do
echo $dir
if [[ $dir == *"ep_"* ]]; then
if [[ $dir != "ep_etherpad-lite" ]]; then
# node src/bin/plugins/checkPlugin.js $dir autofix autocommit autoupdate
# node src/bin/plugins/checkPlugin.js $dir autopush
cd node_modules/$dir
git commit -m "Automatic update: bump update to re-run latest Etherpad tests" --allow-empty
git push origin master

View File

@ -10,7 +10,7 @@ do
# echo $0
if [[ $dir == *"ep_"* ]]; then
if [[ $dir != "ep_etherpad-lite" ]]; then
node src/bin/plugins/checkPlugin.js $dir autofix autocommit autoupdate
node src/bin/plugins/checkPlugin.js $dir autopush
fi
fi
# echo $dir

View File

@ -5,5 +5,5 @@ set -e
for dir in node_modules/ep_*; do
dir=${dir#node_modules/}
[ "$dir" != ep_etherpad-lite ] || continue
node src/bin/plugins/checkPlugin.js "$dir" autofix autocommit autoupdate
node src/bin/plugins/checkPlugin.js "$dir" autopush
done

View File

@ -132,9 +132,9 @@ try {
// Many users will be using the latest LTS version of npm, and the latest LTS version of npm uses
// lockfileVersion 1. Enforce v1 so that users don't see a (benign) compatibility warning.
if (readJson('./src/package-lock.json').lockfileVersion !== 1) {
throw new Error('Please regenerate package-lock.json with npm v6.x.');
}
const pkglock = readJson('./src/package-lock.json');
pkglock.lockfileVersion = 1;
writeJson('./src/package-lock.json', pkglock);
run('git add src/package.json');
run('git add src/package-lock.json');

View File

@ -23,7 +23,7 @@
{
"name": "static",
"hooks": {
"expressCreateServer": "ep_etherpad-lite/node/hooks/express/static"
"expressPreSession": "ep_etherpad-lite/node/hooks/express/static"
}
},
{
@ -35,13 +35,14 @@
{
"name": "i18n",
"hooks": {
"expressCreateServer": "ep_etherpad-lite/node/hooks/i18n"
"expressPreSession": "ep_etherpad-lite/node/hooks/i18n"
}
},
{
"name": "specialpages",
"hooks": {
"expressCreateServer": "ep_etherpad-lite/node/hooks/express/specialpages"
"expressCreateServer": "ep_etherpad-lite/node/hooks/express/specialpages",
"expressPreSession": "ep_etherpad-lite/node/hooks/express/specialpages"
}
},
{
@ -50,16 +51,10 @@
"expressCreateServer": "ep_etherpad-lite/node/hooks/express/padurlsanitize"
}
},
{
"name": "webaccess",
"hooks": {
"expressConfigure": "ep_etherpad-lite/node/hooks/express/webaccess"
}
},
{
"name": "apicalls",
"hooks": {
"expressCreateServer": "ep_etherpad-lite/node/hooks/express/apicalls"
"expressPreSession": "ep_etherpad-lite/node/hooks/express/apicalls"
}
},
{
@ -85,7 +80,7 @@
{
"name": "tests",
"hooks": {
"expressCreateServer": "ep_etherpad-lite/node/hooks/express/tests"
"expressPreSession": "ep_etherpad-lite/node/hooks/express/tests"
}
},
{
@ -111,7 +106,7 @@
{
"name": "openapi",
"hooks": {
"expressCreateServer": "ep_etherpad-lite/node/hooks/express/openapi"
"expressPreSession": "ep_etherpad-lite/node/hooks/express/openapi"
}
}
]

View File

@ -15,21 +15,29 @@
"محمد أحمد عبد الفتاح"
]
},
"admin_plugins": "مدير المساعد",
"admin_plugins.available": "الإضافات المتوفرة",
"admin_plugins.available_not-found": "لم يتم العثور على مكونات إضافية.",
"admin_plugins.available_fetching": "جارٍ الجلب...",
"admin_plugins.available_install.value": "تنصيب",
"admin_plugins.available_search.placeholder": " تنصيب عن الإضافات لتثبيتها",
"admin.page-title": "لوحة تحكم المسؤول - Etherpad",
"admin_plugins.description": "الوصف",
"admin_plugins.installed_uninstall.value": "فك التنصيب",
"admin_plugins.last-update": "آخر تحديث",
"admin_plugins.installed": "الإضافات المثبتة",
"admin_plugins.installed_fetching": "جارٍ إحضار المكونات الإضافية المثبتة ...",
"admin_plugins.installed_nothing": "لم تقم بتثبيت أي مكونات إضافية حتى الآن.",
"admin_plugins.name": "الاسم",
"admin_plugins.page-title": "مدير البرنامج المساعد - Etherpad",
"admin_plugins.version": "الإصدار",
"admin_plugins_info.version_latest": "أحدث نسخة متاحة",
"admin_plugins_info": "معلومات استكشاف الأخطاء وإصلاحها",
"admin_plugins_info.hooks": "خطافات مثبتة",
"admin_plugins_info.hooks_client": "خطاطيف من جانب العميل",
"admin_plugins_info.hooks_server": "خطاطيف من جانب الخادم",
"admin_plugins_info.parts": "الأجزاء المثبتة",
"admin_plugins_info.plugins": "الإضافات المثبتة",
"admin_plugins_info.page-title": "معلومات البرنامج المساعد - Etherpad",
"admin_plugins_info.version": "إصدار Etherpad",
"admin_plugins_info.version_number": "رقم الإصدار",
"admin_settings": "إعدادات",
"admin_settings.current": "التكوين الحالي",
"admin_settings.current_example-devel": "مثال على قالب إعدادات التطوير",
"admin_settings.current_example-prod": "مثال على قالب إعدادات الإنتاج",
"admin_settings.current_restart.value": "أعد تشغيل Etherpad",
"admin_settings.current_save.value": "حفظ الإعدادات",
"admin_settings.page-title": "الإعدادات - Etherpad",
"index.newPad": "باد جديد",
"index.createOpenPad": "أو صنع/فتح باد بوضع اسمه:",
"index.openPad": "افتح باد موجودة بالاسم:",
@ -101,8 +109,8 @@
"pad.modals.corruptPad.cause": "قد يكون هذا بسبب تكوين ملقم خاطئ أو بسبب سلوك آخر غير متوقع. يرجى الاتصال بمسؤول الخدمة.",
"pad.modals.deleted": "محذوف.",
"pad.modals.deleted.explanation": "تمت إزالة هذا الباد.",
"pad.modals.rateLimited.explanation": "لقد أرسلت عددًا كبيرًا جدًا من الرسائل إلى هذه اللوحة ، لذا فقد قطع اتصالك.",
"pad.modals.rejected.explanation": "رفض الخادم رسالة أرسلها متصفحك.",
"pad.modals.rateLimited": "معدل محدود.",
"pad.modals.rejected.cause": "ربما تم تحديث الخادم أثناء عرض اللوحة ، أو ربما كان هناك خطأ في Etherpad. حاول إعادة تحميل الصفحة.",
"pad.modals.disconnected": "لم تعد متصلا.",
"pad.modals.disconnected.explanation": "تم فقدان الاتصال بالخادم",
"pad.modals.disconnected.cause": "قد يكون الخادم غير متوفر. يرجى إعلام مسؤول الخدمة إذا كان هذا لا يزال يحدث.",
@ -115,6 +123,7 @@
"pad.chat.loadmessages": "تحميل المزيد من الرسائل",
"pad.chat.stick.title": "ألصق الدردشة بالشاشة",
"pad.chat.writeMessage.placeholder": "اكتب رسالتك هنا",
"timeslider.followContents": "اتبع تحديثات محتوى الوسادة",
"timeslider.pageTitle": "{{appTitle}} متصفح التاريخ",
"timeslider.toolbar.returnbutton": "العودة إلى الباد",
"timeslider.toolbar.authors": "المؤلفون:",

View File

@ -1,7 +1,8 @@
{
"@metadata": {
"authors": [
"1AnuraagPandey"
"1AnuraagPandey",
"बडा काजी"
]
},
"index.newPad": "नयाँ प्याड",
@ -35,7 +36,7 @@
"pad.modals.unauth": "अनाधिकृत",
"pad.modals.initsocketfail": "सर्भरमा पहुँच से बहरे है ।",
"pad.share.readonly": "पढय वाला खाली",
"pad.share.link": "लिङ्क",
"pad.share.link": "डी",
"pad.share.emebdcode": "URL जोडा जाय",
"pad.chat": "बातचीत",
"timeslider.pageTitle": "{{appTitle}} समय रेखा",

View File

@ -13,6 +13,28 @@
"admin_plugins.available_not-found": "Плагіны ня знойдзеныя.",
"admin_plugins.available_fetching": "Атрымліваем…",
"admin_plugins.available_install.value": "Усталяваць",
"admin_plugins.available_search.placeholder": "Шукаць пашырэньні для ўсталяваньня",
"admin_plugins.description": "Апісаньне",
"admin_plugins.installed": "Усталяваныя пашырэньні",
"admin_plugins.installed_fetching": "Атрыманьне ўсталяваных пашырэньняў…",
"admin_plugins.installed_nothing": "Вы пакуль не ўсталявалі ніводнага пашырэньня.",
"admin_plugins.installed_uninstall.value": "Выдаліць",
"admin_plugins.last-update": "Апошняе абнаўленьне",
"admin_plugins.name": "Назва",
"admin_plugins.page-title": "Кіраўнік пашырэньняў — Etherpad",
"admin_plugins.version": "Вэрсія",
"admin_plugins_info": "Інфармацыя пра вырашэньне няспраўнасьцяў",
"admin_plugins_info.hooks": "Усталяваныя кручкі",
"admin_plugins_info.hooks_client": "Кліенцкія кручкі",
"admin_plugins_info.hooks_server": "Сэрвэрныя кручкі",
"admin_plugins_info.parts": "Усталяваныя часткі",
"admin_plugins_info.plugins": "Усталяваныя пашырэньні",
"admin_plugins_info.page-title": "Інфармацыя пра пашырэньне — Etherpad",
"admin_plugins_info.version": "Вэрсія Etherpad",
"admin_plugins_info.version_latest": "Апошняя даступная вэрсія",
"admin_plugins_info.version_number": "Нумар вэрсіі",
"admin_settings": "Налады",
"admin_settings.current": "Цяперашняя канфігурацыя",
"admin_settings.page-title": "Налады — Etherpad",
"index.newPad": "Стварыць",
"index.createOpenPad": "ці тварыць/адкрыць дакумэнт з назвай:",

View File

@ -9,6 +9,7 @@
"Nasir8891",
"Sankarshan",
"Sibabrata Banerjee",
"আজিজ",
"আফতাবুজ্জামান"
]
},
@ -22,6 +23,7 @@
"admin_plugins.description": "বিবরণ",
"admin_plugins.installed": "ইন্সটল হওয়া প্লাগিনসমূহ",
"admin_plugins.installed_fetching": "ইন্সটলকৃত প্লাগিন আনা হচ্ছে",
"admin_plugins.installed_nothing": "আপনি এখনও কোনো প্লাগইন ইনস্টল করেননি।",
"admin_plugins.installed_uninstall.value": "আনইনস্টল করুন",
"admin_plugins.last-update": "সর্বশেষ হালনাগাদ",
"admin_plugins.name": "নাম",
@ -39,10 +41,14 @@
"admin_plugins_info.version_number": "সংস্করণ সংখ্যা",
"admin_settings": "সেটিংসমূহ",
"admin_settings.current": "বর্তমান কনফিগারেশন",
"admin_settings.current_example-devel": "উদাহরণ ডেভেলপমেন্ট সেটিংস টেমপ্লেট",
"admin_settings.current_example-prod": "উদাহরণ উৎপাদন সেটিংস টেমপ্লেট",
"admin_settings.current_restart.value": "ইথারপ্যাড পুনরায় চালু করুন",
"admin_settings.current_save.value": "সেটিংসমূহ সংরক্ষণ করুন",
"admin_settings.page-title": "সেটিংস - ইথারপ্যাড",
"index.newPad": "নতুন প্যাড",
"index.createOpenPad": "অথবা নাম লিখে প্যাড খুলুন/তৈরী করুন:",
"index.openPad": "নাম সহ একটি বিদ্যমান প্যাড খুলুন:",
"pad.toolbar.bold.title": "গাঢ় (Ctrl-B)",
"pad.toolbar.italic.title": "বাঁকা (Ctrl+I)",
"pad.toolbar.underline.title": "নিম্নরেখা (Ctrl+U)",
@ -90,12 +96,27 @@
"pad.modals.connected": "সংযোগস্থাপন করা হয়েছে।",
"pad.modals.reconnecting": "আপনার প্যাডের সাথে সংযোগস্থাপন করা হচ্ছে…",
"pad.modals.forcereconnect": "পুনরায় সংযোগস্থাপনের চেষ্টা",
"pad.modals.reconnecttimer": "পুনঃসংযোগের চেষ্টা করা হচ্ছে",
"pad.modals.cancel": "বাতিল",
"pad.modals.userdup": "অন্য উইন্ডো-তে খোলা হয়েছে",
"pad.modals.userdup.explanation": "এই প্যাডটি এই কম্পিউটারে একাধিক ব্রাউজার উইন্ডোতে খোলা হয়েছে বলে মনে হচ্ছে৷",
"pad.modals.userdup.advice": "পরিবর্তে এই উইন্ডোটি ব্যবহার করতে পুনঃসংযোগ করুন৷",
"pad.modals.unauth": "আপনার অধিকার নেই",
"pad.modals.unauth.explanation": "এই পৃষ্ঠাটি দেখার সময় আপনার অনুমতি পরিবর্তিত হয়েছে৷ পুনঃসংযোগের চেষ্টা করুন।",
"pad.modals.looping.explanation": "সিঙ্ক্রোনাইজেশন সার্ভারের সাথে যোগাযোগের সমস্যা রয়েছে।",
"pad.modals.looping.cause": "সম্ভবত আপনি একটি বেমানান ফায়ারওয়াল বা প্রক্সির মাধ্যমে সংযুক্ত হয়েছেন৷",
"pad.modals.initsocketfail": "সার্ভারে পৌঁছানো যাচ্ছে না।",
"pad.modals.initsocketfail.explanation": "সিঙ্ক্রোনাইজেশন সার্ভারের সাথে সংযোগ করা যায়নি৷",
"pad.modals.initsocketfail.cause": "এটি সম্ভবত আপনার ব্রাউজার বা আপনার ইন্টারনেট সংযোগের কোনও সমস্যার কারণে হয়েছে৷",
"pad.modals.slowcommit.explanation": "সার্ভার সাড়া দিচ্ছে না।",
"pad.modals.slowcommit.cause": "এটি নেটওয়ার্ক সংযোগের সমস্যার কারণে হতে পারে।",
"pad.modals.badChangeset.explanation": "আপনার করা একটি সম্পাদনা সিঙ্ক্রোনাইজেশন সার্ভার কর্তৃক বেআইনি হিসেবে শ্রেণীবদ্ধ করা হয়েছে৷",
"pad.modals.corruptPad.explanation": "আপনি যে প্যাডে প্রবেশ করার চেষ্টা করছেন সেটি দূষিত।",
"pad.modals.corruptPad.cause": "এটি একটি ভুল সার্ভার কনফিগারেশন বা অন্য কোনও অপ্রত্যাশিত আচরণের কারণে হতে পারে। পরিষেবা প্রশাসকের সাথে যোগাযোগ করুন।",
"pad.modals.deleted": "অপসারিত।",
"pad.modals.deleted.explanation": "এই প্যাডটি অপসারণ করা হয়েছে।",
"pad.modals.rateLimited.explanation": "আপনি এই প্যাডে অনেকগুলি বার্তা পাঠিয়েছেন তাই এটি আপনাকে সংযোগ বিচ্ছিন্ন করেছে৷",
"pad.modals.rejected.explanation": "সার্ভার আপনার ব্রাউজারের পাঠানো একটি বার্তা প্রত্যাখ্যান করেছে৷",
"pad.modals.disconnected": "আপনি সংযোগ বিচ্ছিন্ন হয়েছে গেছে।",
"pad.modals.disconnected.explanation": "সার্ভারের সাথে যোগাযোগ করা যাচ্ছে না",
"pad.share": "শেয়ার করুন",
@ -127,6 +148,7 @@
"timeslider.month.november": "নভেম্বর",
"timeslider.month.december": "ডিসেম্বর",
"timeslider.unnamedauthors": "নামবিহীন {{num}} জন {[plural(num) one: লেখক, other: লেখক ]}",
"pad.savedrevs.marked": "এই সংশোধনটি এখন সংরক্ষিত সংশোধন হিসেবে চিহ্নিত করা হয়েছে",
"pad.userlist.entername": "আপনার নাম লিখুন",
"pad.userlist.unnamed": "কোন নাম নির্বাচন করা হয়নি",
"pad.impexp.importbutton": "এখন আমদানি করুন",
@ -135,5 +157,6 @@
"pad.impexp.uploadFailed": "আপলোড করতে ব্যর্থ, দয়া করে আবার চেষ্টা করুন",
"pad.impexp.importfailed": "আমদানি ব্যর্থ",
"pad.impexp.copypaste": "দয়া করে অনুলিপি প্রতিলেপন করুন",
"pad.impexp.exportdisabled": "{{type}} হিসেবে রপ্তানি করা নিষ্ক্রিয় আছে। বিস্তারিত জানার জন্য আপনার সিস্টেম প্রশাসকের সাথে যোগাযোগ করুন।"
"pad.impexp.exportdisabled": "{{type}} হিসেবে রপ্তানি করা নিষ্ক্রিয় আছে। বিস্তারিত জানার জন্য আপনার সিস্টেম প্রশাসকের সাথে যোগাযোগ করুন।",
"pad.impexp.maxFileSize": "ফাইল খুব বড়। আমদানির জন্য অনুমোদিত ফাইলের আকার বাড়াতে আপনার সাইট প্রশাসকের সাথে যোগাযোগ করুন"
}

View File

@ -4,6 +4,7 @@
"Fohanno",
"Fulup",
"Gwenn-Ael",
"Huñvreüs",
"Y-M D"
]
},
@ -86,7 +87,7 @@
"pad.chat.title": "Digeriñ ar flap kevelet gant ar pad-mañ.",
"pad.chat.loadmessages": "Kargañ muioc'h a gemennadennoù",
"pad.chat.stick.title": "Gwriziennañ an diviz war ar skramm",
"pad.chat.writeMessage.placeholder": "Skrivañ ho kemenadenn amañ",
"pad.chat.writeMessage.placeholder": "Skrivañ ho kemennadenn amañ",
"timeslider.pageTitle": "Istor dinamek eus {{appTitle}}",
"timeslider.toolbar.returnbutton": "Distreiñ d'ar pad-mañ.",
"timeslider.toolbar.authors": "Aozerien :",

View File

@ -3,6 +3,7 @@
"authors": [
"Bjarncraft",
"Dom",
"Justman10000",
"Killarnee",
"Metalhead64",
"Mklehr",
@ -44,6 +45,7 @@
"admin_settings": "Einstellungen",
"admin_settings.current": "Derzeitige Konfiguration",
"admin_settings.current_example-devel": "Beispielhafte Entwicklungseinstellungs-Templates",
"admin_settings.current_example-prod": "Beispiel einer Vorlage für Produktionseinstellungen",
"admin_settings.current_restart.value": "Etherpad neustarten",
"admin_settings.current_save.value": "Einstellungen speichern",
"admin_settings.page-title": "Einstellungen - Etherpad",
@ -121,6 +123,7 @@
"pad.modals.rateLimited": "Begrenzte Rate.",
"pad.modals.rateLimited.explanation": "Sie haben zu viele Nachrichten an dieses Pad gesendet, so dass die Verbindung unterbrochen wurde.",
"pad.modals.rejected.explanation": "Der Server hat eine Nachricht abgelehnt, die von deinem Browser gesendet wurde.",
"pad.modals.rejected.cause": "Möglicherweise wurde der Server aktualisiert, während du das Pad angesehen hast, oder es existiert ein Fehler in Etherpad. Versuche, die Seite neu zu laden.",
"pad.modals.disconnected": "Ihre Verbindung wurde getrennt.",
"pad.modals.disconnected.explanation": "Die Verbindung zum Server wurde unterbrochen.",
"pad.modals.disconnected.cause": "Möglicherweise ist der Server nicht erreichbar. Bitte benachrichtige den Dienstadministrator, falls dies weiterhin passiert.",

View File

@ -4,19 +4,53 @@
"Michawiki"
]
},
"admin.page-title": "Administratorowa delka Etherpad",
"admin_plugins": "Zastojnik tykacow",
"admin_plugins.available": "K dispoziciji stojece tykace",
"admin_plugins.available_not-found": "Žedne tykace namakane.",
"admin_plugins.available_fetching": "Wobstarujo se …",
"admin_plugins.available_install.value": "Instalěrowaś",
"admin_plugins.available_search.placeholder": "Tykace za instalaciju pytaś",
"admin_plugins.description": "Wopisanje",
"admin_plugins.installed": "Zainstalěrowane tykace",
"admin_plugins.installed_fetching": "Zainstalěrowane tykace se wobstaruju …",
"admin_plugins.installed_nothing": "Hyšći njejsćo zainstalěrował tykace.",
"admin_plugins.installed_uninstall.value": "Wótinstalěrowaś",
"admin_plugins.last-update": "Slědna aktualizacija",
"admin_plugins.name": "Mě",
"admin_plugins.page-title": "Zastojnik tykacow Etherpad",
"admin_plugins.version": "Wersija",
"admin_plugins_info": "Informacije wó rozwězanju problemow",
"admin_plugins_info.hooks": "Zainstalěrowane kokulki",
"admin_plugins_info.hooks_client": "Kokulki z boka klienta",
"admin_plugins_info.hooks_server": "Kokulki z boka serwera",
"admin_plugins_info.parts": "Zainstalěrowane źěle",
"admin_plugins_info.plugins": "Zainstalěrowane tykace",
"admin_plugins_info.page-title": "Tykacowe informacije Ehterpad",
"admin_plugins_info.version": "Wersija Etherpad",
"admin_plugins_info.version_latest": "Nejnowša wersija",
"admin_plugins_info.version_number": "Wersijowy numer",
"admin_settings": "Nastajenja",
"admin_settings.current": "Aktualna konfiguracija",
"admin_settings.current_example-devel": "Pśikładowa pśedłoga wuwijańskich nastajenjow",
"admin_settings.current_example-prod": "Pśikładowa pśedłoga produkciskich nastajenjow",
"admin_settings.current_restart.value": "Etherpad znowego startowaś",
"admin_settings.current_save.value": "Nastajenja składowaś",
"admin_settings.page-title": "Nastajenja Etherpad",
"index.newPad": "Nowy zapisnik",
"index.createOpenPad": "abo napóraj/wócyń zapisnik z mjenim:",
"index.openPad": "wócyńśo eksistěrujucy Pad z mjenim:",
"pad.toolbar.bold.title": "Tucny (Strg-B)",
"pad.toolbar.italic.title": "Kursiwny (Strg-I)",
"pad.toolbar.underline.title": "Pódšmarnuś (Strg-U)",
"pad.toolbar.strikethrough.title": "Pśešmarnuś",
"pad.toolbar.ol.title": "Numerěrowana lisćina",
"pad.toolbar.ul.title": "Nalicenje",
"pad.toolbar.strikethrough.title": "Pśešmarnuś (Strg+5)",
"pad.toolbar.ol.title": "Numerěrowana lisćina (Strg+Umsch+N)",
"pad.toolbar.ul.title": "Nalicenje (Strg+Umsch+L)",
"pad.toolbar.indent.title": "Zasunuś (TAB)",
"pad.toolbar.unindent.title": "Wusunuś (Umsch+TAB)",
"pad.toolbar.undo.title": "Anulěrowaś (Strg-Z)",
"pad.toolbar.redo.title": "Wóspjetowaś (Strg-Y)",
"pad.toolbar.clearAuthorship.title": "Awtorowe barwy lašowaś",
"pad.toolbar.clearAuthorship.title": "Awtorowe barwy lašowaś (Strg+Umsch+C)",
"pad.toolbar.import_export.title": "Import/Eksport z/do drugich datajowych formatow",
"pad.toolbar.timeslider.title": "Wersijowa historija",
"pad.toolbar.savedRevision.title": "Wersiju składowaś",
@ -26,29 +60,36 @@
"pad.colorpicker.save": "Składowaś",
"pad.colorpicker.cancel": "Pśetergnuś",
"pad.loading": "Zacytujo se...",
"pad.noCookie": "Cookie njejo se namakał. Pšosym dowólśo cookieje w swójom wobglědowaku! Wašo pósejźenje a waše nastajenja se mjazy dwěma woglědoma njeskładuju. To móžo se stas, gaž Etherpad jo w někotarych wobglědowakach w iFrame wopśimjony. Pšosym zawěsććo, až Etherpad jo na samskej póddomenje/domenje ako nadrědowany iFrame",
"pad.permissionDenied": "Njamaš pśistupne pšawo za toś ten zapisnik.",
"pad.settings.padSettings": "Nastajenja zapisnika",
"pad.settings.myView": "Mój naglěd",
"pad.settings.stickychat": "Chat pśecej na wobrazowce pokazaś",
"pad.settings.chatandusers": "Chat a wužywarje pokazaś",
"pad.settings.colorcheck": "Awtorowe barwy",
"pad.settings.linenocheck": "Smužkowe numery",
"pad.settings.rtlcheck": "Wopśimjeśe wótpšawa nalěwo cytaś?",
"pad.settings.fontType": "Pismowa družyna:",
"pad.settings.fontType.normal": "Normalny",
"pad.settings.language": "Rěc:",
"pad.settings.about": "Wó",
"pad.settings.poweredBy": "Pódpěrany wót",
"pad.importExport.import_export": "Import/Eksport",
"pad.importExport.import": "Tekstowu dataju abo dokument nagraś",
"pad.importExport.importSuccessful": "Wuspěšny!",
"pad.importExport.export": "Aktualny zapisnik eksportěrowaś ako:",
"pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Lutny tekst",
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Móžoš jano z fprmatow lutnego teksta abo z HTML-formata importěrowaś. Za wěcej rozšyrjone importěrowańske funkcije <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">instalěruj pšosym Abiword</a>.",
"pad.importExport.abiword.innerHTML": "Móžoš jano z fprmatow lutnego teksta abo z HTML-formata importěrowaś. Za wěcej rozšyrjone importěrowańske funkcije <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">instalěruj pšosym Abiword abo LibreOffice</a>.",
"pad.modals.connected": "Zwězany.",
"pad.modals.reconnecting": "Zwězujo se znowego z twójim zapisnikom...",
"pad.modals.forcereconnect": "Znowego zwězaś",
"pad.modals.reconnecttimer": "Wopytaj se znowego zwězaś w",
"pad.modals.cancel": "Pśetergnuś",
"pad.modals.userdup": "W drugem woknje wócynjony",
"pad.modals.userdup.explanation": "Zda se, až toś ten zapisnik jo se we wěcej ako jadnem woknje wobglědowaka na toś tom licadłu wócynił.",
"pad.modals.userdup.advice": "Zwězaj znowego, aby toś to wokno město togo wužywał.",
@ -67,6 +108,10 @@
"pad.modals.corruptPad.cause": "To jo se snaź wopacneje serweroweje konfiguracije dla abo drugego njewócakanego zaźaržanja dla stało. Pšosym staj se ze słužbowym administratorom do zwiska.",
"pad.modals.deleted": "Wulašowany.",
"pad.modals.deleted.explanation": "Toś ten zapisnik jo se wótpórał.",
"pad.modals.rateLimited": "Wobgranicowana rata.",
"pad.modals.rateLimited.explanation": "Sćo pósłał pśewjele powěsćow na zapisnik, togodla jo se zwisk źělił.",
"pad.modals.rejected.explanation": "Serwer jo wótpokazał powěsć, kótaraž jo se pósłał pśez waš wobglědowak pósłał.",
"pad.modals.rejected.cause": "Serwer jo se snaź zaktualizěrował, mjaztym až sy se woglědał zapisnik, abo dajo snaź zmólku w Etherpad. Wopytaj bok znowego zacytaś.",
"pad.modals.disconnected": "Zwisk jo pśetergnjony.",
"pad.modals.disconnected.explanation": "Zwisk ze serwerom jo se zgubił",
"pad.modals.disconnected.cause": "Serwer njestoj k dispoziciji. Pšosym informěruj słužbowego administratora, jolic to se dalej stawa.",
@ -77,6 +122,9 @@
"pad.chat": "Chat",
"pad.chat.title": "Chat za toś ten zapisnik wócyniś",
"pad.chat.loadmessages": "Dalšne powěsći zacytaś",
"pad.chat.stick.title": "Chat k wobrazowce pśipěś",
"pad.chat.writeMessage.placeholder": "Piš swóju powěsć how",
"timeslider.followContents": "Aktualizacijam wopśimjeśa zapisnika slědowaś",
"timeslider.pageTitle": "{{appTitle}} - wersijowa historija",
"timeslider.toolbar.returnbutton": "Slědk k zapisnikoju",
"timeslider.toolbar.authors": "Awtory:",
@ -85,6 +133,9 @@
"timeslider.exportCurrent": "Aktualnu wersiju eksportěrowaś ako:",
"timeslider.version": "Wersija {{version}}",
"timeslider.saved": "Składowany {{day}}. {{month}} {{year}}",
"timeslider.playPause": "Wopśimjeśe zapisnika wótgraś/pawzěrowaś",
"timeslider.backRevision": "Wó jadnu wersiju w toś tom dokumenśe slědk hyś",
"timeslider.forwardRevision": "Wó jadnu wersiju w toś tom dokumenśe doprědka hyś",
"timeslider.dateformat": "{{day}}. {{month}} {{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "januara",
"timeslider.month.february": "februara",
@ -100,15 +151,18 @@
"timeslider.month.december": "decembra",
"timeslider.unnamedauthors": "{{num}} {[plural(num) one: awtor, two: awtora, few: awtory, other: awtorow ]} bźez mjenja",
"pad.savedrevs.marked": "Toś ta wersija jo se něnto ako składowana wersija markěrowała",
"pad.savedrevs.timeslider": "Móžoš se skłaźone wersije woglědowaś, gaž se k historiji dokumenta woglědujoś.",
"pad.userlist.entername": "Zapódaj swójo mě",
"pad.userlist.unnamed": "bźez mjenja",
"pad.editbar.clearcolors": "Awtorowe barwy w cełem dokumenśe lašowaś?",
"pad.editbar.clearcolors": "Awtorowe barwy w cełem dokumenśe lašowaś? To njedajo se anulěrowaś",
"pad.impexp.importbutton": "Něnto importěrowaś",
"pad.impexp.importing": "Importěrujo se...",
"pad.impexp.confirmimport": "Importowanje dataje pśepišo aktualny tekst zapisnika. Coš napšawdu pókšacowaś?",
"pad.impexp.convertFailed": "Njejsmy mógli toś tu dataju importěrowaś. Pšosym wužyj drugi dokumentowy format abo kopěruj manuelnje",
"pad.impexp.padHasData": "Njejsmy mógli toś tu dataju importěrowaś, dokulaž toś ten dokument južo změny wopśimujo, pšosym importěruj nowy dokument.",
"pad.impexp.uploadFailed": "Nagraśe njejo se raźiło, pšosym wopytaj hyšći raz",
"pad.impexp.importfailed": "Import njejo se raził",
"pad.impexp.copypaste": "Pšosym kopěrowaś a zasajźiś",
"pad.impexp.exportdisabled": "Eksport ako format {{type}} jo znjemóžnjony. Pšosym staj se ze swójim systemowym administratorom za drobnostki do zwiska."
"pad.impexp.exportdisabled": "Eksport ako format {{type}} jo znjemóžnjony. Pšosym staj se ze swójim systemowym administratorom za drobnostki do zwiska.",
"pad.impexp.maxFileSize": "Dataja jo pśewjelika. Staj se ze swójim sedłowym administratorom do zwiska, aby dowólonu datajowu wjelikosć za import pówušył"
}

View File

@ -2,6 +2,7 @@
"@metadata": {
"authors": [
"Nirajan pant",
"बडा काजी",
"रमेश सिंह बोहरा",
"राम प्रसाद जोशी"
]
@ -78,7 +79,7 @@
"pad.modals.disconnected.cause": "सर्भर अनुपलब्ध होइसकन्छ। यदि यो हुनोइ रयाबर कृपया सेवा व्यवस्थापकलाई सूचित अरऽ।",
"pad.share": "यस प्याडलाई बाड्न्या",
"pad.share.readonly": "पड्‍ड्या मात्तरै",
"pad.share.link": "लिङ्क",
"pad.share.link": "डी",
"pad.share.emebdcode": "URL थप्प्या",
"pad.chat": "कुरणिकानी",
"pad.chat.title": "येइ प्याड खिलाइ गफ खोलऽ",

View File

@ -6,35 +6,66 @@
"Glavkos",
"Monopatis",
"Norhorn",
"Papspyr",
"Protnet"
]
},
"index.newPad": "Νέο Pad",
"index.createOpenPad": "ή δημιουργία/άνοιγμα ενός Pad με όνομα:",
"index.openPad": "άνοιγμα υπάρχων Pad με όνομα:",
"pad.toolbar.bold.title": "Έντονη (Ctrl-B)",
"admin.page-title": "Πίνακας ελέγχου διαχειριστή - Etherpad",
"admin_plugins": "Διαχειριστής πρόσθετων",
"admin_plugins.available": "Διαθέσιμα πρόσθετα",
"admin_plugins.available_not-found": "Δεν βρέθηκαν πρόσθετα.",
"admin_plugins.available_install.value": "Εγκατάσταση",
"admin_plugins.available_search.placeholder": "Αναζητήστε πρόσθετα για εγκατάσταση",
"admin_plugins.description": "Περιγραφή",
"admin_plugins.installed": "Εγκατεστημένα πρόσθετα",
"admin_plugins.installed_nothing": "Δεν έχετε εγκαταστήσει πρόσθετα ακόμη.",
"admin_plugins.installed_uninstall.value": "Απεγκατάσταση",
"admin_plugins.last-update": "Τελευταία ενημέρωση",
"admin_plugins.name": "Όνομα",
"admin_plugins.page-title": "Διαχειριστής πρόσθετων - Etherpad",
"admin_plugins.version": "Έκδοση",
"admin_plugins_info": "Πληροφορίες αντιμετώπισης προβλημάτων",
"admin_plugins_info.hooks": "Εγκατεστημένα άγκιστρα",
"admin_plugins_info.hooks_server": "Άγκιστρα από την πλευρά του διακομιστή",
"admin_plugins_info.parts": "Εγκατεστημένα εξαρτήματα",
"admin_plugins_info.plugins": "Εγκατεστημένα πρόσθετα",
"admin_plugins_info.page-title": "Πληροφορίες πρόσθετου - Etherpad",
"admin_plugins_info.version": "Έκδοση Etherpad",
"admin_plugins_info.version_latest": "Τελευταία διαθέσιμη έκδοση",
"admin_plugins_info.version_number": "Αριθμός έκδοσης",
"admin_settings": "Ρυθμίσεις",
"admin_settings.current": "Τρέχουσα διαμόρφωση",
"admin_settings.current_example-devel": "Παράδειγμα προτύπου ρυθμίσεων ανάπτυξης",
"admin_settings.current_example-prod": "Παράδειγμα προτύπου ρυθμίσεων παραγωγής",
"admin_settings.current_restart.value": "Επανεκκινήστε το Etherpad",
"admin_settings.current_save.value": "Αποθήκευση Ρυθμίσεων",
"admin_settings.page-title": "Ρυθμίσεις - Etherpad",
"index.newPad": "Νέος Κοινόχρηστος Πίνακας",
"index.createOpenPad": "ή δημιουργία/άνοιγμα ενός κοινόχρηστου πίνακα με όνομα:",
"index.openPad": "άνοιγμα υπάρχοντος κοινόχρηστού πίνακα με όνομα:",
"pad.toolbar.bold.title": "Έντονα (Ctrl-B)",
"pad.toolbar.italic.title": "Πλάγια (Ctrl-I)",
"pad.toolbar.underline.title": "Υπογράμμιση (Ctrl-U)",
"pad.toolbar.underline.title": "Υπογραμμισμένα (Ctrl-U)",
"pad.toolbar.strikethrough.title": "Διακριτή διαγραφή (Ctrl+5)",
"pad.toolbar.ol.title": "Ταξινομημένη λίστα (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Λίστα χωρίς σειρά (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Αριστερά εσοχή (TAB)",
"pad.toolbar.unindent.title": "Δεξιά εσοχή (Shift+TAB)",
"pad.toolbar.ul.title": "Λίστα χωρίς ταξινόμηση (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Εσοχή (TAB)",
"pad.toolbar.unindent.title": "Εσοχή (Shift+TAB)",
"pad.toolbar.undo.title": "Αναίρεση (Ctrl-Z)",
"pad.toolbar.redo.title": "Επανάληψη (Ctrl-Y)",
"pad.toolbar.clearAuthorship.title": "Εκκαθάριση των χρωμάτων των συντακτών (Ctrl+Shift+C)",
"pad.toolbar.clearAuthorship.title": "Εκκαθάριση χρωμάτων σύνταξης κειμένου (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Εισαγωγή/Εξαγωγή από/σε διαφορετικούς τύπους αρχείων",
"pad.toolbar.timeslider.title": "Χρονοδιάγραμμα",
"pad.toolbar.savedRevision.title": "Αποθήκευση Αναθεώρησης",
"pad.toolbar.settings.title": "Ρυθμίσεις",
"pad.toolbar.embed.title": "Διαμοίραση και Ενσωμάτωση αυτού του pad",
"pad.toolbar.showusers.title": "Εμφάνιση των χρηστών αυτού του pad",
"pad.toolbar.embed.title": "Διαμοίραση και Ενσωμάτωση αυτού του κοινόχρηστου πίνακα",
"pad.toolbar.showusers.title": "Εμφάνιση των χρηστών αυτού του κοινόχρηστου πίνακα",
"pad.colorpicker.save": "Αποθήκευση",
"pad.colorpicker.cancel": "Άκυρο",
"pad.colorpicker.cancel": "Ακύρωση",
"pad.loading": "Φόρτωση...",
"pad.noCookie": "Το cookie δεν βρέθηκε. Παρακαλώ επιτρέψτε τα cookies στον περιηγητή σας! Η περίοδος σύνδεσης και οι ρυθμίσεις σας δεν θα αποθηκευτούν μεταξύ των επισκέψεων. Αυτό μπορεί να οφείλεται στο ότι το Etherpad περιλαμβάνεται σε ένα iFrame σε ορισμένα προγράμματα περιήγησης. Βεβαιωθείτε ότι το Etherpad βρίσκεται στον ίδιο υποτομέα/τομέα με το γονικό iFrame",
"pad.permissionDenied": "Δεν έχετε δικαίωμα πρόσβασης σε αυτό το pad",
"pad.settings.padSettings": "Ρυθμίσεις Pad",
"pad.noCookie": "Το cookie δε βρέθηκε. Παρακαλούμε επιτρέψτε τα cookies στο φυλλομετρητή σας! Η περίοδος σύνδεσης και οι ρυθμίσεις σας δε θα αποθηκευτούν μεταξύ των επισκέψεων. Αυτό μπορεί να οφείλεται επειδή το Etherpad περιλαμβάνεται στο iFrame σε ορισμένα προγράμματα πλοήγησης. Παρακαλούμε βεβαιωθείτε ότι το Etherpad βρίσκεται στον ίδιο υποτομέα/τομέα με το iFrame",
"pad.permissionDenied": "Δεν έχετε δικαίωμα πρόσβασης σε αυτόν τον κοινόχρηστο πίνακα",
"pad.settings.padSettings": "Ρυθμίσεις κοινόχρηστου πίνακα",
"pad.settings.myView": "Η προβολή μου",
"pad.settings.stickychat": "Να είναι πάντα ορατή η συνομιλία",
"pad.settings.chatandusers": "Εμφάνιση Συνομιλίας και Χρηστών",
@ -63,7 +94,7 @@
"pad.modals.reconnecttimer": "Προσπάθεια επανασύνδεσης σε",
"pad.modals.cancel": "Ακύρωση",
"pad.modals.userdup": "Ανοιγμένο σε άλλο παράθυρο",
"pad.modals.userdup.explanation": "Αυτό το pad φαίνεται να είναι ανοιχτό σε περισσότερα από ένα παράθυρο του προγράμματος περιήγησης σε αυτόν τον υπολογιστή.",
"pad.modals.userdup.explanation": "Αυτός ο κοινόχρηστος πίνακας φαίνεται να είναι ανοιχτός σε περισσότερα από ένα παράθυρο του προγράμματος περιήγησης σε αυτόν τον υπολογιστή.",
"pad.modals.userdup.advice": "Επανασυνδεθείτε για να χρησιμοποιήσετε αυτό το παράθυρο.",
"pad.modals.unauth": "Δεν επιτρέπεται",
"pad.modals.unauth.explanation": "Τα δικαιώματά σας άλλαξαν όσο βλέπατε αυτήν τη σελίδα. Δοκιμάστε να επανασυνδεθείτε.",
@ -80,6 +111,7 @@
"pad.modals.corruptPad.cause": "Αυτό μπορεί να οφείλεται σε ένα λάθος στη ρύθμιση του διακομιστή ή κάποια άλλη απρόβλεπτη συμπεριφορά. Παρακαλώ επικοινωνήστε με τον διαχειριστή της υπηρεσίας.",
"pad.modals.deleted": "Διεγράφη.",
"pad.modals.deleted.explanation": "Αυτό το pad έχει καταργηθεί.",
"pad.modals.rejected.explanation": "Ο διακομιστής απέρριψε ένα μήνυμα που στάλθηκε από το πρόγραμμα περιήγησής σας.",
"pad.modals.disconnected": "Είστε αποσυνδεδεμένοι.",
"pad.modals.disconnected.explanation": "Χάθηκε η σύνδεση με τον διακομιστή",
"pad.modals.disconnected.cause": "Ο διακομιστής μπορεί να μην είναι διαθέσιμος. Παρακαλούμε ειδοποιήστε τον διαχειριστή της υπηρεσίας εάν εξακολουθεί να συμβαίνει αυτό.",

View File

@ -2,8 +2,10 @@
"@metadata": {
"authors": [
"Armando-Martin",
"DDPAT",
"Dgstranz",
"Fitoschido",
"Ice bulldog",
"Jacobo",
"Joker",
"Larjona",
@ -98,7 +100,7 @@
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Solo es posible importar texto sin formato o en HTML. Para obtener funciones de importación más avanzadas es necesario <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">instalar AbiWord</a>.",
"pad.modals.connected": "Conectado.",
"pad.modals.reconnecting": "Reconectando a tu pad..",
"pad.modals.reconnecting": "Reconectando a tu pad...",
"pad.modals.forcereconnect": "Forzar reconexión",
"pad.modals.reconnecttimer": "Se intentará reconectar en",
"pad.modals.cancel": "Cancelar",

View File

@ -2,6 +2,7 @@
"@metadata": {
"authors": [
"BMRG14",
"Beginneruser",
"Dalba",
"Ebraminio",
"FarsiNevis",
@ -12,7 +13,7 @@
"الناز"
]
},
"admin.page-title": "داشبورد مدیر - اترپد",
"admin.page-title": "پیش‌خوان مدیر - اترپد",
"admin_plugins": "مدیریت افزونه",
"admin_plugins.available": "افزونه‌های موجود",
"admin_plugins.available_not-found": "هیچ افزونه‌ای یافت نشد.",
@ -59,7 +60,7 @@
"pad.toolbar.undo.title": "باطل‌کردن (Ctrl-Z)",
"pad.toolbar.redo.title": "از نو (Ctrl-Y)",
"pad.toolbar.clearAuthorship.title": "پاک‌کردن رنگ‌های نویسندگی (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "درون‌ریزی/برون‌ریزی از/به قالب‌های مختلف",
"pad.toolbar.import_export.title": "درون‌ریزی/برون‌بری از/به قالب‌های مختلف پرونده",
"pad.toolbar.timeslider.title": "لغزندهٔ زمان",
"pad.toolbar.savedRevision.title": "ذخیره‌سازی نسخه",
"pad.toolbar.settings.title": "تنظیمات",
@ -82,10 +83,10 @@
"pad.settings.language": "زبان:",
"pad.settings.about": "درباره",
"pad.settings.poweredBy": "قدرست‌گرفته از",
"pad.importExport.import_export": "درون‌ریزی/برون‌ریزی",
"pad.importExport.import_export": "درون‌ریزی/برون‌بری",
"pad.importExport.import": "بارگذاری پرونده‌ی متنی یا سند",
"pad.importExport.importSuccessful": "موفقیت آمیز بود!",
"pad.importExport.export": "برون‌ریزی این دفترچه یادداشت با قالب:",
"pad.importExport.export": "برون‌بری این دفترچه یادداشت با قالب:",
"pad.importExport.exportetherpad": "اترپد",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "متن ساده",
@ -133,7 +134,7 @@
"timeslider.toolbar.returnbutton": "بازگشت به دفترچه یادداشت",
"timeslider.toolbar.authors": "نویسندگان:",
"timeslider.toolbar.authorsList": "بدون نویسنده",
"timeslider.toolbar.exportlink.title": "برون‌ریزی",
"timeslider.toolbar.exportlink.title": "برون‌بری",
"timeslider.exportCurrent": "برون‌ریزی نگارش کنونی به عنوان:",
"timeslider.version": "نگارش {{version}}",
"timeslider.saved": "{{month}} {{day}}، {{year}} ذخیره شد",
@ -163,9 +164,9 @@
"pad.impexp.importing": "در حال درون‌ریزی...",
"pad.impexp.confirmimport": "با درون‌ریزی یک پرونده نوشتهٔ کنونی دفترچه پاک می‌شود. آیا می‌خواهید ادامه دهید؟",
"pad.impexp.convertFailed": "ما نمی‌توانیم این پرونده را درون‌ریزی کنیم. خواهشمندیم قالب دیگری برای سندتان انتخاب کرده یا بصورت دستی آنرا کپی کنید",
"pad.impexp.padHasData": "امکان درون‌ریز این پرونده نیست زیرا این پد تغییر کرده‌است. لطفاً در پد جدید درون‌ریزی کنید.",
"pad.impexp.padHasData": "امکان درون‌ریزی این پرونده نیست زیرا این پد تغییر کرده‌است. لطفاً در پد جدید درون‌ریزی کنید.",
"pad.impexp.uploadFailed": "آپلود انجام نشد، دوباره تلاش کنید",
"pad.impexp.importfailed": "درون‌ریزی انجام نشد",
"pad.impexp.copypaste": "کپی پیست کنید",
"pad.impexp.exportdisabled": "برون‌ریزی با قالب {{type}} از کار افتاده است. برای جزئیات بیشتر با مدیر سیستمتان تماس بگیرید."
"pad.impexp.exportdisabled": "برون‌ریزی با قالب {{type}} از کار افتاده است. برای جزئیات بیشتر با مدیر سامانه خودتان تماس بگیرید."
}

167
src/locales/ff.json Normal file
View File

@ -0,0 +1,167 @@
{
"@metadata": {
"authors": [
"Ibrahima Malal Sarr"
]
},
"admin.page-title": "Tiimtorde Jiiloowo - Etherpad",
"admin_plugins": "Toppitorde Ceŋe",
"admin_plugins.available": "Ceŋe goodaaɗe",
"admin_plugins.available_not-found": "Alaa ceŋe njiytaa.",
"admin_plugins.available_fetching": "Nana balloo…",
"admin_plugins.available_install.value": "Aaf",
"admin_plugins.available_search.placeholder": "Yiylo ceŋe aafeteeɗe",
"admin_plugins.description": "Cifol",
"admin_plugins.installed": "Ceŋe aafaaɗe",
"admin_plugins.installed_fetching": "Nana yiyloo ceŋe aafaaɗe…",
"admin_plugins.installed_nothing": "A aafaani ceŋe tawo.",
"admin_plugins.installed_uninstall.value": "Aaftu",
"admin_plugins.last-update": "Kesɗitinal cakkitiingal",
"admin_plugins.name": "Innde",
"admin_plugins.page-title": "Toppitorde ceŋe - Etherpad",
"admin_plugins.version": "Yamre",
"admin_plugins_info": "Humpito njiylaw caɗe",
"admin_plugins_info.hooks": "Logge aafaaɗe",
"admin_plugins_info.hooks_client": "Logge senngo-kuutoro",
"admin_plugins_info.hooks_server": "Logge senngo-sarworde",
"admin_plugins_info.parts": "Terɗe aafaaɗe",
"admin_plugins_info.plugins": "Ceŋe aafaaɗe",
"admin_plugins_info.page-title": "Humpito ceŋe - Etherpad",
"admin_plugins_info.version": "Yamre Etherpad",
"admin_plugins_info.version_latest": "Yamre sakkitiinde woodunde",
"admin_plugins_info.version_number": "Tonngoode yamre",
"admin_settings": "Teelte",
"admin_settings.current": "Teeltannde wonaango",
"admin_settings.current_example-devel": "Yeru tugnorgal teelte topagol",
"admin_settings.current_example-prod": "Yeru tugnorgal teelte baayino",
"admin_settings.current_restart.value": "Hurmitin Etherpad",
"admin_settings.current_save.value": "Danndu Teelte",
"admin_settings.page-title": "Teelte - Etherpad",
"index.newPad": "Alluwal Kesal",
"index.createOpenPad": "walla sos/uddit Alluwal e innde:",
"index.openPad": "Uddit paɗo woodungo e ndee innde:",
"pad.toolbar.bold.title": "Buutol (Ctrl+B)",
"pad.toolbar.italic.title": "Italik (Ctrl+I)",
"pad.toolbar.underline.title": "Diidoles (Ctrl+U)",
"pad.toolbar.strikethrough.title": "Baar (Ctrl+5)",
"pad.toolbar.ol.title": "Doggol leemtangol(Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Doggol ngol lemtaaka",
"pad.toolbar.indent.title": "Ɓeydu taaɓal (TAB)",
"pad.toolbar.unindent.title": "Ruttu taaɓal (Shift+TAB)",
"pad.toolbar.undo.title": "Firtu (Ctrl+Z)",
"pad.toolbar.redo.title": "Waɗtu (Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "Momtu Noone Wallifɓe (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Jiggo/Jiggito iwde/faade mbayka piille goɗɗe",
"pad.toolbar.timeslider.title": "Daasorde tuma",
"pad.toolbar.savedRevision.title": "Dannde Baylital",
"pad.toolbar.settings.title": "Teelte",
"pad.toolbar.embed.title": "Lollin maa soomtor ngoo faɗo",
"pad.toolbar.showusers.title": "Hollu huutorɓe e ngoo faɗo",
"pad.colorpicker.save": "Danndu",
"pad.colorpicker.cancel": "Haaytin",
"pad.loading": "Nana loowa...",
"pad.noCookie": "Kukii yiytaaka. Tiiɗno yamir kukiije e wanngorde maa!\nNaatal maa e teelte maa danndetaake hakkunde njulluuji. Ɗuum ena waawi tawa Etherpad ena soomaa e nder iFrame e won e banngorɗe. Tiiɗno ƴeewto so Etherpad woni ko e domen/lesdomen iFrame yumma oo.",
"pad.permissionDenied": "A alaa yamiroore naatde e ngoo faɗo",
"pad.settings.padSettings": "Teelte Faɗo",
"pad.settings.myView": "Jiytol am",
"pad.settings.stickychat": "Yeewtere e yaynirde sahaa kala",
"pad.settings.chatandusers": "Hollu Yeewtere e Huutorɓe",
"pad.settings.colorcheck": "Noone Wallifɓe",
"pad.settings.linenocheck": "Tonngooɗe gori",
"pad.settings.rtlcheck": "Tar loowdi iwde ñaamo faya nano?",
"pad.settings.fontType": "Fannu binndi:",
"pad.settings.language": "Ɗemngal:",
"pad.settings.about": "Baɗte",
"pad.settings.poweredBy": "Dognata ko",
"pad.importExport.import_export": "Jiggo/Jiggito",
"pad.importExport.import": "Yollu fiilde binndol maa fiilannde",
"pad.importExport.importSuccessful": "Ɓennii no haaniri!",
"pad.importExport.export": "Jiggito faɗo wonaango e innde:",
"pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Binndi ɓolɓolti",
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Mbaaw-ɗaa jiggaade tan ko baykaaji binndi ɓolɓolti maa HTML. Ngam heɓde fannuuji jiggagol ɓurɗi seeɓde, tiiɗno yillo <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">install AbiWord or LibreOffice</a>.",
"pad.modals.connected": "Seŋiima.",
"pad.modals.reconnecting": "Nana seŋoo e faɗo maa…",
"pad.modals.forcereconnect": "Forsu ceŋagol kadi",
"pad.modals.reconnecttimer": "Nana etoo seŋaade kadi ɗoo e",
"pad.modals.cancel": "Haaytin",
"pad.modals.userdup": "Uddit e henorde woɗnde",
"pad.modals.userdup.explanation": "Ngoo faɗo ellee ena udditii e ko ɓuri henorde wanngorde wootere e ndee komputere.",
"pad.modals.userdup.advice": "Seŋo kadi ngam huutoraade ndee henorde kisa.",
"pad.modals.unauth": "Yamiraaka",
"pad.modals.unauth.explanation": "Jamirooje maa mbayliima tuma nde ƴeewataa ngoo hello. Eto seŋaade kadi.",
"pad.modals.looping.explanation": "Caɗeele jokkondiral ena ngoodi faade e sarworde canngoɗinal ndee.",
"pad.modals.looping.cause": "Ma a taw ko a ceŋoriiɗo proxy maa ɓalal-jayngue.",
"pad.modals.initsocketfail": "Sorworde heɓotaako.",
"pad.modals.initsocketfail.explanation": "Horiima seŋaade e sarworde canngoɗinal ndee.",
"pad.modals.initsocketfail.cause": "Ɗuum ena gasa waɗi ɗum ko saɗeede wonnde e wanngorde maa maa ceŋol Enternet maa.",
"pad.modals.slowcommit.explanation": "Sarworde ndee jaabaaki.",
"pad.modals.slowcommit.cause": "Ɗuum ena gasa ko caɗeele ceŋagol laylaytol.",
"pad.modals.badChangeset.explanation": "Taƴtol ngol mbaɗ-ɗaa joopaama rewaani laawol to sarworde canngoɗinal ndee.",
"pad.modals.badChangeset.cause": "Ɗuum ena gasa ko teeltol sarworde ngol moƴƴaani maa geɗel ngel tijjanooka. Tiiɗno jokkondir e jiiloowo sarwiis oo, so aɗa sikki ɗuum ko juumre. Eto seŋaade kadi ngam jokkude taƴtagol maa.",
"pad.modals.corruptPad.explanation": "Faɗo ngo etoto-ɗaa naatde ngoo nattii moƴƴude.",
"pad.modals.corruptPad.cause": "Ɗuum ena gasa addi ɗum ko teeltol sarworde ngol feewaani maa geɗel ngel tijjanooka. Tiiɗno jokkondir e jiiloowo.",
"pad.modals.deleted": "Momtaama.",
"pad.modals.deleted.explanation": "Ngoo faɗo ko momtaango.",
"pad.modals.rateLimited": "Cookol happinaama.",
"pad.modals.rateLimited.explanation": "A neldii ɓatakuuje keewɗe haa ɓurti e ngoo faɗo, wadde e seŋtaama.",
"pad.modals.rejected.explanation": "Sarworde ndee riiwtii ɓatakuru ngu wanngorde maa neldunoo.",
"pad.modals.rejected.cause": "Sarworde ndee ena gasa koko hesɗitinanoo tuma nde ngon-ɗaa e ƴeewde faɗo ngoo, walla ma a taw ena woodi buggere e Etherpad. Eto loowtude hello ngoo.",
"pad.modals.disconnected": "A seŋtaama.",
"pad.modals.disconnected.explanation": "Ceŋagol to sarworde waasaama",
"pad.modals.disconnected.cause": "Sarworde ndee ena gasa heɓotaako. Tiiɗno habru jiiloowo sarwii soo so ɗum nattaani.",
"pad.share": "Lollin ngoo faɗo",
"pad.share.readonly": "Targol tan",
"pad.share.link": "Jokkorde",
"pad.share.emebdcode": "Soomtor URL",
"pad.chat": "Yeewtere",
"pad.chat.title": "Uddit yeewtere ngoo faɗo.",
"pad.chat.loadmessages": "Loow ɓatakuuje goɗɗe",
"pad.chat.stick.title": "Hedde e yaynirde yeewtere",
"pad.chat.writeMessage.placeholder": "Winndu ɗoo ɓatakuru maa",
"timeslider.followContents": "Rewindo kesɗitine loowdi faɗo",
"timeslider.pageTitle": "{{appTitle}} Daasorde tuma",
"timeslider.toolbar.returnbutton": "Rutto to faɗo",
"timeslider.toolbar.authors": "Willifɓe:",
"timeslider.toolbar.authorsList": "Alaa ballifo",
"timeslider.toolbar.exportlink.title": "Jiggito",
"timeslider.exportCurrent": "Jiggito yamre wonaande e innde:",
"timeslider.version": "Yamre {{version}}",
"timeslider.saved": "Danndaama {{month}} {{day}} {{year}}",
"timeslider.playPause": "Tar / Dartin Loowdi Faɗo",
"timeslider.backRevision": "Rutto to baylital e ngoo Faɗo",
"timeslider.forwardRevision": "Yah yeeso to baylital en ngoo Faɗo",
"timeslider.dateformat": "{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Siilo",
"timeslider.month.february": "Colte",
"timeslider.month.march": "MBooy",
"timeslider.month.april": "Seeɗto",
"timeslider.month.may": "Duujal",
"timeslider.month.june": "Korse",
"timeslider.month.july": "Morso",
"timeslider.month.august": "Juko",
"timeslider.month.september": "Silto",
"timeslider.month.october": "Yarkomaa",
"timeslider.month.november": "Jolal",
"timeslider.month.december": "Bowte",
"timeslider.unnamedauthors": "{{num}} innitaaka {[plural(num) goo: ballifo, goɗɗo: wallifɓe]}",
"pad.savedrevs.marked": "Ndee yamre maantaama jooni ko baylital danndangal",
"pad.savedrevs.timeslider": "Aɗa waawi yiyde baylitte danndaaɗe so yillaade daasorde tuma ndee",
"pad.userlist.entername": " Naatnu innde maa",
"pad.userlist.unnamed": "innitaaki",
"pad.editbar.clearcolors": "Momtu noone wallifɓe e fiilannde ndee fof? Ɗum waawaa firteede",
"pad.impexp.importbutton": "Jiggito Jooni",
"pad.impexp.importing": "Nana Jiggitoo...",
"pad.impexp.confirmimport": "Jiggitaade fiilde maa winndito e dow winndannde wonaande ndee. Aɗa yenanaa yiɗde jokkude?",
"pad.impexp.convertFailed": "Min koriima jiggitaade ndee fiilde. Tiiɗno huutoro mbayka fiilannde ngoɗka walla natto ɗakkiraa junngo",
"pad.impexp.padHasData": "Min koriima jiggitaade ndee fiilde sabu ngoo Faɗo meeɗii wayleede, tiiɗno jiggito faade e faɗo heso",
"pad.impexp.uploadFailed": "Jollugol woorii, tiiɗno fuɗɗito",
"pad.impexp.importfailed": "Jiggitol woorii",
"pad.impexp.copypaste": "Tiiɗno natto ɗakkaa",
"pad.impexp.exportdisabled": "Jiggitaade e mbayka {{type}} koko daaƴaa. Tuuɗno jokkondir e jiiloowo yuɓɓo maa ngam ɓeydude faamade.",
"pad.impexp.maxFileSize": "Fiilde ena mawni haa ɓurti. Jokkondir e jiiloowo ngam ɓeydude ɓetol fiilde jamirangol ngam jiggeede"
}

View File

@ -17,13 +17,15 @@
"Stryn",
"Tomi Toivio",
"Veikk0.ma",
"VezonThunder"
"VezonThunder",
"Yupik"
]
},
"admin.page-title": "Ylläpitäjän kojelauta - Etherpad",
"admin_plugins": "Lisäosien hallinta",
"admin_plugins.available": "Saatavilla olevat liitännäiset",
"admin_plugins.available_not-found": "Lisäosia ei löytynyt.",
"admin_plugins.available_fetching": "Noudetaan…",
"admin_plugins.available_install.value": "Asenna",
"admin_plugins.available_search.placeholder": "Etsi asennettavia laajennuksia",
"admin_plugins.description": "Kuvaus",
@ -48,6 +50,7 @@
"admin_settings": "Asetukset",
"admin_settings.current": "Nykyinen kokoonpano",
"admin_settings.current_example-devel": "Esimerkki kehitysasetusten mallista",
"admin_settings.current_restart.value": "Käynnistä Etherpad uudelleen",
"admin_settings.current_save.value": "Tallenna asetukset",
"admin_settings.page-title": "asetukset - Etherpad",
"index.newPad": "Uusi muistio",
@ -166,7 +169,7 @@
"pad.impexp.importing": "Tuodaan...",
"pad.impexp.confirmimport": "Tiedoston tuonti korvaa kaiken muistiossa olevan tekstin. Haluatko varmasti jatkaa?",
"pad.impexp.convertFailed": "TIedoston tuonti epäonnistui. Käytä eri tiedostomuotoa tai kopioi ja liitä käsin.",
"pad.impexp.padHasData": "Tiedostoa ei voitu lisätä lehtiöön, koska lehtiötä on jo muokattu ole hyvä ja lisää tiedosto uuteen lehtiöön",
"pad.impexp.padHasData": "Tiedostoa ei voitu lisätä muistioon, koska muistiota on jo muokattu ole hyvä ja lisää tiedosto uuteen muistioon",
"pad.impexp.uploadFailed": "Lähetys epäonnistui. Yritä uudelleen.",
"pad.impexp.importfailed": "Tuonti epäonnistui",
"pad.impexp.copypaste": "Kopioi ja liitä",

View File

@ -65,17 +65,17 @@
"index.newPad": "Nouveau bloc-notes",
"index.createOpenPad": "ou créer/ouvrir un bloc-notes intitulé:",
"index.openPad": "ouvrir un bloc-note existant avec le nom:",
"pad.toolbar.bold.title": "Gras (Ctrl+B)",
"pad.toolbar.italic.title": "Italique (Ctrl+I)",
"pad.toolbar.underline.title": "Souligné (Ctrl+U)",
"pad.toolbar.strikethrough.title": "Barré (Ctrl+5)",
"pad.toolbar.ol.title": "Liste ordonnée (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Liste non ordonnée (Ctrl+Shift+L)",
"pad.toolbar.bold.title": "Gras (Ctrl+B)",
"pad.toolbar.italic.title": "Italique (Ctrl+I)",
"pad.toolbar.underline.title": "Souligné (Ctrl+U)",
"pad.toolbar.strikethrough.title": "Barré (Ctrl+5)",
"pad.toolbar.ol.title": "Liste ordonnée (Ctrl+Maj+N)",
"pad.toolbar.ul.title": "Liste non ordonnée (Ctrl+Maj+L)",
"pad.toolbar.indent.title": "Indenter (TAB)",
"pad.toolbar.unindent.title": "Désindenter (Maj+TAB)",
"pad.toolbar.undo.title": "Annuler (Ctrl+Z)",
"pad.toolbar.redo.title": "Rétablir (Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "Effacer le surlignage par auteur (Ctrl+Shift+C)",
"pad.toolbar.undo.title": "Annuler (Ctrl+Z)",
"pad.toolbar.redo.title": "Rétablir (Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "Effacer le surlignage par auteur (Ctrl+Maj+C)",
"pad.toolbar.import_export.title": "Importer/Exporter des formats de fichiers différents",
"pad.toolbar.timeslider.title": "Historique dynamique",
"pad.toolbar.savedRevision.title": "Enregistrer la révision",
@ -84,7 +84,7 @@
"pad.toolbar.showusers.title": "Afficher les utilisateurs du bloc-notes",
"pad.colorpicker.save": "Enregistrer",
"pad.colorpicker.cancel": "Annuler",
"pad.loading": "Chargement...",
"pad.loading": "Chargement en cours...",
"pad.noCookie": "Un fichier témoin (ou ''cookie'') na pas pu être trouvé. Veuillez autoriser les fichiers témoins dans votre navigateur! Votre session et vos paramètres ne seront pas enregistrés entre les visites. Cela peut être dû au fait quEtherpad est inclus dans un ''iFrame'' dans certains navigateurs. Veuillez vous assurer quEtherpad est dans le même sous-domaine/domaine que son ''iFrame'' parent.",
"pad.permissionDenied": "Vous nêtes pas autorisé à accéder à ce bloc-notes",
"pad.settings.padSettings": "Paramètres du bloc-notes",
@ -177,11 +177,11 @@
"timeslider.unnamedauthors": "{{num}} {[plural(num) one: auteur anonyme, other: auteurs anonymes ]}",
"pad.savedrevs.marked": "Cette révision est maintenant marquée comme révision enregistrée",
"pad.savedrevs.timeslider": "Vous pouvez voir les révisions enregistrées en ouvrant lhistorique",
"pad.userlist.entername": "Entrez votre nom",
"pad.userlist.entername": "Saisissez votre nom",
"pad.userlist.unnamed": "anonyme",
"pad.editbar.clearcolors": "Effacer le surlignage par auteur dans tout le document? Cette action ne peut être annulée.",
"pad.impexp.importbutton": "Importer maintenant",
"pad.impexp.importing": "Import en cours...",
"pad.impexp.importing": "Importation en cours...",
"pad.impexp.confirmimport": "Importer un fichier écrasera le contenu actuel du bloc-notes. Êtes-vous sûr de vouloir le faire?",
"pad.impexp.convertFailed": "Nous ne pouvons pas importer ce fichier. Veuillez utiliser un autre format de document ou faire manuellement un copier/coller du texte brut",
"pad.impexp.padHasData": "Nous navons pas pu importer ce fichier parce que ce bloc-notes a déjà été modifié; veuillez limporter vers un nouveau bloc-notes.",

View File

@ -48,13 +48,13 @@
"pad.toolbar.strikethrough.title": "Riscar (Ctrl+5)",
"pad.toolbar.ol.title": "Lista ordenada (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Lista sen ordenar (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Sangría (TAB)",
"pad.toolbar.unindent.title": "Sen sangría (Maiús.+TAB)",
"pad.toolbar.indent.title": "Sangrar (TAB)",
"pad.toolbar.unindent.title": "Sen sangrar (Maiús.+TAB)",
"pad.toolbar.undo.title": "Desfacer (Ctrl-Z)",
"pad.toolbar.redo.title": "Refacer (Ctrl-Y)",
"pad.toolbar.clearAuthorship.title": "Eliminar as cores que identifican ás autoras (Ctrl+Shift+C)",
"pad.toolbar.clearAuthorship.title": "Eliminar as cores que identifican ás participantes (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Importar/Exportar desde/a diferentes formatos de ficheiro",
"pad.toolbar.timeslider.title": "Liña do tempo",
"pad.toolbar.timeslider.title": "Cronoloxía",
"pad.toolbar.savedRevision.title": "Gardar a revisión",
"pad.toolbar.settings.title": "Axustes",
"pad.toolbar.embed.title": "Compartir e incorporar este documento",
@ -65,9 +65,9 @@
"pad.noCookie": "Non se puido atopar a cookie. Por favor, habilita as cookies no teu navegador! A túa sesión e axustes non se gardarán entre visitas. Esto podería deberse a que Etherpad está incluído nalgún iFrame nalgúns navegadores. Asegúrate de que Etherpad está no mesmo subdominio/dominio que o iFrame pai",
"pad.permissionDenied": "Non tes permiso para acceder a este documento",
"pad.settings.padSettings": "Configuracións do documento",
"pad.settings.myView": "A miña vista",
"pad.settings.myView": "Ver",
"pad.settings.stickychat": "Chat sempre visible",
"pad.settings.chatandusers": "Mostrar o chat e os usuarios",
"pad.settings.chatandusers": "Mostrar o chat e as usuarias",
"pad.settings.colorcheck": "Cores de identificación",
"pad.settings.linenocheck": "Números de liña",
"pad.settings.rtlcheck": "Queres ler o contido da dereita á esquerda?",
@ -88,7 +88,7 @@
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Só podes importar texto simple ou formatos HTML. Para obter máis información sobre as características de importación avanzadas <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">instala AbiWord</a>.",
"pad.modals.connected": "Conectado.",
"pad.modals.reconnecting": "Reconectando co teu documento...",
"pad.modals.reconnecting": "Reconectando co seu documento...",
"pad.modals.forcereconnect": "Forzar a reconexión",
"pad.modals.reconnecttimer": "Intentarase reconectar en",
"pad.modals.cancel": "Cancelar",
@ -127,10 +127,10 @@
"pad.chat.stick.title": "Pegar a conversa á pantalla",
"pad.chat.writeMessage.placeholder": "Escribe aquí a túa mensaxe",
"timeslider.followContents": "Segue as actualizacións do contido",
"timeslider.pageTitle": "Liña do tempo de {{appTitle}}",
"timeslider.pageTitle": "Cronoloxía de {{appTitle}}",
"timeslider.toolbar.returnbutton": "Volver ao documento",
"timeslider.toolbar.authors": "Autores:",
"timeslider.toolbar.authorsList": "Ningún autor",
"timeslider.toolbar.authors": "Editoras:",
"timeslider.toolbar.authorsList": "Sen Editoras",
"timeslider.toolbar.exportlink.title": "Exportar",
"timeslider.exportCurrent": "Exportar a versión actual en formato:",
"timeslider.version": "Versión {{version}}",
@ -151,12 +151,12 @@
"timeslider.month.october": "outubro",
"timeslider.month.november": "novembro",
"timeslider.month.december": "decembro",
"timeslider.unnamedauthors": "{{num}} {[plural(num) one: autor anónimo, other: autores anónimos ]}",
"timeslider.unnamedauthors": "{{num}} {[plural(num) one: editora anónima, other: editora anónima ]}",
"pad.savedrevs.marked": "Esta revisión está agora marcada como revisión gardada",
"pad.savedrevs.timeslider": "Pode consultar as revisións gardadas visitando a liña do tempo",
"pad.savedrevs.timeslider": "Pode consultar as revisións gardadas visitando a cronoloxía",
"pad.userlist.entername": "Insira o seu nome",
"pad.userlist.unnamed": "anónimo",
"pad.editbar.clearcolors": "Eliminar as cores relativas aos autores en todo o documento? Non se poderán recuperar",
"pad.editbar.clearcolors": "Eliminar as cores relativas ás participantes en todo o documento? Non se poderán recuperar",
"pad.impexp.importbutton": "Importar agora",
"pad.impexp.importing": "Importando...",
"pad.impexp.confirmimport": "A importación dun ficheiro ha sobrescribir o texto actual do documento. Está seguro de querer continuar?",

View File

@ -55,7 +55,7 @@
"pad.toolbar.undo.title": "ביטול (Ctrl-Z)",
"pad.toolbar.redo.title": "ביצוע מחדש",
"pad.toolbar.clearAuthorship.title": "ניקוי צבעי כותבים (Ctrl-Shift-C)",
"pad.toolbar.import_export.title": "ייבוא/ייצוא בתסדירי קבצים שונים",
"pad.toolbar.import_export.title": "יבוא/יצוא בתסדירי קבצים שונים",
"pad.toolbar.timeslider.title": "גולל זמן",
"pad.toolbar.savedRevision.title": "שמירת גרסה",
"pad.toolbar.settings.title": "הגדרות",
@ -78,17 +78,17 @@
"pad.settings.language": "שפה:",
"pad.settings.about": "על אודות",
"pad.settings.poweredBy": "מופעל על גבי",
"pad.importExport.import_export": "ייבוא/ייצוא",
"pad.importExport.import_export": "יבוא/יצוא",
"pad.importExport.import": "העלאת כל קובץ טקסט או מסמך",
"pad.importExport.importSuccessful": "זה עבד!",
"pad.importExport.export": "ייצוא הפנקס הנוכחי בתור:",
"pad.importExport.export": "יצוא הפנקס הנוכחי בתור:",
"pad.importExport.exportetherpad": "את'רפד",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "טקסט רגיל",
"pad.importExport.exportword": "מיקרוסופט וורד",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "באפשרותך לייבא מטקסט פשוט או מ־HTML. לאפשרויות ייבוא מתקדמות יותר יש <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">להתקין AbiWord או LibreOffice</a>.",
"pad.importExport.abiword.innerHTML": "באפשרותך לייבא מטקסט פשוט או מ־HTML. לאפשרויות יבוא מתקדמות יותר יש <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">להתקין AbiWord או LibreOffice</a>.",
"pad.modals.connected": "מחובר.",
"pad.modals.reconnecting": "מתבצע חיבור מחדש למחברת שלך…",
"pad.modals.forcereconnect": "לכפות חיבור מחדש",
@ -133,8 +133,8 @@
"timeslider.toolbar.returnbutton": "חזרה אל הפנקס",
"timeslider.toolbar.authors": "כותבים:",
"timeslider.toolbar.authorsList": "אין כותבים",
"timeslider.toolbar.exportlink.title": "ייצוא",
"timeslider.exportCurrent": "ייצוא הגרסה הנוכחית בתור:",
"timeslider.toolbar.exportlink.title": "יצוא",
"timeslider.exportCurrent": "יצוא הגרסה הנוכחית בתור:",
"timeslider.version": "גרסה {{version}}",
"timeslider.saved": "נשמרה ב־{{day}} ב{{month}} {{year}}",
"timeslider.playPause": "לנגן / לעצור את תוכן הפנקס",
@ -160,13 +160,13 @@
"pad.userlist.unnamed": "ללא שם",
"pad.editbar.clearcolors": "לנקות צבעים לסימון כותבים בכל המסמך? זו פעולה בלתי הפיכה",
"pad.impexp.importbutton": "לייבא כעת",
"pad.impexp.importing": "מתבצע ייבוא…",
"pad.impexp.confirmimport": "ייבוא של קובץ יבטל את הטקסט הנוכחי בפנקס. להמשיך?",
"pad.impexp.importing": "מתבצע יבוא...",
"pad.impexp.confirmimport": "יבוא של קובץ יבטל את הטקסט הנוכחי בפנקס. להמשיך?",
"pad.impexp.convertFailed": "לא הצלחנו לייבא את הקובץ הזה. נא להשתמש בתסדיר מסמך שונה או להעתיק ולהדביק ידנית",
"pad.impexp.padHasData": "לא הצלחנו לייבא את הקובץ הזה, כי בפנקס הזה כבר יש שינויים. נא לייבא לפנקס חדש.",
"pad.impexp.uploadFailed": "ההעלאה נכשלה, נא לנסות שוב",
"pad.impexp.importfailed": "הייבוא נכשל",
"pad.impexp.importfailed": "היבוא נכשל",
"pad.impexp.copypaste": "נא להעתיק ולהדביק",
"pad.impexp.exportdisabled": "ייצוא בתסדיר {{type}} אינו פעיל. מנהל המערכת שלך יוכל לספר לך על זה עוד פרטים.",
"pad.impexp.exportdisabled": "יצוא בתסדיר {{type}} אינו פעיל. מנהל המערכת שלך יוכל לספר לך על זה עוד פרטים.",
"pad.impexp.maxFileSize": "הקובץ גדול מדי. נא ליצור קשר עם הנהלת האתר כדי להגדיל את הגודל המרבי שמותר לייבא."
}

View File

@ -2,7 +2,8 @@
"@metadata": {
"authors": [
"Bugoslav",
"Hmxhmx"
"Hmxhmx",
"Ponor"
]
},
"index.newPad": "Novi blokić",
@ -89,7 +90,7 @@
"pad.chat.title": "Otvori čavrljanje uz ovaj blokić.",
"pad.chat.loadmessages": "Učitaj više poruka",
"pad.chat.stick.title": "Prilijepi razgovor na zaslon",
"pad.chat.writeMessage.placeholder": "Napišite Vašu poruku ovdje",
"pad.chat.writeMessage.placeholder": "Ovdje napišite svoju poruku",
"timeslider.followContents": "Prati ažuriranja sadržaja blokića",
"timeslider.pageTitle": "{{appTitle}} Vremenska lenta",
"timeslider.toolbar.returnbutton": "Vrati se natrag na blokić",

View File

@ -4,8 +4,42 @@
"Michawiki"
]
},
"admin.page-title": "Administratorowa deska Etherpad",
"admin_plugins": "Zrjadowak tykačow",
"admin_plugins.available": "K dispoziciji stejace tykače",
"admin_plugins.available_not-found": "Žane tykače namakane.",
"admin_plugins.available_fetching": "Wobstaruje so …",
"admin_plugins.available_install.value": "Instalować",
"admin_plugins.available_search.placeholder": "Tykače za instalaciju pytać",
"admin_plugins.description": "Wopisanje",
"admin_plugins.installed": "Instalowane tykače",
"admin_plugins.installed_fetching": "Instalowane tykače so wobstaruja …",
"admin_plugins.installed_nothing": "Hišće njejsće tykače instalował.",
"admin_plugins.installed_uninstall.value": "Wotinstalować",
"admin_plugins.last-update": "Poslednja aktualizacija",
"admin_plugins.name": "Mjeno",
"admin_plugins.page-title": "Zrjadowak tykačow Etherpad",
"admin_plugins.version": "Wersija",
"admin_plugins_info": "Informacije wo rozrisanju problemow",
"admin_plugins_info.hooks": "Instalowane hoki",
"admin_plugins_info.hooks_client": "Hoki ze strony klienta",
"admin_plugins_info.hooks_server": "Hoki ze strony serwera",
"admin_plugins_info.parts": "Instalowane dźěle",
"admin_plugins_info.plugins": "Instalowane tykače",
"admin_plugins_info.page-title": "Tykačowe informacije Ehterpad",
"admin_plugins_info.version": "Wersija Etherpad",
"admin_plugins_info.version_latest": "Najnowša wersija",
"admin_plugins_info.version_number": "Wersijowe čisło",
"admin_settings": "Nastajenja",
"admin_settings.current": "Aktualna konfiguracija",
"admin_settings.current_example-devel": "Přikładowa předłoha wuwiwanskich nastajenjow",
"admin_settings.current_example-prod": "Přikładowa předłoha produkciskich nastajenjow",
"admin_settings.current_restart.value": "Etherpad znowa startować",
"admin_settings.current_save.value": "Nastajenja składować",
"admin_settings.page-title": "Nastajenja Etherpad",
"index.newPad": "Nowy zapisnik",
"index.createOpenPad": "abo wutwor/wočiń zapisnik z mjenom:",
"index.openPad": "wočińće eksistowacy Pad z mjenom:",
"pad.toolbar.bold.title": "Tučny (Strg-B)",
"pad.toolbar.italic.title": "Kursiwny (Strg-I)",
"pad.toolbar.underline.title": "Podšmórnyć (Strg-U)",
@ -26,7 +60,7 @@
"pad.colorpicker.save": "Składować",
"pad.colorpicker.cancel": "Přetorhnyć",
"pad.loading": "Začituje so...",
"pad.noCookie": "Plack njeje so namakał. Prošu dopušćće placki w swojim wobhladowaku!",
"pad.noCookie": "Plack njeje so namakał. Prošu dowolće placki w swojim wobhladowaku! Waše posedźenje a nastajenja so mjez dwěmaj wopytomaj njeskładuja. To móže so stać, hdyž Etherpad je w někotrych wobhladowakach w iFrame wobsahowany. Prošu zawěsćće, zo Etherpad je na samsnej poddomenje/domenje kaž nadrjadowany iFrame",
"pad.permissionDenied": "Nimaće prawo za přistup na tutón zapisnik.",
"pad.settings.padSettings": "Nastajenja zapisnika",
"pad.settings.myView": "Mój napohlad",
@ -38,6 +72,8 @@
"pad.settings.fontType": "Pismowa družina:",
"pad.settings.fontType.normal": "Normalny",
"pad.settings.language": "Rěč:",
"pad.settings.about": "Wo",
"pad.settings.poweredBy": "Spěchowany wot",
"pad.importExport.import_export": "Import/Eksport",
"pad.importExport.import": "Tekstowu dataju abo dokument nahrać",
"pad.importExport.importSuccessful": "Wuspěšny!",
@ -48,10 +84,12 @@
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Móžeš jenož z formatow luteho teksta abo z HTML-formata importować. Za bóle rozšěrjene importowanske funkcije <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-in-Ubuntu-or-OpenSuse-or-SLES-with-AbiWord\">instaluj prošu Abiword</a>.",
"pad.importExport.abiword.innerHTML": "Móžeš jenož z formatow luteho teksta abo z HTML-formata importować. Za bóle rozšěrjene importowe funkcije <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">instaluj prošu Abiword abo LibreOffice</a>.",
"pad.modals.connected": "Zwjazany.",
"pad.modals.reconnecting": "Zwjazuje so znowa z twojim zapisnikom...",
"pad.modals.forcereconnect": "Znowa zwjazać",
"pad.modals.reconnecttimer": "Spytaj so znowa zwjazać w",
"pad.modals.cancel": "Přetorhnyć",
"pad.modals.userdup": "W druhim woknje wočinjeny",
"pad.modals.userdup.explanation": "Zda so, zo tutón zapisnik je so we wjace hač jednym woknje wobhladowaka na tutym ličaku wočinił.",
"pad.modals.userdup.advice": "Zwjazaj znowa, zo by tute wokno město toho wužiwał.",
@ -70,6 +108,10 @@
"pad.modals.corruptPad.cause": "To je so snano wopačneje serweroweje konfiguracije dla abo druheho njewočakowaneho zadźerženja dla stało. Prošu staj so ze słužbowym administratorom do zwiska.",
"pad.modals.deleted": "Zhašany.",
"pad.modals.deleted.explanation": "Tutón zapisnik je so wotstronił.",
"pad.modals.rateLimited": "Wobmjezowana rata.",
"pad.modals.rateLimited.explanation": "Sće přewjele powěsćow na zapisnik pósłał, tohodla je so zwisk dźělił.",
"pad.modals.rejected.explanation": "Serwer je powěsć wotpokazał, kotraž je so přez waš wobhladowak pósłał.",
"pad.modals.rejected.cause": "Serwer je so snano zaktualizował, mjeztym zo sy sej zapisnik wobhladał, abo je snano zmylk w Etherpad. Spytaj stronu znowa začitać.",
"pad.modals.disconnected": "Zwisk je přetorhnjeny.",
"pad.modals.disconnected.explanation": "Zwisk ze serwerom je so zhubił",
"pad.modals.disconnected.cause": "Serwer k dispoziciji njesteji. Prošu informuj słužboweho administratora, jeli to so dale stawa.",
@ -80,6 +122,9 @@
"pad.chat": "Chat",
"pad.chat.title": "Chat za tutón zapisnik wočinić",
"pad.chat.loadmessages": "Dalše powěsće začitać",
"pad.chat.stick.title": "Chat k wobrazowce připjeć",
"pad.chat.writeMessage.placeholder": "Pisajće swoju powěsć tu",
"timeslider.followContents": "Aktualizacijam wobsaha zapisnika slědować",
"timeslider.pageTitle": "{{appTitle}} - wersijowa historija",
"timeslider.toolbar.returnbutton": "Wróćo k zapisnikej",
"timeslider.toolbar.authors": "Awtorojo:",
@ -88,7 +133,7 @@
"timeslider.exportCurrent": "Aktualnu wersiju eksportować jako:",
"timeslider.version": "Wersija {{version}}",
"timeslider.saved": "Składowany {{day}}. {{month}} {{year}}",
"timeslider.playPause": "Wobdźěłanje wothrać/pawzować",
"timeslider.playPause": "Wobsah zapisnika wothrać/pawsěrować",
"timeslider.backRevision": "Wo jednu wersiju w tutym dokumenće wróćo hić",
"timeslider.forwardRevision": "Wo jednu wersiju w tutym dokumenće doprědka hić",
"timeslider.dateformat": "{{day}}. {{month}} {{year}} {{hours}}:{{minutes}}:{{seconds}}",
@ -109,7 +154,7 @@
"pad.savedrevs.timeslider": "Móžeš sej składowane wersije wobhladować, wopytujo historiju dokumenta.",
"pad.userlist.entername": "Zapodaj swoje mjeno",
"pad.userlist.unnamed": "bjez mjena",
"pad.editbar.clearcolors": "Awtorowe barby w cyłym dokumenće zhašeć?",
"pad.editbar.clearcolors": "Awtorowe barby w cyłym dokumenće zhašeć? To njeda so cofnyć",
"pad.impexp.importbutton": "Nětko importować",
"pad.impexp.importing": "Importuje so...",
"pad.impexp.confirmimport": "Importowanje dataje přepisa aktualny tekst zapisnika. Chceš woprawdźe pokročować?",
@ -118,5 +163,6 @@
"pad.impexp.uploadFailed": "Nahraće njeje so poradźiło, prošu spytaj hišće raz",
"pad.impexp.importfailed": "Import njeje so poradźiło",
"pad.impexp.copypaste": "Prošu kopěrować a zasadźić",
"pad.impexp.exportdisabled": "Eksport jako format {{type}} je znjemóžnjeny. Prošu staj so ze swojim systemowym administratorom za podrobnosće do zwiska."
"pad.impexp.exportdisabled": "Eksport jako format {{type}} je znjemóžnjeny. Prošu staj so ze swojim systemowym administratorom za podrobnosće do zwiska.",
"pad.impexp.maxFileSize": "Dataja je přewulka. Stajće so ze swojim sydłowym administratorom do zwiska, zo by dowolenu datajowu wulkosć za import powyšił"
}

View File

@ -1,6 +1,7 @@
{
"@metadata": {
"authors": [
"Armenoid",
"Kareyac"
]
},
@ -26,7 +27,7 @@
"pad.settings.fontType": "Տառատեսակի տեսակը",
"pad.settings.language": "Լեզու",
"pad.importExport.import_export": "Ներմուծում/արտահանում",
"pad.importExport.import": "Բեռնել ցանկացած տեքստային ֆայլը կամ փաստաթուղթ",
"pad.importExport.import": "Վերբեռնել ցանկացած տեքստային նիշք կամ փաստաթուղթ",
"pad.importExport.importSuccessful": "Հաջողություն",
"pad.importExport.export": "Արտահանել ընթացիկ փաստաթուղթ է որպես",
"pad.importExport.exportplain": "Պարզ տեքստ",

View File

@ -4,8 +4,42 @@
"McDutchie"
]
},
"admin.page-title": "Pannello administrative Etherpad",
"admin_plugins": "Gestor de plug-ins",
"admin_plugins.available": "Plug-ins disponibile",
"admin_plugins.available_not-found": "Necun plug-in trovate.",
"admin_plugins.available_fetching": "Obtention…",
"admin_plugins.available_install.value": "Installar",
"admin_plugins.available_search.placeholder": "Cercar plug-ins a installar",
"admin_plugins.description": "Description",
"admin_plugins.installed": "Plug-ins installate",
"admin_plugins.installed_fetching": "Obtene plug-ins installate…",
"admin_plugins.installed_nothing": "Tu non ha ancora installate alcun plug-in.",
"admin_plugins.installed_uninstall.value": "Disinstallar",
"admin_plugins.last-update": "Ultime actualisation",
"admin_plugins.name": "Nomine",
"admin_plugins.page-title": "Gestor de plug-ins Etherpad",
"admin_plugins.version": "Version",
"admin_plugins_info": "Resolution de problemas",
"admin_plugins_info.hooks": "Uncinos installate",
"admin_plugins_info.hooks_client": "Uncinos al latere del cliente",
"admin_plugins_info.hooks_server": "Uncinos al latere del servitor",
"admin_plugins_info.parts": "Partes installate",
"admin_plugins_info.plugins": "Plug-ins installate",
"admin_plugins_info.page-title": "Information sur le plug-in  Etherpad",
"admin_plugins_info.version": "Version de Etherpad",
"admin_plugins_info.version_latest": "Ultime version disponibile",
"admin_plugins_info.version_number": "Numero de version",
"admin_settings": "Parametros",
"admin_settings.current": "Configuration actual",
"admin_settings.current_example-devel": "Exemplo de patrono de parametros de disveloppamento",
"admin_settings.current_example-prod": "Exemplo de patrono de parametros de production",
"admin_settings.current_restart.value": "Reinitiar Etherpad",
"admin_settings.current_save.value": "Salveguardar parametros",
"admin_settings.page-title": "Parametros  Etherpad",
"index.newPad": "Nove pad",
"index.createOpenPad": "o crear/aperir un pad con le nomine:",
"index.openPad": "aperir un Pad existente con le nomine:",
"pad.toolbar.bold.title": "Grasse (Ctrl-B)",
"pad.toolbar.italic.title": "Italic (Ctrl-I)",
"pad.toolbar.underline.title": "Sublinear (Ctrl-U)",
@ -38,6 +72,8 @@
"pad.settings.fontType": "Typo de litteras:",
"pad.settings.fontType.normal": "Normal",
"pad.settings.language": "Lingua:",
"pad.settings.about": "A proposito",
"pad.settings.poweredBy": "Actionate per",
"pad.importExport.import_export": "Importar/Exportar",
"pad.importExport.import": "Incargar qualcunque file de texto o documento",
"pad.importExport.importSuccessful": "Succedite!",
@ -72,6 +108,10 @@
"pad.modals.corruptPad.cause": "Isto pote esser debite a un configuration incorrecte del servitor o a alcun altere comportamento impreviste. Per favor contacta le administrator del servicio.",
"pad.modals.deleted": "Delite.",
"pad.modals.deleted.explanation": "Iste pad ha essite removite.",
"pad.modals.rateLimited": "Frequentia limitate.",
"pad.modals.rateLimited.explanation": "Tu ha inviate troppo de messages a iste pad, dunque illo te ha disconnectite.",
"pad.modals.rejected.explanation": "Le servitor ha rejectate un message que tu navigator ha inviate.",
"pad.modals.rejected.cause": "Es possibile que le servitor ha essite actualisate durante que tu legeva le pad, o que il ha un falta in Etherpad. Tenta recargar le pagina.",
"pad.modals.disconnected": "Tu ha essite disconnectite.",
"pad.modals.disconnected.explanation": "Le connexion al servitor ha essite perdite.",
"pad.modals.disconnected.cause": "Le servitor pote esser indisponibile. Per favor notifica le administrator del servicio si isto continua a producer se.",
@ -82,6 +122,9 @@
"pad.chat": "Chat",
"pad.chat.title": "Aperir le chat pro iste pad.",
"pad.chat.loadmessages": "Cargar plus messages",
"pad.chat.stick.title": "Ancorar le chat sur le schermo",
"pad.chat.writeMessage.placeholder": "Scribe tu message hic",
"timeslider.followContents": "Sequer le actualisationes de contento del pad",
"timeslider.pageTitle": "Glissa-tempore pro {{appTitle}}",
"timeslider.toolbar.returnbutton": "Retornar al pad",
"timeslider.toolbar.authors": "Autores:",
@ -120,5 +163,6 @@
"pad.impexp.uploadFailed": "Le incargamento ha fallite. Per favor reproba.",
"pad.impexp.importfailed": "Importation fallite",
"pad.impexp.copypaste": "Per favor copia e colla",
"pad.impexp.exportdisabled": "Le exportation in formato {{type}} es disactivate. Per favor contacta le administrator del systema pro detalios."
"pad.impexp.exportdisabled": "Le exportation in formato {{type}} es disactivate. Per favor contacta le administrator del systema pro detalios.",
"pad.impexp.maxFileSize": "Le file es troppo grande. Contacta le administrator de tu sito pro augmentar le grandor de file autorisate pro importation."
}

View File

@ -3,9 +3,18 @@
"authors": [
"Bennylin",
"IvanLanin",
"Marwan Mohamad"
"Marwan Mohamad",
"Veracious"
]
},
"admin.page-title": "Dasbor Pengurus - Etherpad",
"admin_plugins": "Manajer plugin",
"admin_plugins.available": "Plugin yang tersedia",
"admin_plugins.available_install.value": "Instal",
"admin_plugins.version": "Versi",
"admin_settings": "Pengaturan",
"admin_settings.current_save.value": "Simpan pengaturan",
"admin_settings.page-title": "Pengaturan - Etherpad",
"index.newPad": "Pad baru",
"index.createOpenPad": "atau buat/buka Pad dengan nama:",
"pad.toolbar.bold.title": "Tebal (Ctrl-B)",
@ -39,6 +48,7 @@
"pad.settings.rtlcheck": "Membaca dari kanan ke kiri?",
"pad.settings.fontType": "Jenis fonta:",
"pad.settings.language": "Bahasa:",
"pad.settings.about": "Tentang",
"pad.importExport.import_export": "Impor/Ekspor",
"pad.importExport.import": "Unggah setiap berkas teks atau dokumen",
"pad.importExport.importSuccessful": "Berhasil!",

View File

@ -5,8 +5,39 @@
"Sveinn í Felli"
]
},
"admin.page-title": "Stjórnborð fyrir stjórnendur - Etherpad",
"admin_plugins": "Stýring viðbóta",
"admin_plugins.available": "Tiltækar viðbætur",
"admin_plugins.available_not-found": "Engar viðbætur fundust.",
"admin_plugins.available_fetching": "Sæki…",
"admin_plugins.available_install.value": "Setja upp",
"admin_plugins.available_search.placeholder": "Leita að viðbótum til uppsetningar",
"admin_plugins.description": "Lýsing",
"admin_plugins.installed": "Uppsettar viðbætur",
"admin_plugins.installed_fetching": "Sæki uppsettar viðbætur…",
"admin_plugins.installed_nothing": "Þú hefur ekki ennþá sett upp neinarar viðbætur.",
"admin_plugins.installed_uninstall.value": "Taka út",
"admin_plugins.last-update": "Síðast uppfært",
"admin_plugins.name": "Heiti",
"admin_plugins.page-title": "Stýring viðbóta - Etherpad",
"admin_plugins.version": "Útgáfa",
"admin_plugins_info": "Upplýsingar fyrir úrræðaleit",
"admin_plugins_info.parts": "Uppsettir hlutar",
"admin_plugins_info.plugins": "Uppsettar viðbætur",
"admin_plugins_info.page-title": "Upplýsingar um viðbætur - Etherpad",
"admin_plugins_info.version": "Útgáfa Etherpad",
"admin_plugins_info.version_latest": "Nýjasta tiltæka útgáfa",
"admin_plugins_info.version_number": "Útgáfunúmer",
"admin_settings": "Stillingar",
"admin_settings.current": "Fyrirliggjandi uppsetning",
"admin_settings.current_example-devel": "Sniðmát með dæmigerðum þróunarstillingum",
"admin_settings.current_example-prod": "Sniðmát með dæmigerðum keyrslustillingum",
"admin_settings.current_restart.value": "Endurræsa Etherpad",
"admin_settings.current_save.value": "Vista stillingar",
"admin_settings.page-title": "Stillingar - Etherpad",
"index.newPad": "Ný skrifblokk",
"index.createOpenPad": "eða búa til/opna skrifblokk með heitinu:",
"index.openPad": "opna skrifblokk með heitinu:",
"pad.toolbar.bold.title": "Feitletrað (Ctrl+B)",
"pad.toolbar.italic.title": "Skáletrað (Ctrl+I)",
"pad.toolbar.underline.title": "Undirstrikað (Ctrl+U)",
@ -27,7 +58,7 @@
"pad.colorpicker.save": "Vista",
"pad.colorpicker.cancel": "Hætta við",
"pad.loading": "Hleð inn...",
"pad.noCookie": "Smákaka fannst ekki. Þú verður að leyfa smákökur í vafranum þínum!",
"pad.noCookie": "Vefkaka fannst ekki. Þú verður að leyfa vefkökur í vafranum þínum! Setan þín og stillingar verða ekki vistaðar á milli heimsókna. Þetta gæti stafað af því Etherpad sé innan í iFrame-ramma í sumum vöfrum. Gakktu úr skugga um að Etherpad sé á sama undirléni/léni eins og yfir-iFrame-ramminn",
"pad.permissionDenied": "Þú hefur ekki réttindi til að nota þessa skrifblokk",
"pad.settings.padSettings": "Stillingar skrifblokkar",
"pad.settings.myView": "Mitt yfirlit",
@ -53,7 +84,7 @@
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Þú getur aðeins flutt inn úr hreinum texta eða HTML sniðum. Til að geta nýtt \nfleiri þróaðri innflutningssnið <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">settu þá upp AbiWord forritið eða LibreOffice</a>.",
"pad.modals.connected": "Tengt.",
"pad.modals.reconnecting": "Endurtengist skrifblokkinni þinni...",
"pad.modals.reconnecting": "Endurtengist skrifblokkinni þinni",
"pad.modals.forcereconnect": "Þvinga endurtengingu",
"pad.modals.reconnecttimer": "Reyni aftur að tengjast eftir",
"pad.modals.cancel": "Hætta við",
@ -75,6 +106,9 @@
"pad.modals.corruptPad.cause": "Þetta gæti verið vegna rangrar uppsetningar á þjóninum eða annarar óvæntrar hegðunar. Hafðu samband við stjórnanda þjónustunnar.",
"pad.modals.deleted": "Eytt.",
"pad.modals.deleted.explanation": "Þessi skrifblokk hefur verið fjarlægð.",
"pad.modals.rateLimited": "Með takmörkum.",
"pad.modals.rateLimited.explanation": "Þú hefur sent of mörg skilaboð á þessa skrifblokk, þannig að hún aftengdi þig.",
"pad.modals.rejected.explanation": "Þjónninn hafnaði skilaboðum sem vafrinn þinn sendi.",
"pad.modals.disconnected": "Þú hefur verið aftengd(ur).",
"pad.modals.disconnected.explanation": "Missti tengingu við miðlara",
"pad.modals.disconnected.cause": "Miðlarinn gæti verið ekki tiltækur. Láttu kerfisstjóra vita ef þetta heldur áfram að gerast.",
@ -87,6 +121,7 @@
"pad.chat.loadmessages": "Hlaða inn fleiri skeytum",
"pad.chat.stick.title": "Festa spjallið á skjáinn",
"pad.chat.writeMessage.placeholder": "Skrifaðu skilaboðin þín hér",
"timeslider.followContents": "Fylgja uppfærslum á efni skrifblokkar",
"timeslider.pageTitle": "Tímalína {{appTitle}}",
"timeslider.toolbar.returnbutton": "Fara til baka í skrifblokk",
"timeslider.toolbar.authors": "Höfundar:",
@ -125,5 +160,6 @@
"pad.impexp.uploadFailed": "Sending mistókst, endilega reyndu aftur",
"pad.impexp.importfailed": "Innflutningur mistókst",
"pad.impexp.copypaste": "Afritaðu og límdu",
"pad.impexp.exportdisabled": "Útflutningur á {{type}} sniði er óvirkur. Hafðu samband við kerfisstjóra til að fá frekari aðstoð."
"pad.impexp.exportdisabled": "Útflutningur á {{type}} sniði er óvirkur. Hafðu samband við kerfisstjóra til að fá frekari aðstoð.",
"pad.impexp.maxFileSize": "Of stór skrá. Hafðu samband við kerfisstjóra til að láta auka leyfilega stærð skráa í innflutningi"
}

View File

@ -8,15 +8,21 @@
"Macofe",
"Muxator",
"Nivit",
"VamosErik88",
"Vituzzu"
]
},
"admin.page-title": "Pannello amministrativo - Etherpad",
"admin_plugins": "Gestione plugin",
"admin_plugins.available": "Plugin disponibili",
"admin_plugins.available_not-found": "Nessun plugin trovato.",
"admin_plugins.available_install.value": "Installa",
"admin_plugins.installed_uninstall.value": "Disinstalla",
"admin_plugins.last-update": "Ultimo aggiornamento",
"admin_plugins.name": "Nome",
"admin_plugins.version": "Versione",
"admin_settings": "Impostazioni",
"admin_settings.current_save.value": "Salva impostazioni",
"index.newPad": "Nuovo pad",
"index.createOpenPad": "o crea/apre un pad con il nome:",
"index.openPad": "apri un Pad esistente col nome:",

65
src/locales/kn.json Normal file
View File

@ -0,0 +1,65 @@
{
"@metadata": {
"authors": [
"Nayvik",
"ಮಲ್ನಾಡಾಚ್ ಕೊಂಕ್ಣೊ"
]
},
"admin_plugins.available": "ಲಭ್ಯವಿರುವ ಪ್ಲಗಿನ್‌ಗಳು",
"admin_plugins.available_not-found": "ಯಾವುದೇ ಪ್ಲಗಿನ್‌ಗಳು ಸಿಗಲಿಲ್ಲ",
"admin_plugins.available_fetching": "ಪಡೆಯಲಾಗುತ್ತಿದೆ...",
"admin_plugins.available_install.value": "ಅಳವಡಿಸು",
"admin_plugins.available_search.placeholder": "ಅಳವಡಿಸಲು ಪ್ಲಗಿನ್‌ಗಳನ್ನು ಹುಡುಕಿ",
"admin_plugins.description": "ವಿವರ",
"admin_plugins.installed": "ಅಳವಡಿಸಿದ ಪ್ಲಗಿನ್‌ಗಳು",
"admin_plugins.installed_fetching": "ಅಳವಡಿಸಿದ ಪ್ಲಗಿನ್‌ಗಳನ್ನು ಪಡೆಯಲಾಗುತ್ತಿದೆ...",
"admin_plugins.installed_nothing": "ನೀವು ಇನ್ನೂ ಯಾವುದೇ ಪ್ಲಗಿನ್‌ಗಳನ್ನು ಅಳವಡಿಸಿಲ್ಲ.",
"admin_plugins.name": "ಹೆಸರು",
"admin_plugins.version": "ಆವೃತ್ತಿ",
"admin_plugins_info.plugins": "ಅಳವಡಿಸಿದ ಪ್ಲಗಿನ್‌ಗಳು",
"admin_plugins_info.page-title": "ಪ್ಲಗಿನ್ ಮಾಹಿತಿ - ಈಥರ್‌ಪ್ಯಾಡ್",
"admin_plugins_info.version": "ಈಥರ್‌ಪ್ಯಾಡ್ ಆವೃತ್ತಿ",
"admin_plugins_info.version_number": "ಆವೃತ್ತಿ ಸಂಖ್ಯೆ",
"admin_settings": "ವ್ಯವಸ್ಥೆಗಳು",
"admin_settings.page-title": "ವ್ಯವಸ್ಥೆಗಳು - ಈಥರ್‌ಪ್ಯಾಡ್",
"index.newPad": "ಹೊಸ ಪ್ಯಾಡ್",
"index.createOpenPad": "ಅಥವಾ ಈ ಹೆಸರಿನ ಪ್ಯಾಡನ್ನು ಸೃಷ್ಟಿಸು/ತೆರೆ:",
"pad.toolbar.bold.title": "ದಟ್ಟ (Ctrl-B)",
"pad.toolbar.italic.title": "ಓರೆ (Ctrl-I)",
"pad.toolbar.underline.title": "ಕೆಳಗೆರೆ (Ctrl-U)",
"pad.toolbar.settings.title": "ವ್ಯವಸ್ಥೆಗಳು",
"pad.colorpicker.save": "ಉಳಿಸಿ",
"pad.colorpicker.cancel": "ರದ್ದು ಮಾಡು",
"pad.loading": "ತುಂಬಿಸಲಾಗುತ್ತಿದೆ....",
"pad.settings.myView": "ನನ್ನ ನೋಟ",
"pad.settings.linenocheck": "ಗೆರೆ ಸಂಖ್ಯೆಗಳು",
"pad.settings.language": "ಭಾಷೆ:",
"pad.settings.about": "ಕುರಿತು",
"pad.importExport.import_export": "ಆಮದು/ರಫ್ತು",
"pad.importExport.importSuccessful": "ಯಶಸ್ವಿ!",
"pad.importExport.exportetherpad": "ಈಥರ್‌ಪ್ಯಾಡ್",
"pad.importExport.exporthtml": "ಎಚ್‍ಟಿಎಂಎಲ್",
"pad.importExport.exportplain": "ಸಾದಾ ಪಠ್ಯ",
"pad.importExport.exportword": "ಮೈಕ್ರೋಸಾಫ್ಟ್ ವರ್ಡ್",
"pad.importExport.exportpdf": "ಪಿಡಿಎಫ಼್",
"pad.importExport.exportopen": "ಓಡಿಫ಼್ (ಓಪನ್ ಡಾಕ್ಯುಮೆಂಟ್ ಫ಼ಾರ್ಮ್ಯಾಟ್)",
"pad.modals.cancel": "ರದ್ದು ಮಾಡು",
"pad.share.link": "ಕೊಂಡಿ",
"timeslider.toolbar.authors": "ಕರ್ತೃಗಳು:",
"timeslider.toolbar.exportlink.title": "ರಫ್ತು ಮಾಡು",
"timeslider.version": "ಆವೃತ್ತಿ {{version}}",
"timeslider.saved": "ಉಳಿಸಲಾಗಿದೆ {{month}} {{day}}, {{year}}",
"timeslider.dateformat": "{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "ಜನವರಿ",
"timeslider.month.february": "ಫೆಬ್ರವರಿ",
"timeslider.month.march": "ಮಾರ್ಚ್",
"timeslider.month.april": "ಏಪ್ರಿಲ್",
"timeslider.month.may": "ಮೇ",
"timeslider.month.june": "ಜೂನ್",
"timeslider.month.july": "ಜುಲೈ",
"timeslider.month.august": "ಆಗಸ್ಟ್",
"timeslider.month.september": "ಸೆಪ್ಟೆಂಬರ್",
"timeslider.month.october": "ಅಕ್ಟೋಬರ್",
"timeslider.month.november": "ನವೆಂಬರ್",
"timeslider.month.december": "ಡಿಸೆಂಬರ್"
}

View File

@ -59,7 +59,7 @@
"pad.toolbar.unindent.title": "내어쓰기 (Shift+TAB)",
"pad.toolbar.undo.title": "실행 취소 (Ctrl+Z)",
"pad.toolbar.redo.title": "다시 실행 (Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "저자의 색 지우기 (Ctrl+Shift+C)",
"pad.toolbar.clearAuthorship.title": "작성자 표시 색상 지우기 (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "다른 파일 형식으로 가져오기/내보내기",
"pad.toolbar.timeslider.title": "시간슬라이더",
"pad.toolbar.savedRevision.title": "판 저장",
@ -75,7 +75,7 @@
"pad.settings.myView": "내 보기",
"pad.settings.stickychat": "화면에 항상 대화 보기",
"pad.settings.chatandusers": "대화와 사용자 보기",
"pad.settings.colorcheck": "저자 색",
"pad.settings.colorcheck": "작성자 표시 색상",
"pad.settings.linenocheck": "줄 번호",
"pad.settings.rtlcheck": "우횡서(오른쪽에서 왼쪽으로)입니까?",
"pad.settings.fontType": "글꼴 종류:",
@ -136,7 +136,7 @@
"timeslider.followContents": "패드 콘텐츠의 갱신 주시하기",
"timeslider.pageTitle": "{{appTitle}} 시간슬라이더",
"timeslider.toolbar.returnbutton": "패드로 돌아가기",
"timeslider.toolbar.authors": "자:",
"timeslider.toolbar.authors": "작성자:",
"timeslider.toolbar.authorsList": "저자 없음",
"timeslider.toolbar.exportlink.title": "내보내기",
"timeslider.exportCurrent": "현재 버전으로 내보내기:",
@ -158,12 +158,12 @@
"timeslider.month.october": "10월",
"timeslider.month.november": "11월",
"timeslider.month.december": "12월",
"timeslider.unnamedauthors": "이름 없는 {[plural(num) one: 저자, other: 저자 ]} {{num}}명",
"timeslider.unnamedauthors": "이름 없는 {[plural(num) one: 작성자, other: 작성자]} {{num}}명",
"pad.savedrevs.marked": "이 판은 이제 저장한 판으로 표시합니다.",
"pad.savedrevs.timeslider": "당신은 타임슬라이더를 통해 저장된 버전을 볼 수 있습니다",
"pad.userlist.entername": "이름을 입력하세요",
"pad.userlist.unnamed": "이름없음",
"pad.editbar.clearcolors": "전체 문서의 저자 색을 지우시겠습니까? 이 작업은 취소할 수 없습니다",
"pad.editbar.clearcolors": "전체 문서의 작성자 표시 색상을 지우시겠습니까? 이 작업은 취소할 수 없습니다",
"pad.impexp.importbutton": "지금 가져오기",
"pad.impexp.importing": "가져오는 중...",
"pad.impexp.confirmimport": "파일을 가져오면 패드의 현재 텍스트를 덮어쓰게 됩니다. 진행하시겠습니까?",

View File

@ -1,26 +1,142 @@
{
"@metadata": {
"authors": [
"Ernác"
"Ernác",
"Къарачайлы"
]
},
"admin.page-title": "Администраторну панели — Etherpad",
"admin_plugins": "Плагин менеджер",
"admin_plugins.available": "Киришли плагинле",
"admin_plugins.available_not-found": "Плагинле табылмадыла.",
"admin_plugins.available_fetching": "Келтириле турады...",
"admin_plugins.available_install.value": "Къур",
"admin_plugins.available_search.placeholder": "Къурур ючюн плагинлени изле",
"admin_plugins.description": "Ачыкълау",
"admin_plugins.installed": "Къурулгъан плагинле",
"admin_plugins.installed_fetching": "Къурулгъан плагинле алына турадыла...",
"admin_plugins.installed_nothing": "Алкъын бир плагин да къурмагъансыз.",
"admin_plugins.installed_uninstall.value": "Къорат",
"admin_plugins.last-update": "Ахыр джангыртыу",
"admin_plugins.name": "Ат",
"admin_plugins.page-title": "Плагин менеджер - Etherpad",
"admin_plugins.version": "Версия",
"admin_plugins_info": "Бузукъланы кетериулени юсюнден информация",
"admin_plugins_info.hooks": "Къурулгъан ыргъакъла",
"admin_plugins_info.hooks_client": "Клиентни джанындагъы ыргъакъла",
"admin_plugins_info.hooks_server": "Сервер джанындагъы ыргъакъла",
"admin_plugins_info.parts": "Къурулгъан юлюшле",
"admin_plugins_info.plugins": "Къурулгъан плагинле",
"admin_plugins_info.page-title": "Плагин информация — Etherpad",
"admin_plugins_info.version": "Etherpad версия",
"admin_plugins_info.version_latest": "Ахыр киришли версия",
"admin_plugins_info.version_number": "Версияны номери",
"admin_settings": "Джарашдырыўла",
"admin_settings.current": "Баргъан конфигурация",
"admin_settings.current_example-devel": "Юлгю хазырлау джарашдырыуланы шаблону",
"admin_settings.current_example-prod": "Юлгю чыгъарыу джарашдырыуланы шаблону",
"admin_settings.current_restart.value": "Etherpad-ны джангыдан башлат",
"admin_settings.current_save.value": "Джарашдырыуланы Сакъла",
"admin_settings.page-title": "Джарашдырыула — Etherpad",
"index.newPad": "Джангы Блокнот",
"index.createOpenPad": "неда бу ат бла Блокнот болдур/ач:",
"index.openPad": "бу ат бла бар болгъан Блокнотну ачыгъыз:",
"pad.toolbar.bold.title": "Къалын (Ctrl+B)",
"pad.toolbar.italic.title": "Курсив (Ctrl-I)",
"pad.toolbar.underline.title": "Тюбю чертилген (Ctrl+U)",
"pad.toolbar.strikethrough.title": "Юсю сызылгъан (Ctrl+5)",
"pad.toolbar.ol.title": "Кёзюулю тизме (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Кёзюуге этилмеген тизме (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Абзац (TAB)",
"pad.toolbar.unindent.title": "Чыгъыш (Shift+TAB)",
"pad.toolbar.undo.title": "Кери ал (Ctrl+Z)",
"pad.toolbar.redo.title": "Къайтар (Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "Авторлукъну боялурын тазала (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Файлланы башха форматларын (а/дан) импорт/экспорт",
"pad.toolbar.timeslider.title": "Заман шкала",
"pad.toolbar.savedRevision.title": "Версияны сакъла",
"pad.toolbar.settings.title": "Джарашдырыула",
"pad.toolbar.embed.title": "Бу блокнотну Джай эмда Ичине сал",
"pad.toolbar.showusers.title": "Хайырланыучуланы бу блокнотда кёргюзт",
"pad.colorpicker.save": "Сакъла",
"pad.colorpicker.cancel": "Ызына ал",
"pad.loading": "Джюклениу...",
"pad.noCookie": "Куки табылмадыла. Бразуеригизде кукилени бир джандырсагъыз! Сизни кириулеригизни арасында сессиягъыз эмда джарашдырыуларыгъыз сакъланныкъ тюлдюле. Буну чуруму, бир къауум браузерледе Etherpad iFrame ичинде болгъаны болургъа болур. Тилейбиз, Etherpad эмда аны башындагъы iFrame бир тюбдоменде/доменде болгъанындан ишексиз болугъуз.",
"pad.permissionDenied": "Бу блокнотха кириш эркинлигигиз джокъду",
"pad.settings.padSettings": "Блокнотну джарашдырыулары",
"pad.settings.myView": "Кёрюнюмюм",
"pad.settings.stickychat": "Ушакъны хар заман да экранда кёргюзт",
"pad.settings.chatandusers": "Ушакъ бла къошулуучуланы кёргюзт",
"pad.settings.colorcheck": "Авторлукъ бояула",
"pad.settings.linenocheck": "Сатырланы номерлери",
"pad.settings.rtlcheck": "Ичиндеги онгдан солгъа окъулсунму?",
"pad.settings.fontType": "Шрифтни типи:",
"pad.settings.fontType.normal": "Нормал",
"pad.settings.language": "Тил:",
"pad.settings.about": "Юсюнден",
"pad.settings.poweredBy": "Этген:",
"pad.importExport.import_export": "Импорт/экспорт",
"pad.importExport.import": "Къаллай болса да текст файл неда документ джюкле",
"pad.importExport.importSuccessful": "Тыйыншлы!",
"pad.importExport.export": "Баргъан блокнотну бу шекилде экспорт эт:",
"pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Тюз текст",
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (OpenOffice'ни документи)",
"pad.importExport.abiword.innerHTML": "Сиз къуру тюз текстни неда HTML импорт этерге боллукъсуз. Импортну андан кенг функциялары ючюн <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">AbiWord не LibreOffice къуругъуз</a>.",
"pad.modals.connected": "Байланды.",
"pad.modals.reconnecting": "Блокнотугъузгъа джангыдан байлана турады...",
"pad.modals.forcereconnect": "Джангыдан зор бла байланыу",
"pad.modals.reconnecttimer": "Джангыдан байланыргъа кюрешеди",
"pad.modals.cancel": "Ызына алыу",
"pad.modals.userdup": "Башха терезеде ачыкъды",
"pad.modals.userdup.explanation": "Бу блокнот, бу компьютерде бирден аслам бразуре терезеде ачылгъаннга ушайды.",
"pad.modals.userdup.advice": "Бу терезени хайырланыб джангыдан байлан",
"pad.modals.unauth": "Авторизацияны ётмегенди",
"pad.modals.unauth.explanation": "Бу бетни къарагъан заманда, эркинликлеригиз тюрленнгедиле. Джангыдан байланыб кёрюгюз.",
"pad.modals.looping.explanation": "Синхронизация сервер бла байлам проблемала боладыла.",
"pad.modals.looping.cause": "Келишмеген фаерволл неда прокси бла байланнган болурсуз.",
"pad.modals.initsocketfail": "Серверге джетишилимейди.",
"pad.modals.initsocketfail.explanation": "Синхронизация серверге байланылалмады.",
"pad.modals.initsocketfail.cause": "Бу проблема браузеригиз бла, неда интернет байламыгъыз бла чурумланады.",
"pad.modals.slowcommit.explanation": "Сервер джууаб бермейди.",
"pad.modals.slowcommit.cause": "Бу болум ау байлам бла болгъан проблемала ючюн чыгъаргъа боллукъду.",
"pad.modals.badChangeset.explanation": "Этген тюзетиуюгюзню, синхронизация сервер джараусузча класслагъанды.",
"pad.modals.badChangeset.cause": "Буну чуруму джангылыч сервер конфигурация неда башха сакъланмагъан этиу болургъа боллукъду. Тилейбиз, буну халатха санай эсегиз, къуллукъну администратору бла байланыгъыз. Тюзетиуню андан ары бардырыр ючюн, джангыдан байланыб кёрюгюз.",
"pad.modals.corruptPad.explanation": "Кириш алыргъа излеген блокнот бузукъду.",
"pad.modals.corruptPad.cause": "Буну чуруму джангылыч сервер конфигурация неда башха сакъланмагъан этиу болургъа боллукъду. Тилейбиз, къуллукъну администратору бла байланыгъыз.",
"pad.modals.deleted": "Кетерилди.",
"pad.modals.deleted.explanation": "Бу блокнот къоратылгъанды.",
"pad.modals.rateLimited": "Терклик чеклендирилгенди.",
"pad.modals.rateLimited.explanation": "Бу блокнотха асыры кёб билдириу джибергенигиз ючюн, байлам кесилди.",
"pad.modals.rejected.explanation": "Браузеригиз джибергени билдириуюгюзню алыргъа унамады.",
"pad.modals.rejected.cause": "Блоконтха къарай тургъанлайыгъызгъа, сервер джангыртылыргъа болур неда Etherpad халатлы болургъа болур. Бетни джангыдан джюклеб кёрюгюз.",
"pad.modals.disconnected": "Байламыгъыз кесилди.",
"pad.modals.disconnected.explanation": "Серверге байлам кесилди.",
"pad.modals.disconnected.cause": "Сервер хайырланалмаз халда болургъа болур. Тилейбиз, былай андан ары барса, къуллукъну администраторуна билдиригизю.",
"pad.share": "Бу блокнотну ортагъа сал",
"pad.share.readonly": "Къуру окъу",
"pad.share.link": "Джибериу",
"pad.share.emebdcode": "URL сал",
"pad.chat": "Чат",
"pad.chat.title": "Бу блокнот ючюн ушакъны ач",
"pad.chat.loadmessages": "Мындан аслам билдириу джюкле",
"pad.chat.stick.title": "Ушакъны экраннга джабышдыр",
"pad.chat.writeMessage.placeholder": "Билдириуюгюзню былайда джазыгъыз",
"timeslider.followContents": "Блокнот ичин джангыртыуун марагъыз",
"timeslider.pageTitle": "{{appTitle}} Заман Шкала",
"timeslider.toolbar.returnbutton": "Документге",
"timeslider.toolbar.authors": "Авторла:",
"timeslider.toolbar.authorsList": "Автор джокъду",
"timeslider.toolbar.exportlink.title": "Эспорт эт",
"timeslider.exportCurrent": "Баргъан версияны бу шекилде экспорт эт:",
"timeslider.version": "{{version}} версия",
"timeslider.saved": "{{day}} {{month}} {{year}} датада сакъланнганды",
"timeslider.playPause": "Блокнотну ичин Ойнат / Пауза",
"timeslider.backRevision": "Бу блокнотдагъы версиягъа кери къайт",
"timeslider.forwardRevision": "Блокнотда эндиги версиягъа бар",
"timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}.{{minutes}}.{{seconds}}",
"timeslider.month.january": "январь",
"timeslider.month.february": "февраль",
@ -34,5 +150,20 @@
"timeslider.month.october": "октябрь",
"timeslider.month.november": "ноябрь",
"timeslider.month.december": "декабрь",
"pad.impexp.importing": "Импорт этиу…"
"timeslider.unnamedauthors": "{{num}} атсыз {[plural(num) one: автор, other: автор ]}",
"pad.savedrevs.marked": "Бу версия, артыкъ сакъланнган версия болуб белгиленнгенди",
"pad.savedrevs.timeslider": "Заман шкалагъа кириб, сакъланнган версияланы кёрюрге боллукъсуз",
"pad.userlist.entername": "Атынгы киргизт",
"pad.userlist.unnamed": "атсыз",
"pad.editbar.clearcolors": "Буютеу документдеги автор бояула сюртюлсюнмю? Бу этиу кери алынамаз",
"pad.impexp.importbutton": "Энди импорт эт",
"pad.impexp.importing": "Импорт этиу…",
"pad.impexp.confirmimport": "Файлны импорту баргъан текстни джангыдан джазарыкъды. Андан ары бардырыргъа излегенигизден ишексизмисиз?",
"pad.impexp.convertFailed": "Бу файлны импорт эталмадыкъ. Тилейбиз, башха форматны хайырланыгъыз, неда къол бла копия этиб джабышдырыгъыз",
"pad.impexp.padHasData": "Бу блокнотда алайсыз да тюрлениуле болгъаны ючюн бу файлны импорт эталмадыкъ, тилейбиз джангы блокнотха импорт этигиз",
"pad.impexp.uploadFailed": "Джюклеу джетишимсиз болду, тилейбизщ джангыдан сынагъыз",
"pad.impexp.importfailed": "Импорт этилалмады",
"pad.impexp.copypaste": "Тилейбиз, копия этиб джабышдыргъыз",
"pad.impexp.exportdisabled": "{{type}} форматда экспорт джукъланыбды. Ачыкълаула ючюн система администраторлагъа байланыгъыз.",
"pad.impexp.maxFileSize": "Файл асыры уллуду. Импорт ючюн эркинлик берилген файл ёлчемини уллу этер ючюн сайтны администратору бла байланыгъыз"
}

View File

@ -1,6 +1,7 @@
{
"@metadata": {
"authors": [
"Balyozxane",
"Bikarhêner",
"Dilyaramude",
"George Animal",
@ -59,7 +60,7 @@
"timeslider.toolbar.returnbutton": "Vegere bloknotê",
"timeslider.toolbar.authors": "Nivîser:",
"timeslider.toolbar.authorsList": "Nivîser Tine",
"timeslider.version": "Guhertoya {{version}}",
"timeslider.version": "Guhartoya {{version}}",
"timeslider.saved": "Di dîroka {{day}} {{month}} {{year}} de hate tomarkirin",
"timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}.{{minutes}}.{{seconds}}",
"timeslider.month.january": "kanûna paşîn",

View File

@ -3,12 +3,21 @@
"authors": [
"Gromper",
"Robby",
"Soued031"
"Soued031",
"Volvox"
]
},
"admin_plugins_info.version": "Etherpad Versioun",
"admin_plugins.available_install.value": "Installéieren",
"admin_plugins.description": "Beschreiwung",
"admin_plugins.installed_uninstall.value": "Desinstalléieren",
"admin_plugins.name": "Numm",
"admin_plugins.version": "Versioun",
"admin_plugins_info.version": "Etherpad-Versioun",
"admin_plugins_info.version_latest": "Lescht disponibel Versioun",
"admin_plugins_info.version_number": "Versiounsnummer",
"admin_settings": "Astellungen",
"admin_settings.current_save.value": "Astellunge späicheren",
"admin_settings.page-title": "Astellungen - Etherpad",
"index.newPad": "Neie Pad",
"index.createOpenPad": "oder maacht ee Pad mat dësem Numm op:",
"pad.toolbar.bold.title": "Fett (Strg-B)",
@ -29,7 +38,8 @@
"pad.loading": "Lueden...",
"pad.noCookie": "Cookie gouf net fonnt. Erlaabt wgl. Cookien an Ärem Browser! Är Sessioun an Är Astellungen ginn net tëscht de Visitte gespäichert. Dëst kann doduerch bedéngt sinn datt Etherpad a verschiddene Browser an iFrameën agebaut ass. Vergewëssert Iech wgl. datt Etherpad am selwechten Subdomain/Domain ass wéi den iwwergeuerdneten iFrame",
"pad.permissionDenied": "Dir hutt net déi néideg Rechter fir dëse Pad opzemaachen",
"pad.settings.myView": "Méng Usiicht",
"pad.settings.padSettings": "Pad-Astellungen",
"pad.settings.myView": "Meng Usiicht",
"pad.settings.linenocheck": "Zeilennummeren",
"pad.settings.rtlcheck": "Inhalt vu riets no lénks liesen?",
"pad.settings.fontType": "Schrëftart:",
@ -49,17 +59,21 @@
"pad.modals.connected": "Verbonnen.",
"pad.modals.cancel": "Ofbriechen",
"pad.modals.userdup": "An enger anerer Fënster opgemaach",
"pad.modals.userdup.explanation": "Et schéngt, datt dëse Pad a méi wéi enger Browserfënster op dësem Computer opgemaach ginn ass.",
"pad.modals.unauth": "Net autoriséiert",
"pad.modals.unauth.explanation": "Är Rechter hu geännert während deem Dir dës säit gekuckt hutt. Probéiert fir Iech nei ze connectéieren.",
"pad.modals.looping.explanation": "Et gëtt Kommunikatiounsproblemer mam Synchronisatiouns-Server.",
"pad.modals.initsocketfail": "De Server kann net erreecht ginn.",
"pad.modals.slowcommit.explanation": "De Server äntwert net.",
"pad.modals.deleted": "Geläscht.",
"pad.modals.deleted.explanation": "Dëse Pad gouf geläscht.",
"pad.modals.disconnected": "Äre Verbindung ass ofgebrach.",
"pad.modals.disconnected.explanation": "D'Verbindung mam Server ass verluergaang.",
"pad.share": "Dëse Pad deelen",
"pad.share.readonly": "Nëmme liesen",
"pad.share.link": "Link",
"pad.chat": "Chat",
"pad.chat.title": "Den Chat fir dëse Pad opmaachen.",
"pad.chat.loadmessages": "Méi Message lueden",
"pad.chat.writeMessage.placeholder": "Schreift Äre Message hei",
"timeslider.toolbar.authors": "Auteuren:",

View File

@ -5,10 +5,17 @@
"I-svetaines",
"Mantak111",
"Naktis",
"Nokeoo",
"Vogone",
"Zygimantus"
]
},
"admin.page-title": "Administratoriaus prietaisų skydelis Etherpad",
"admin_plugins": "Įskiepių tvarkyklė",
"admin_plugins.available": "Galimi įskiepiai",
"admin_plugins.available_not-found": "Įskiepių nerasta.",
"admin_plugins.available_fetching": "Gaunama…",
"admin_plugins.available_install.value": "Įdiegti",
"index.newPad": "Naujas bloknotas",
"index.createOpenPad": "arba sukurkite/atidarykite Bloknotą su pavadinimu:",
"pad.toolbar.bold.title": "Paryškintasis (Ctrl-B)",

View File

@ -2,6 +2,7 @@
"@metadata": {
"authors": [
"Akapochtli",
"Languaeditor",
"Taresi"
]
},
@ -15,7 +16,7 @@
"pad.toolbar.redo.title": "Occeppa (Ctrl+Y)",
"pad.toolbar.settings.title": "Tlatlālīliztli",
"pad.colorpicker.save": "Xicpiya",
"pad.colorpicker.cancel": "Moxitiniz",
"pad.colorpicker.cancel": "Xikxolewa",
"pad.settings.padSettings": "Pad Ītlatlālīliz",
"pad.settings.myView": "Notlachiyaliz",
"pad.settings.language": "Tlahtolli:",
@ -24,20 +25,20 @@
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.modals.cancel": "Moxitiniz",
"pad.modals.cancel": "Xikxolewa",
"pad.modals.deleted": "Omopohpoloh.",
"pad.modals.deleted.explanation": "Ōmopoloh inīn Pad.",
"timeslider.version": "Inīc {{version}} Cuepaliztli",
"timeslider.month.january": "Īccēmētztli",
"timeslider.month.february": "Īcōmemētztli",
"timeslider.month.march": "Īcyēyimētztli",
"timeslider.month.april": "Īcnāhuimētztli",
"timeslider.month.may": "Īcmācuīllimētztli",
"timeslider.month.june": "Īcchicuacemmētztli",
"timeslider.month.july": "Īcchicōmemētztli",
"timeslider.month.august": "Īcchicuēyimētztli",
"timeslider.month.september": "Īcchiucnāhuimētztli",
"timeslider.month.october": "Īcmahtlactlimētztli",
"timeslider.month.november": "Īcmahtlactlioncēmētztli",
"timeslider.month.december": "Īcmahtlactliomōmemētztli"
"timeslider.month.january": "Eneroh",
"timeslider.month.february": "Febreroh",
"timeslider.month.march": "Marsoh",
"timeslider.month.april": "April",
"timeslider.month.may": "Mayoh",
"timeslider.month.june": "Honioh",
"timeslider.month.july": "Holioh",
"timeslider.month.august": "Ahostoh",
"timeslider.month.september": "Septiempreh",
"timeslider.month.october": "Oktopreh",
"timeslider.month.november": "Noviempreh",
"timeslider.month.december": "Tisiempreh"
}

View File

@ -3,9 +3,11 @@
"authors": [
"C.R.",
"Chelin",
"Finizio",
"Ruthven"
]
},
"admin_plugins.name": "Nomme",
"index.newPad": "Nuovo Pad",
"index.createOpenPad": "o crià o arape nu Pad cu 'o nomme:",
"pad.toolbar.bold.title": "Grassetto (Ctrl-B)",

View File

@ -3,12 +3,17 @@
"authors": [
"Chameleon222",
"Cocu",
"EdoAug",
"Jon Harald Søby",
"Laaknor",
"Orjanmen",
"SuperPotato"
]
},
"admin_plugins.available_install.value": "Installer",
"admin_plugins.version": "Versjon",
"admin_settings": "Innstillinger",
"admin_settings.current_save.value": "Lagre innstillinger",
"index.newPad": "Ny pad",
"index.createOpenPad": "eller opprett/åpne en pad med dette navnet:",
"index.openPad": "åpne en eksisterende Pad med følgende navn:",

View File

@ -1,8 +1,10 @@
{
"@metadata": {
"authors": [
"Bada Kaji",
"Nirajan pant",
"Nirjal stha",
"बडा काजी",
"राम प्रसाद जोशी",
"सरोज कुमार ढकाल",
"हिमाल सुबेदी"
@ -23,14 +25,14 @@
"pad.toolbar.clearAuthorship.title": "लेखकीय रङ्ग हटाउने (Ctrl+Shift+C)",
"pad.toolbar.timeslider.title": "टाइमस्लाइडर",
"pad.toolbar.savedRevision.title": "पुनरावलोकन संग्रहगर्ने",
"pad.toolbar.settings.title": "सेटिङ्गहरू",
"pad.toolbar.settings.title": "अभिरुचिहरू",
"pad.toolbar.embed.title": "यस प्याडलाई बाड्ने या इम्बेड गर्ने",
"pad.toolbar.showusers.title": "यस प्याडमा रहेका प्रयोगकर्ता देखाउने",
"pad.colorpicker.save": "सङ्ग्रह गर्ने",
"pad.colorpicker.cancel": "रद्द",
"pad.colorpicker.cancel": "रद्द गर्नुहोस्",
"pad.loading": "खुल्दै छ…",
"pad.permissionDenied": "तपाईंलाई यो प्याड खोल्न अनुमति छैन",
"pad.settings.padSettings": "प्याड सेटिङ्गहरू",
"pad.settings.padSettings": "प्याड अभिरुचिहरू",
"pad.settings.myView": "मेरो दृष्य",
"pad.settings.stickychat": "पर्दामा सधै च्याट गर्ने",
"pad.settings.chatandusers": "वार्ता तथा प्रयोगकर्ताहरू देखाउने",
@ -65,7 +67,7 @@
"pad.modals.disconnected.explanation": "तपाईंको सर्भरसँगको जडान अवरुद्ध भयो",
"pad.share": "यस प्यडलाई बाड्ने",
"pad.share.readonly": "पढ्ने मात्र",
"pad.share.link": "लिङ्क",
"pad.share.link": "डी",
"pad.share.emebdcode": "URL थप्ने",
"pad.chat": "कुराकानी",
"pad.chat.title": "यस प्याडको लागि कुराकानी खोल्ने",
@ -78,7 +80,7 @@
"timeslider.exportCurrent": "हालको संस्करण निम्म रुपमा निर्यात गर्ने :",
"timeslider.version": "संस्करण {{version}}",
"timeslider.saved": "सङ्ग्रह गरिएको {{month}} {{day}}, {{year}}",
"timeslider.playPause": "प्याडको सामग्रीहरूलाई चालु/बन्द गर्नुहोस",
"timeslider.playPause": "प्याडको सामग्रीहरूलाई चालु / बन्द गर्नुहोस",
"timeslider.backRevision": "यो प्याडको एक संस्करण पहिले जानुहोस्",
"timeslider.forwardRevision": "यो प्याडको एक संस्करण पछि जानुहोस्",
"timeslider.dateformat": "{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",

View File

@ -13,6 +13,7 @@
"Robin van der Vliet",
"Robin0van0der0vliet",
"Siebrand",
"Spinster",
"woeterman94"
]
},
@ -32,7 +33,7 @@
"admin_plugins.name": "Naam",
"admin_plugins.page-title": "Plugin beheer - Etherpad",
"admin_plugins.version": "Versie",
"admin_plugins_info": "Info",
"admin_plugins_info": "Probleemoplossingsinformatie",
"admin_plugins_info.hooks": "Geïnstalleerde hooks",
"admin_plugins_info.hooks_client": "Client-side hooks",
"admin_plugins_info.hooks_server": "Server-side hooks",
@ -44,13 +45,14 @@
"admin_plugins_info.version_number": "Versie nummer",
"admin_settings": "Instellingen",
"admin_settings.current": "Huidige configuratie",
"admin_settings.current_example-devel": "Development instellingen template",
"admin_settings.current_example-devel": "Voorbeeldsjabloon voor ontwikkelingsinstellingen",
"admin_settings.current_example-prod": "Productie instellingen template",
"admin_settings.current_restart.value": "Herstart Etherpad",
"admin_settings.current_save.value": "Bewaar instellingen",
"admin_settings.page-title": "Instellingen - Etherpad",
"index.newPad": "Nieuw pad",
"index.createOpenPad": "of maak/open een pad met de naam:",
"index.openPad": "open een bestaande Pad met de naam:",
"pad.toolbar.bold.title": "Vet (Ctrl-B)",
"pad.toolbar.italic.title": "Cursief (Ctrl-I)",
"pad.toolbar.underline.title": "Onderstrepen (Ctrl-U)",
@ -84,6 +86,7 @@
"pad.settings.fontType.normal": "Normaal",
"pad.settings.language": "Taal:",
"pad.settings.about": "Over",
"pad.settings.poweredBy": "Aangedreven door",
"pad.importExport.import_export": "Importeren/exporteren",
"pad.importExport.import": "Tekstbestand of document uploaden",
"pad.importExport.importSuccessful": "Afgerond",
@ -118,6 +121,10 @@
"pad.modals.corruptPad.cause": "Dit kan komen door een onjuiste serverinstelling of door ander onverwacht gedrag. Neem contact op met de servicebeheerder.",
"pad.modals.deleted": "Verwijderd.",
"pad.modals.deleted.explanation": "Dit pad is verwijderd.",
"pad.modals.rateLimited": "Snelheid begrensd.",
"pad.modals.rateLimited.explanation": "Je hebt te veel berichten naar deze pad gestuurd. Daarom is je verbinding verbroken.",
"pad.modals.rejected.explanation": "De server heeft een bericht afgewezen dat door je browser is verzonden.",
"pad.modals.rejected.cause": "Mogelijks is de server bijgewerkt terwijl je de pad aan het bekijken was. Of misschien is er een bug in Etherpad. Probeer de pagina opnieuw te laden.",
"pad.modals.disconnected": "Uw verbinding is verbroken.",
"pad.modals.disconnected.explanation": "De verbinding met de server is verbroken",
"pad.modals.disconnected.cause": "De server is mogelijk niet beschikbaar. Stel de servicebeheerder op de hoogte.",
@ -128,8 +135,9 @@
"pad.chat": "Chatten",
"pad.chat.title": "Chat voor dit pad opnenen",
"pad.chat.loadmessages": "Meer berichten laden",
"pad.chat.stick.title": "Zet de chat op het scherm",
"pad.chat.stick.title": "Chat op scherm vastzetten",
"pad.chat.writeMessage.placeholder": "Schrijf je bericht hier",
"timeslider.followContents": "Volg de inhoudelijke updates van de pad",
"timeslider.pageTitle": "Tijdlijn voor {{appTitle}}",
"timeslider.toolbar.returnbutton": "Terug naar pad",
"timeslider.toolbar.authors": "Auteurs:",
@ -168,5 +176,6 @@
"pad.impexp.uploadFailed": "Het uploaden is mislukt. Probeer het opnieuw",
"pad.impexp.importfailed": "Importeren is mislukt",
"pad.impexp.copypaste": "Gebruik kopiëren en plakken",
"pad.impexp.exportdisabled": "Exporteren als {{type}} is uitgeschakeld. Neem contact op met de systeembeheerder voor details."
"pad.impexp.exportdisabled": "Exporteren als {{type}} is uitgeschakeld. Neem contact op met de systeembeheerder voor details.",
"pad.impexp.maxFileSize": "Het bestand is te groot. Neem contact op met je sitebeheerder om de toegestane bestandsgrootte voor importeren te vergroten."
}

View File

@ -18,7 +18,8 @@
"Titoncio",
"Tuliouel",
"Walesson",
"Webysther"
"Webysther",
"YuriNikolai"
]
},
"admin.page-title": "Painel administrativo - Etherpad",
@ -55,18 +56,18 @@
"admin_settings.current_save.value": "Salvar configurações",
"admin_settings.page-title": "Configurações - Etherpad",
"index.newPad": "Nova Nota",
"index.createOpenPad": "ou criar-abrir uma Nota com o nome:",
"index.openPad": "abra um bloco existente com o nome:",
"pad.toolbar.bold.title": "Negrito (Ctrl-B)",
"pad.toolbar.italic.title": "Itálico (Ctrl-I)",
"pad.toolbar.underline.title": "Sublinhado (Ctrl-U)",
"index.createOpenPad": "ou criar/abrir uma Nota com o nome:",
"index.openPad": "abra uma Nota existente com o nome:",
"pad.toolbar.bold.title": "Negrito (Ctrl+B)",
"pad.toolbar.italic.title": "Itálico (Ctrl+I)",
"pad.toolbar.underline.title": "Sublinhado (Ctrl+U)",
"pad.toolbar.strikethrough.title": "Tachado (Ctrl+5)",
"pad.toolbar.ol.title": "Lista ordenada (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Lista não ordenada (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Aumentar Recuo (TAB)",
"pad.toolbar.unindent.title": "Diminuir Recuo (Shift+TAB)",
"pad.toolbar.undo.title": "Desfazer (Ctrl-Z)",
"pad.toolbar.redo.title": "Refazer (Ctrl-Y)",
"pad.toolbar.undo.title": "Desfazer (Ctrl+Z)",
"pad.toolbar.redo.title": "Refazer (Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "Limpar as cores de identificação de autoria (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Importar/Exportar de/para diferentes formatos de arquivo",
"pad.toolbar.timeslider.title": "Linha do tempo",
@ -103,7 +104,7 @@
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Só é possível importar texto sem formatação ou HTML. Para obter funcionalidades de importação mais avançadas, por favor <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">instale o AbiWordor ou LibreOffice</a>.",
"pad.modals.connected": "Conectado.",
"pad.modals.reconnecting": "Reconectando à sua nota...",
"pad.modals.reconnecting": "Reconectando à sua nota",
"pad.modals.forcereconnect": "Forçar reconexão",
"pad.modals.reconnecttimer": "Tentando se reconectar",
"pad.modals.cancel": "Cancelar",
@ -128,6 +129,7 @@
"pad.modals.rateLimited": "Limitado.",
"pad.modals.rateLimited.explanation": "Você enviou muitas mensagens para este pad por isso será desconectado.",
"pad.modals.rejected.explanation": "O servidor rejeitou uma mensagem que foi enviada pelo seu navegador.",
"pad.modals.rejected.cause": "O server pode ter sido atualizado enquanto visualizava esta nota, ou talvez seja apenas um bug do Etherpad. Tenta recarregar a página.",
"pad.modals.disconnected": "Você foi desconectado.",
"pad.modals.disconnected.explanation": "A conexão com o servidor foi perdida",
"pad.modals.disconnected.cause": "O servidor pode estar indisponível. Por favor, notifique o administrador caso isso continue.",

168
src/locales/sc.json Normal file
View File

@ -0,0 +1,168 @@
{
"@metadata": {
"authors": [
"Adr mm"
]
},
"admin.page-title": "Pannellu de amministratzione - Etherpad",
"admin_plugins": "Gestore de connetores",
"admin_plugins.available": "Connetores a disponimentu",
"admin_plugins.available_not-found": "Nissunu connetore a disponimentu",
"admin_plugins.available_fetching": "Recuperende...",
"admin_plugins.available_install.value": "Installa",
"admin_plugins.available_search.placeholder": "Chirca connetores de installare",
"admin_plugins.description": "Descritzione",
"admin_plugins.installed": "Connetores installados",
"admin_plugins.installed_fetching": "Recuperende connetores installados...",
"admin_plugins.installed_nothing": "No as installadu ancora nissunu connetore.",
"admin_plugins.installed_uninstall.value": "Disinstalla",
"admin_plugins.last-update": "Ùrtima atualizatzione",
"admin_plugins.name": "Nòmine",
"admin_plugins.page-title": "Gestore de connetores - Etherpad",
"admin_plugins.version": "Versione",
"admin_plugins_info": "Informatzione pro sa risolutzione de problemas",
"admin_plugins_info.hooks": "Gantzos installados",
"admin_plugins_info.hooks_client": "Gantzos dae su costadu de su cliente",
"admin_plugins_info.hooks_server": "Gantzos dae su costadu de su serbidore",
"admin_plugins_info.parts": "Partes installadas",
"admin_plugins_info.plugins": "Connetores installados",
"admin_plugins_info.page-title": "Informatzione de su connetore - Etherpad",
"admin_plugins_info.version": "Versione de Etherpad",
"admin_plugins_info.version_latest": "Ùrtima versione a disponimentu",
"admin_plugins_info.version_number": "Nùmeru de versione",
"admin_settings": "Cunfiguratzione",
"admin_settings.current": "Cunfiguratzione atuale",
"admin_settings.current_example-devel": "Modellu de esempru de cunfiguratzione de isvilupu",
"admin_settings.current_example-prod": "Modellu de esempru de cunfiguratzione de produtzione",
"admin_settings.current_restart.value": "Torra a aviare Etherpad",
"admin_settings.current_save.value": "Sarva sa cunfiguratzione",
"admin_settings.page-title": "Cunfiguratzione - Etherpad",
"index.newPad": "Pad nou",
"index.createOpenPad": "o crea/aberi unu pad cun su nòmine:",
"index.openPad": "aberi unu pad esistente cun su nòmine:",
"pad.toolbar.bold.title": "Grassetu (Ctrl+B)",
"pad.toolbar.italic.title": "Cursivu (Ctrl+I)",
"pad.toolbar.underline.title": "Sutaliniadu (Ctrl+U)",
"pad.toolbar.strikethrough.title": "Istangadu (Ctrl+5)",
"pad.toolbar.ol.title": "Lista numerada (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Lista cun puntos (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Indentatzione a dereta (Tab)",
"pad.toolbar.unindent.title": "Indentatzione a manca (Shift+Tab)",
"pad.toolbar.undo.title": "Iscontza (Ctrl+Z)",
"pad.toolbar.redo.title": "Torra a fàghere (Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "Lìmpia is colores de autoria (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Importa/esporta dae/a formados de archìviu diferentes",
"pad.toolbar.timeslider.title": "Presentatzione cronologia",
"pad.toolbar.savedRevision.title": "Sarva sa versione",
"pad.toolbar.settings.title": "Cunfiguratzione",
"pad.toolbar.embed.title": "Cumpartzi e incòrpora custu pad",
"pad.toolbar.showusers.title": "Ammustra is utentes in custu pad",
"pad.colorpicker.save": "Sarva",
"pad.colorpicker.cancel": "Annulla",
"pad.loading": "Carrighende...",
"pad.noCookie": "Su testimòngiu no est istètiu agatadu. Permite is testimòngios in su navigadore tuo. Sa sessione e sa cunfiguratzione tuas no ant a èssere sarvadas intre bìsitas. Podet èssere pro more de s'inclusione de Etherpad comente iFrame in tzertos navigadores. Assegura·ti chi Etherpad s'agatat in su pròpiu sutadomìniu/domìniu chi s'iFrame printzipale",
"pad.permissionDenied": "Non tenes permissu pro atzèdere a custu pad",
"pad.settings.padSettings": "Cunfiguratzione de su pad",
"pad.settings.myView": "Sa visualizatzione mia",
"pad.settings.stickychat": "Ammustra semper sa tzarrada",
"pad.settings.chatandusers": "Ammustra sa tzarrada e is utentes",
"pad.settings.colorcheck": "Colores de autoria",
"pad.settings.linenocheck": "Nùmeros de lìnia",
"pad.settings.rtlcheck": "Cuntenutu dae manca a dereta",
"pad.settings.fontType": "Tipu de caràtere:",
"pad.settings.fontType.normal": "Normale",
"pad.settings.language": "Lìngua:",
"pad.settings.about": "Informatziones",
"pad.settings.poweredBy": "Realizadu cun",
"pad.importExport.import_export": "Importatzione/esportatzione",
"pad.importExport.import": "Càrriga un'archìviu de testu o unu documentu",
"pad.importExport.importSuccessful": "Carrigadu.",
"pad.importExport.export": "Esporta su pad atuale comente:",
"pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Testu sèmplitze",
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Documentu Formadu)",
"pad.importExport.abiword.innerHTML": "Isceti is formados de testu sèmplitze o HTML podent èssere importados. Pro mètodos avantzados de importatzione, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">installa AbiWord o LibreOffice</a>.",
"pad.modals.connected": "Connètidu.",
"pad.modals.reconnecting": "Connetende a su pad tuo...",
"pad.modals.forcereconnect": "Fortza sa connesione",
"pad.modals.reconnecttimer": "Torrende a connètere in",
"pad.modals.cancel": "Annulla",
"pad.modals.userdup": "Abertu in una àtera ventana",
"pad.modals.userdup.explanation": "Podet dare chi custu pad siat abertu in un'àtera ischeda de custu navigadore in custu ordinadore.",
"pad.modals.userdup.advice": "Torra a connètere pro impreare custa ventana.",
"pad.modals.unauth": "Chena autorizatzione",
"pad.modals.unauth.explanation": "Is permissos tuos sunt istados cambiados in su mentras chi fias bidende custa pàgina. Prova de ti torrare a connètere.",
"pad.modals.looping.explanation": "Bi sunt problemas de comunicatzione cun su serbidore de sincronizatzione.",
"pad.modals.looping.cause": "Forsis sa connessione at impreadu unu serbidore intermediàriu (proxy) o unu firewall chi no est cumpatìbile.",
"pad.modals.initsocketfail": "Su serbidore no est atzessìbile.",
"pad.modals.initsocketfail.explanation": "Impossìbile connètere cun su serbidore de sincronizatzione.",
"pad.modals.initsocketfail.cause": "Podet èssere a càusa de unu problema cun su navigadore tuo o cun sa connessione de internet.",
"pad.modals.slowcommit.explanation": "Su serbidore non rispondet.",
"pad.modals.slowcommit.cause": "Podet èssere a càusa de problemas cun sa connessione de internet.",
"pad.modals.badChangeset.explanation": "Una modìfica tua est istada cunsiderada illegale dae su serbidore de sincronizatzione.",
"pad.modals.badChangeset.cause": "Podet èssere a càusa de una cunfiguratzione de serbidore isballiada o calicunu àteru cumportamentu imprevistu. Iscrie a s'amministratzione de su servìtziu si pensas chi siat un'errore. Prova a connètere torra pro sighire a modificare.",
"pad.modals.corruptPad.explanation": "Su pad a su chi ses chirchende de atzèdere est dannadu.",
"pad.modals.corruptPad.cause": "Podet èssere a càusa de una cunfiguratzione de serbidore non curreta o pro unu cumportamentu imprevistu. Iscrie a s'amministratzione de su servìtziu.",
"pad.modals.deleted": "Cantzelladu.",
"pad.modals.deleted.explanation": "Pad cantzelladu.",
"pad.modals.rateLimited": "Frecuèntzia limitada.",
"pad.modals.rateLimited.explanation": "As imbiadu tropu messàgios a custu pad e t'at disconnètidu.",
"pad.modals.rejected.explanation": "Su serbidore at rifiutadu unu messàgiu imbiadu dae su navigadore tuo.",
"pad.modals.rejected.cause": "Podet èssere chi su serbidore siat istadu atualizadu in su mentras chi fias bidende su pad, o podet èssere chi bi siat un'errore in Etherpad. Prova a atualizare sa pàgina.",
"pad.modals.disconnected": "Disconnètidu.",
"pad.modals.disconnected.explanation": "Connessione cun su serbidore pèrdida.",
"pad.modals.disconnected.cause": "Su serbidore no est a disponimentu. Iscrie a s'amministratzione de su servìtziu si su problema persistet.",
"pad.share": "Cumpartzi custu pad",
"pad.share.readonly": "Letura isceti",
"pad.share.link": "Ligàmene",
"pad.share.emebdcode": "Incòrpora URL",
"pad.chat": "Tzarrada",
"pad.chat.title": "Aberi sa tzarrada pro custu pad.",
"pad.chat.loadmessages": "Càrriga àteros messàgios",
"pad.chat.stick.title": "Apica sa tzarrada in s'ischermu",
"pad.chat.writeMessage.placeholder": "Iscrie su messàgiu tuo inoghe",
"timeslider.followContents": "Sighi sas atualizatziones de cuntenutu de su pad",
"timeslider.pageTitle": "Cronologia {{appTitle}}",
"timeslider.toolbar.returnbutton": "Torra a su pad",
"timeslider.toolbar.authors": "Autores:",
"timeslider.toolbar.authorsList": "Nissunu autore",
"timeslider.toolbar.exportlink.title": "Esporta",
"timeslider.exportCurrent": "Esporta sa versione atuale comente:",
"timeslider.version": "Versione {{version}}",
"timeslider.saved": "Sarvadu su {{day}} de {{month}} de su {{year}}",
"timeslider.playPause": "Riprodutzione/pàusa de is cuntenutos de su pad",
"timeslider.backRevision": "Bae a una versione pretzedente de custu pad",
"timeslider.forwardRevision": "Bae a una versione imbeniente de custu pad",
"timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Ghennàrgiu",
"timeslider.month.february": "Freàrgiu",
"timeslider.month.march": "Martzu",
"timeslider.month.april": "Abrile",
"timeslider.month.may": "Maju",
"timeslider.month.june": "Làmpadas",
"timeslider.month.july": "Mese de argiolas",
"timeslider.month.august": "Austu",
"timeslider.month.september": "Cabudanni",
"timeslider.month.october": "Ledàmine",
"timeslider.month.november": "Onniasantu",
"timeslider.month.december": "Mese de idas",
"timeslider.unnamedauthors": "{{num}} {[plural(num) one: autore, other: autores ]} chena nòmine",
"pad.savedrevs.marked": "Custa revisione est istada marcada comente revisione sarvada",
"pad.savedrevs.timeslider": "Podes bìdere is versiones sarvadas bisitende sa cronologia",
"pad.userlist.entername": "Inserta su nòmine tuo",
"pad.userlist.unnamed": "Chena nòmine",
"pad.editbar.clearcolors": "Seguru chi boles limpiare is colores de autoria de totu su documentu? Custa atzione no dda podes annullare",
"pad.impexp.importbutton": "Importa immoe",
"pad.impexp.importing": "Importende...",
"pad.impexp.confirmimport": "S'importatzione de un'archìviu at a subraiscrìere su testu atuale de su pad. Seguru chi boles sighire?",
"pad.impexp.convertFailed": "Impossìbile importare custu archìviu. Imprea unu formadu de documentu diferente o còpia e incolla a manu",
"pad.impexp.padHasData": "Impossìbile importare custu archìviu pro ite custu pad est istadu giai modificadu. Importa·ddu in unu pad nou",
"pad.impexp.uploadFailed": "Errore in sa càrriga. Torra a provare",
"pad.impexp.importfailed": "Errore de importatzione",
"pad.impexp.copypaste": "Còpia e incolla",
"pad.impexp.exportdisabled": "S'esportatzione comente {{type}} est disativada. Iscrie a s'amministratzione de su sistema pro àteras informatziones.",
"pad.impexp.maxFileSize": "S'archìviu est tropu manu. Iscrie a s'amministratzione pro ismanniare sa dimensione permìtida pro s'importatzione"
}

View File

@ -5,8 +5,16 @@
"Vlad5250"
]
},
"admin_plugins.available_not-found": "Nijedan plugin nije pronađen.",
"admin_plugins.description": "Opis",
"admin_plugins.installed_uninstall.value": "Deinstaliraj",
"admin_plugins.last-update": "Posljednja podnova",
"admin_plugins.name": "Naziv",
"admin_plugins.version": "Verzija",
"admin_settings.current_save.value": "Sačuvaj podešavanja",
"index.newPad": "Novi blokić",
"index.createOpenPad": "ili napravite/otvorite blokić s imenom:",
"index.openPad": "otvori postojeći blokić Etherpada s imenom:",
"pad.toolbar.bold.title": "Podebljano (Ctrl+B)",
"pad.toolbar.italic.title": "Ukošeno (Ctrl+I)",
"pad.toolbar.underline.title": "Podcrtano (Ctrl+U)",
@ -14,7 +22,7 @@
"pad.toolbar.ol.title": "Poredani spisak (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Neporedani spisak (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Uvlaka (TAB)",
"pad.toolbar.unindent.title": "Izvlaka (Shift+TAB)",
"pad.toolbar.unindent.title": "Izvlačenje (Shift+TAB)",
"pad.toolbar.undo.title": "Vrati (Ctrl+Z)",
"pad.toolbar.redo.title": "Ponovi (Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "Ukloni boje autorstva (Ctrl+Shift+C)",
@ -27,7 +35,7 @@
"pad.colorpicker.save": "Snimi",
"pad.colorpicker.cancel": "Otkaži",
"pad.loading": "Učitavam...",
"pad.noCookie": "Nisam mogao pronaći kolačić. Omogućite kolačiće u vašem pregledniku!",
"pad.noCookie": "Kolačić nije pronađen. Molimo Vas, omogućite kolačiće u Vašem pregledniku! Sesija i podešavanja neće biti sačuvana uz sljedeće posjećivanje. Razlog može biti uključenost Etherpada u iFrame u nekim preglednicima. Molimo Vas, osigurajte da je Etherpad na istoj poddomeni/domeni kao i roditeljski iFrame",
"pad.permissionDenied": "Za ovdje nije potrebna dozvola za pristup",
"pad.settings.padSettings": "Postavke blokića",
"pad.settings.myView": "Moj prikaz",
@ -38,6 +46,8 @@
"pad.settings.rtlcheck": "Da prikažem sadržaj zdesna ulijevo?",
"pad.settings.fontType": "Tip fonta:",
"pad.settings.language": "Jezik:",
"pad.settings.about": "O projektu",
"pad.settings.poweredBy": "Omogućeno od strane",
"pad.importExport.import_export": "Uvoz/Izvoz",
"pad.importExport.import": "Otpremanje bilo koje tekstualne datoteke ili dokumenta",
"pad.importExport.importSuccessful": "Uspješno!",
@ -48,7 +58,7 @@
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Možete uvoziti samo iz običnog teksta te HTML-formata. Naprednije mogućnosti uvoza dobit ćete ako <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">uspostavite AbiWord</a>.",
"pad.importExport.abiword.innerHTML": "Možete uvoziti samo iz običnog teksta te datoteke u formatima HTML-a. Naprednije mogućnosti uvoza dobit ćete ako <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">instalirajte AbiWord ili LibreOffice</a>.",
"pad.modals.connected": "Povezano.",
"pad.modals.reconnecting": "Prepovezujemo Vas s blokićem...",
"pad.modals.forcereconnect": "Nametni prepovezivanje",
@ -72,6 +82,10 @@
"pad.modals.corruptPad.cause": "Ovo može biti zbog pogrešne postavljenosti poslužitelja ili nekog drugog neočekivanog ponašanja. Obratite se administratoru.",
"pad.modals.deleted": "Obrisano.",
"pad.modals.deleted.explanation": "Ovaj blokić je uklonjen.",
"pad.modals.rateLimited": "Ograničenje stopa.",
"pad.modals.rateLimited.explanation": "Poslali ste previše poruka na ovaj blokić, te ste stoga odspojeni.",
"pad.modals.rejected.explanation": "Poslužitelj je odbio poruku koju je poslao vaš preglednik.",
"pad.modals.rejected.cause": "Poslužitelj je možda podnovljen dok ste gledali blokić, ili možda postoji greška u Etherpadu. Pokušajte ponovo učitati stranicu.",
"pad.modals.disconnected": "Veza je prekinuta.",
"pad.modals.disconnected.explanation": "Veza s poslužiteljem je prekinuta",
"pad.modals.disconnected.cause": "Moguće je da server nije dostupan. Obavijestite administratora ako se ovo nastavi događati.",
@ -84,6 +98,7 @@
"pad.chat.loadmessages": "Učitaj više poruka",
"pad.chat.stick.title": "Zalijepi ćaskanje na ekranu",
"pad.chat.writeMessage.placeholder": "Ovdje napišite poruku",
"timeslider.followContents": "Prati podnove sadržaja blokića",
"timeslider.pageTitle": "{{appTitle}} Historijski pregled",
"timeslider.toolbar.returnbutton": "Natrag na blokić",
"timeslider.toolbar.authors": "Autori:",
@ -113,7 +128,7 @@
"pad.savedrevs.timeslider": "Možete pogledati spremljene inačice rabeći vremesledni klizač",
"pad.userlist.entername": "Upišite svoje ime",
"pad.userlist.unnamed": "bez imena",
"pad.editbar.clearcolors": "Ukloniti boje autorstva sa cijelog dokumenta?",
"pad.editbar.clearcolors": "Ukloniti boje autorstva sa cijelog dokumenta? Radnju nije moguće poništiti",
"pad.impexp.importbutton": "Uvezi odmah",
"pad.impexp.importing": "Uvozim...",
"pad.impexp.confirmimport": "Uvoženje datoteke presnimit će trenutni sadržaj blokića.\nJeste li sigurni da želite nastaviti?",
@ -122,5 +137,6 @@
"pad.impexp.uploadFailed": "Postavljanje nije uspjelo. Pokušajte ponovo.",
"pad.impexp.importfailed": "Uvoz nije uspio",
"pad.impexp.copypaste": "Prekopirajte",
"pad.impexp.exportdisabled": "Izvoz u formatu {{type}} je onemogućen. Ako želite saznati više o ovome, obratite se administratoru sustava."
"pad.impexp.exportdisabled": "Izvoz u formatu {{type}} je onemogućen. Ako želite saznati više o ovome, obratite se administratoru sustava.",
"pad.impexp.maxFileSize": "Datoteka je prevelika. Kontaktirajte administratora kako biste zatražili povećanje dopuštene veličine datoteke za uvoz"
}

View File

@ -1,6 +1,7 @@
{
"@metadata": {
"authors": [
"Jose1711",
"Kusavica",
"Lexected",
"Mark",
@ -39,7 +40,7 @@
"admin_settings.current": "Aktuálne nastavenia",
"admin_settings.current_example-devel": "Príklad šablóny vývojárskeho nastavenia",
"admin_settings.current_example-prod": "Príklad šablóny výrobného nastavenia",
"admin_settings.current_restart.value": "Reštartovať Ehterpad",
"admin_settings.current_restart.value": "Reštartovať Etherpad",
"admin_settings.current_save.value": "Uložiť nastavenia",
"admin_settings.page-title": "Nastavenia - Etherpad",
"index.newPad": "Nový poznámkový blok",
@ -154,7 +155,7 @@
"timeslider.month.october": "októbra",
"timeslider.month.november": "novembra",
"timeslider.month.december": "decembra",
"timeslider.unnamedauthors": "{[plural(num) one:Počet nemenovaných autorov:, other: Počet nemenovaných autorov:]} {{num}}",
"timeslider.unnamedauthors": "{{num}} {[plural(num) one: nemenovaný autor, few: nemenovaní autori, other: nemenovaných autorov ]}",
"pad.savedrevs.marked": "Táto revízia bola označená ako uložená",
"pad.savedrevs.timeslider": "Návštevou časovej osi môžete zobraziť uložené revízie",
"pad.userlist.entername": "Zadajte svoje meno",

View File

@ -4,10 +4,29 @@
"Saraiki"
]
},
"admin_plugins": "پلگ ان منیجر",
"admin_plugins.available": "دستیاب پلگ ان",
"admin_plugins.available_not-found": "کوئی پلگ ان کائنی لبھے۔",
"admin_plugins.available_install.value": "انسٹال",
"admin_plugins.description": "تفصیل",
"admin_plugins.installed_uninstall.value": "ان انسٹال",
"admin_plugins.last-update": "چھیکڑی تبدیلی",
"admin_plugins.name": "ناں",
"admin_plugins.version": "ورژن",
"admin_plugins_info.parts": "انسٹال تھئے حصے",
"admin_plugins_info.plugins": "انسٹال تھئے پلگ ان",
"admin_plugins_info.version_number": "ورشن نمبر",
"admin_settings": "ترتیباں",
"admin_settings.current_save.value": "ترتیباں محفوظ کرو",
"admin_settings.page-title": "ترتیباں ــ ایتھرپیڈ",
"index.newPad": "نواں پیڈ",
"pad.toolbar.bold.title": "بولڈ(Ctrl+B)",
"pad.toolbar.italic.title": "ترچھے (Ctrl+I)",
"pad.toolbar.underline.title": "ہیٹھ لکیر (Ctrl+U)",
"pad.toolbar.indent.title": "حاشیہ (ٹیب)",
"pad.toolbar.unindent.title": "حاشیہ ٻاہر دوں (شفٹ + ٹیٻ)",
"pad.toolbar.undo.title": "اݨ کیتا (کنٹرول + زیڈ)",
"pad.toolbar.redo.title": "ولدا کرو (کنٹرول + وائی)",
"pad.toolbar.savedRevision.title": "رویژن بچاؤ",
"pad.toolbar.settings.title": "ترتیباں",
"pad.colorpicker.save": "بچاؤ",
@ -16,6 +35,8 @@
"pad.settings.padSettings": "پیڈ ترتیباں",
"pad.settings.fontType": "فونٹ قسم:",
"pad.settings.language": "زبان:",
"pad.settings.about": "تعارف",
"pad.settings.poweredBy": "تکڑا کرݨ آلے",
"pad.importExport.importSuccessful": "کامیاب!",
"pad.importExport.exportetherpad": "ایتھرپیڈ",
"pad.importExport.exporthtml": "ایچ ٹی ایم ایل",

View File

@ -9,130 +9,165 @@
"Upwinxp"
]
},
"admin.page-title": "Administratorska nadzorna plošča Etherpad",
"admin_plugins": "Upravitelj vtičnikov",
"admin_plugins.available": "Razpoložljivi vtičniki",
"admin_plugins.available_not-found": "Ni najdenih vtičnikov.",
"admin_plugins.available_fetching": "Pridobivanje ...",
"admin_plugins.available_install.value": "Namesti",
"admin_plugins.available_search.placeholder": "Poiščite vtičnike za namestitev",
"admin_plugins.description": "Opis",
"admin_plugins.installed": "Nameščeni vtičniki",
"admin_plugins.installed_fetching": "Pridobivanje nameščenih vtičnikov ...",
"admin_plugins.installed_nothing": "Namestili niste še nobenega vtičnika.",
"admin_plugins.installed_uninstall.value": "Odmesti",
"admin_plugins.last-update": "Zadnja posodobitev",
"admin_plugins.name": "Ime",
"admin_plugins.page-title": "Upravitelj vtičnikov Etherpad",
"admin_plugins.version": "Različica",
"admin_plugins_info": "Informacije o odpravljanju težav",
"admin_plugins_info.hooks": "Nameščene razširitvene točke",
"admin_plugins_info.hooks_client": "Razširitvene točke na strani odjemalca",
"admin_plugins_info.hooks_server": "Razširitvene točke na strani strežnika",
"admin_plugins_info.parts": "Nameščeni deli",
"admin_plugins_info.plugins": "Nameščeni vtičniki",
"admin_plugins_info.page-title": "Informacije o vtičniku Etherpad",
"admin_plugins_info.version": "Različica Etherpada",
"admin_plugins_info.version_latest": "Najnovejša razpoložljiva različica",
"admin_plugins_info.version_number": "Številka različice",
"admin_settings": "Nastavitve",
"admin_settings.current": "Trenutna konfiguracija",
"admin_settings.current_example-devel": "Zgled predloge za razvojne nastavitve",
"admin_settings.current_example-prod": "Zgled predloge za roizvodne nastavitve",
"admin_settings.current_restart.value": "Znova zaženi Etherpad",
"admin_settings.current_save.value": "Shrani nastavitve",
"index.newPad": "Nov dokument",
"index.createOpenPad": "ali pa ustvari/odpri dokument z imenom:",
"pad.toolbar.bold.title": "Krepko (Ctrl-B)",
"pad.toolbar.italic.title": "Ležeče (Ctrl-I)",
"pad.toolbar.underline.title": "Podčrtano (Ctrl-U)",
"pad.toolbar.strikethrough.title": "Prečrtano (Ctrl+5)",
"pad.toolbar.ol.title": "Urejen seznam (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Neurejen seznam (Ctrl+Shift+L)",
"admin_settings.page-title": "Nastavitve Etherpad",
"index.newPad": "Nov blokec",
"index.createOpenPad": "ali pa ustvari/odpri blokec z imenom:",
"index.openPad": "odpri obstoječ blokec z imenom:",
"pad.toolbar.bold.title": "Krepko (Ctrl + B)",
"pad.toolbar.italic.title": "Ležeče (Ctrl + I)",
"pad.toolbar.underline.title": "Podčrtano (Ctrl + U)",
"pad.toolbar.strikethrough.title": "Prečrtano (Ctrl + 5)",
"pad.toolbar.ol.title": "Urejen seznam (Ctrl + dvigalka + N)",
"pad.toolbar.ul.title": "Neurejen seznam (Ctrl + dvigalka + L)",
"pad.toolbar.indent.title": "Zamik desno (TAB)",
"pad.toolbar.unindent.title": "Zamik levo (Shift+TAB)",
"pad.toolbar.undo.title": "Razveljavi (Ctrl-Z)",
"pad.toolbar.redo.title": "Ponovno uveljavi (Ctrl-Y)",
"pad.toolbar.clearAuthorship.title": "Počisti barve avtorstva (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Uvozi/Izvozi različne oblike zapisov",
"pad.toolbar.unindent.title": "Zmanjšanje zamika (Shift+TAB)",
"pad.toolbar.undo.title": "Razveljavi (Ctrl + Z)",
"pad.toolbar.redo.title": "Znova uveljavi (Ctrl + Y)",
"pad.toolbar.clearAuthorship.title": "Počisti barve avtorstva (Ctrl + dvigalka + C)",
"pad.toolbar.import_export.title": "Uvozi/Izvozi iz/v različne datotečne formate",
"pad.toolbar.timeslider.title": "Časovni trak",
"pad.toolbar.savedRevision.title": "Shrani redakcijo",
"pad.toolbar.settings.title": "Nastavitve",
"pad.toolbar.embed.title": "Deli in vključi ta dokument",
"pad.toolbar.showusers.title": "Pokaži uporabnike dokumenta",
"pad.toolbar.embed.title": "Deli in vključi ta blokec",
"pad.toolbar.showusers.title": "Pokaži uporabnike blokca",
"pad.colorpicker.save": "Shrani",
"pad.colorpicker.cancel": "Prekliči",
"pad.loading": "Nalaganje ...",
"pad.noCookie": "Piškotka ni bilo mogoče najti. Prosimo, dovolite piškotke v vašem brskalniku!",
"pad.permissionDenied": "Nimate dovoljenja za dostop do tega dokumenta.",
"pad.settings.padSettings": "Nastavitve dokumenta",
"pad.noCookie": "Piškotka ni bilo mogoče najti. Prosimo, dovolite piškotke v vašem brskalniku! Vaša seja in nastavitve se med obiski ne bodo shranili. Razlog za to je morda, da je Etherpad v nekaterih brskalnikih vključen v iFrame. Zsgotovite, da je Etherpad na isti poddomeni/domeni kot nadrejeni iFrame.",
"pad.permissionDenied": "Nimate dovoljenja za dostop do tega bkokca.",
"pad.settings.padSettings": "Nastavitve blokca.",
"pad.settings.myView": "Moj prikaz",
"pad.settings.stickychat": "Vsebina klepeta je vedno na zaslonu",
"pad.settings.chatandusers": "Prikaži klepet in uporabnike",
"pad.settings.colorcheck": "Barve avtorstva",
"pad.settings.linenocheck": "Številke vrstic",
"pad.settings.rtlcheck": "Ali naj se vsebina prebira od desne proti levi?",
"pad.settings.rtlcheck": "Ali naj se vsebina bera od desne proti levi?",
"pad.settings.fontType": "Vrsta pisave:",
"pad.settings.fontType.normal": "Normalno",
"pad.settings.language": "Jezik:",
"pad.settings.about": "Kolofon",
"pad.settings.poweredBy": "Omogoča",
"pad.importExport.import_export": "Uvoz/Izvoz",
"pad.importExport.import": "Naloži katerokoli besedilno datoteko ali dokument.",
"pad.importExport.importSuccessful": "Opravilo je uspešno končano!",
"pad.importExport.export": "Izvozi trenutni dokument kot:",
"pad.importExport.import": "Naložite katero koli besedilno datoteko ali dokument.",
"pad.importExport.importSuccessful": "Uspešno!",
"pad.importExport.export": "Izvozi trenutni blokec kot:",
"pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML (oblikovano besedilo)",
"pad.importExport.exportplain": "TXT (neoblikovano besedilo)",
"pad.importExport.exportword": "DOC (zapis Microsoft Word)",
"pad.importExport.exportpdf": "PDF (zapis Acrobat PDF)",
"pad.importExport.exportopen": "ODF (zapis Open Document)",
"pad.importExport.abiword.innerHTML": "Uvoziti je mogoče le neoblikovano besedilo in zapise HTML. Za naprednejše možnosti uvoza namestite program <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">AbiWord</a>.",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Golo besedilo",
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF",
"pad.importExport.abiword.innerHTML": "Uvoziti je mogoče le golo besedilo in formate HTML. Za naprednejše možnosti uvoza namestite program <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">AbiWord</a>.",
"pad.modals.connected": "Povezano.",
"pad.modals.reconnecting": "Poteka povezovanje z dokumentom ...",
"pad.modals.reconnecting": "Poteka povezovanje z blokcem ...",
"pad.modals.forcereconnect": "Vsili ponovno povezavo",
"pad.modals.reconnecttimer": "Poskus ponovne vzpostavitve povezave čez",
"pad.modals.cancel": "Prekliči",
"pad.modals.userdup": "Dokument je že odprt v v drugem oknu",
"pad.modals.userdup.explanation": "Videti je, da je ta dokument odprt v več kot enem oknu brskalnika na tem računalniku.",
"pad.modals.userdup.advice": "Ponovno vzpostavite povezavo in uporabljajte to okno.",
"pad.modals.userdup": "Blokec je že odprt v drugem oknu",
"pad.modals.userdup.explanation": "Videti je, da je ta blokec na tem računalniku odprt v več kot enem oknu brskalnika.",
"pad.modals.userdup.advice": "Znova vzpostavite povezavo in uporabljajte to okno.",
"pad.modals.unauth": "Nepooblaščen dostop",
"pad.modals.unauth.explanation": "Med ogledovanjem strani so se dovoljenja za ogled spremenila. Poskusite se znova povezati.",
"pad.modals.looping.explanation": "Zaznane so težave pri komunikaciji s strežnikom za usklajevanje.",
"pad.modals.looping.cause": "Morda ste se povezali skozi neustrezno nastavljen požarni zid ali s posredniškim strežnikom.",
"pad.modals.unauth.explanation": "Med ogledovanjem strani so se vaša dovoljenja za ogled spremenila. Poskusite se znova povezati.",
"pad.modals.looping.explanation": "Pri komunikaciji s sinhronizacijskim strežnikom je prišlo do težav.",
"pad.modals.looping.cause": "Morda ste se povezali skozi neustrezno nastavljen požarni zid ali prek posredniškega strežnika.",
"pad.modals.initsocketfail": "Strežnik je nedosegljiv.",
"pad.modals.initsocketfail.explanation": "Povezava s strežnikom za usklajevanje ni mogoča.",
"pad.modals.initsocketfail.cause": "Najverjetneje gre za težavo z vašim brskalnikom, ali internetno povezavo.",
"pad.modals.initsocketfail.explanation": "Povezovanje s sinhronizacijskim strežnikom ni uspelo.",
"pad.modals.initsocketfail.cause": "Najverjetneje gre za težavo z vašim brskalnikom ali internetno povezavo.",
"pad.modals.slowcommit.explanation": "Strežnik se ne odziva.",
"pad.modals.slowcommit.cause": "Možen vzrok so težave z omrežno povezljivostjo.",
"pad.modals.badChangeset.explanation": "Urejanje, ki ste ga naredili, je strežnik za usklajevanje označil kot nedovoljeno.",
"pad.modals.badChangeset.cause": "Razlog za to je morda napačna konfiguracija strežnika ali neko drugo nepričakovano vedenje. Prosimo, stopite v stik z skrbnikom storitve, če menite, da gre za napako. Poskusite se ponovno povezati, da nadaljujete z urejanjem.",
"pad.modals.corruptPad.explanation": "Dokument, do katerega želite dostopati, je poškodovan.",
"pad.modals.corruptPad.cause": "Razlog za to je morda napačna konfiguracija strežnika ali neko drugo nepričakovano vedenje. Prosimo, stopite v stik s skrbnikom storitve.",
"pad.modals.badChangeset.explanation": "Urejanje, ki ste ga naredili, je sinhronizacijski strežnik prepoznal kot nedovoljeno.",
"pad.modals.badChangeset.cause": "Razlog za to je morda napačna konfiguracija strežnika ali neko drugo nepričakovano vedenje. Če menite, da gre za napako, stopite v stik z administratorjem storitve. Za nadaljevanje urejanja se poskusite znova povezati.",
"pad.modals.corruptPad.explanation": "Blokec, do katerega želite dostopati, je poškodovan.",
"pad.modals.corruptPad.cause": "Razlog za to je morda napačna konfiguracija strežnika ali neko drugo nepričakovano vedenje. Prosimo, stopite v stik z administratorjem storitve.",
"pad.modals.deleted": "Izbrisano.",
"pad.modals.deleted.explanation": "Dokument je odstranjen.",
"pad.modals.deleted.explanation": "Blokec je odstranjen.",
"pad.modals.rateLimited": "Omejena hitrost.",
"pad.modals.rateLimited.explanation": "Na ta blokec ste poslali preveč sporočil, zato ste bili odklopljeni.",
"pad.modals.rejected.explanation": "Strežnik je zavrnil sporočilo, ki ga je poslal vaš brskalnik.",
"pad.modals.rejected.cause": "Strežnik je bil morda posodobljen, ko ste si ogledovali blokec, ali pa je v Etherpadu napaka. Poskusite znova naložiti stran.",
"pad.modals.disconnected": "Vaša povezava je bila prekinjena.",
"pad.modals.disconnected.explanation": "Povezava s strežnikom je bila izgubljena.",
"pad.modals.disconnected.cause": "Strežnik morda ni na voljo. Prosimo, obvestite skrbnika storitve, če se to zgodi večkrat.",
"pad.share": "Določi souporabo dokumenta",
"pad.modals.disconnected.cause": "Strežnik morda ni na voljo. Če se to ponavlja, obvestite administratorja storitve.",
"pad.share": "Deljenje blokca",
"pad.share.readonly": "Samo za branje",
"pad.share.link": "Povezava",
"pad.share.emebdcode": "URL za vključitev",
"pad.chat": "Klepet",
"pad.chat.title": "Odpri klepetalno okno dokumenta.",
"pad.chat.title": "Odpri klepetalno okno za blokec.",
"pad.chat.loadmessages": "Naloži več sporočil",
"pad.chat.stick.title": "Prilepi klepet na zaslon",
"pad.chat.writeMessage.placeholder": "Napišite sporočilo",
"timeslider.followContents": "Spremljajte posodobitve vsebine blokca",
"timeslider.pageTitle": "Časovni trak {{appTitle}}",
"timeslider.toolbar.returnbutton": "Vrni se na dokument",
"timeslider.toolbar.returnbutton": "Nazaj na blokec",
"timeslider.toolbar.authors": "Avtorji:",
"timeslider.toolbar.authorsList": "Ni določenih avtorjev",
"timeslider.toolbar.exportlink.title": "Izvozi",
"timeslider.exportCurrent": "Izvozi trenutno različico kot:",
"timeslider.version": "Različica {{version}}",
"timeslider.saved": "Shranjeno {{day}}.{{month}}.{{year}}",
"timeslider.playPause": "Predvajaj/začasno ustavi vsebino dokumenta",
"timeslider.backRevision": "Pojdi eno redakcijo nazaj v tem dokumentu",
"timeslider.forwardRevision": "Pojdi eno redakcijo naprej v tem dokumentu",
"timeslider.playPause": "Predvajaj/zaustavi vsebino blokca",
"timeslider.backRevision": "Pojdi v tem blokcu eno redakcijo nazaj",
"timeslider.forwardRevision": "Pojdi v tem blokcu eno redakcijo naprej",
"timeslider.dateformat": "{{day}}.{{month}}.{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Januar",
"timeslider.month.february": "Februar",
"timeslider.month.march": "Marec",
"timeslider.month.april": "April",
"timeslider.month.may": "Maj",
"timeslider.month.june": "Junij",
"timeslider.month.july": "Julij",
"timeslider.month.august": "August",
"timeslider.month.september": "September",
"timeslider.month.october": "Oktober",
"timeslider.month.november": "November",
"timeslider.month.december": "December",
"timeslider.month.january": "januarja",
"timeslider.month.february": "februarja",
"timeslider.month.march": "marca",
"timeslider.month.april": "aprila",
"timeslider.month.may": "maja",
"timeslider.month.june": "junija",
"timeslider.month.july": "julija",
"timeslider.month.august": "avgusta",
"timeslider.month.september": "septembra",
"timeslider.month.october": "oktobra",
"timeslider.month.november": "novembra",
"timeslider.month.december": "decembra",
"timeslider.unnamedauthors": "{{num}} {[plural(num) one: neimenovan avtor, plural(num) two: neimenovana avtorja, plural(num) few: neimenovani avtorji, other: neimenovanih avtorjev ]}",
"pad.savedrevs.marked": "Ta redakcija je zdaj označena kot shranjena redakcija",
"pad.savedrevs.timeslider": "Shranjene redakcije si lahko ogledate s pomočjo časovnega traku",
"pad.savedrevs.timeslider": "Shranjene redakcije si lahko ogledate z odprtjem časovnega traku",
"pad.userlist.entername": "Vnesite svoje ime",
"pad.userlist.unnamed": "neimenovana oseba",
"pad.editbar.clearcolors": "Ali naj se počistijo barve avtorstva v celotnem dokumentu?",
"pad.editbar.clearcolors": "Ali naj se počistijo barve avtorstva v vsem dokumentu? Tega ni mogoče razveljaviti.",
"pad.impexp.importbutton": "Uvozi takoj",
"pad.impexp.importing": "Poteka uvažanje ...",
"pad.impexp.confirmimport": "Uvoz datoteke prepiše obstoječe besedilo dokumenta. Ali ste prepričani, da želite nadaljevati?",
"pad.impexp.convertFailed": "Datoteke ni bilo mogoče uvoziti. Prosimo uporabite drug podprt zapis dokumenta ali pa vsebino prilepite ročno",
"pad.impexp.padHasData": "Nismo mogli uvoziti datoteke, ker dokument že vsebuje spremembe. Prosimo, uvozite datoteko v nov dokument",
"pad.impexp.confirmimport": "Uvoz datoteke bo prepisal obstoječe besedilo blokca. Ali res želite nadaljevati?",
"pad.impexp.convertFailed": "Datoteke ni bilo mogoče uvoziti. Prosimo, uporabite drug format dokumenta ali pa vsebino kopirajte in prilepite ročno.",
"pad.impexp.padHasData": "Datoteke ni bilo mogoče uvoziti, ker blokec že vsebuje spremembe. Prosimo, uvozite datoteko v nov blokec.",
"pad.impexp.uploadFailed": "Nalaganje je spodletelo, prosimo poskusite znova",
"pad.impexp.importfailed": "Uvoz je spodletel",
"pad.impexp.copypaste": "Vsebino kopirajte in prilepite",
"pad.impexp.exportdisabled": "Izvoz v zapis {{type}} je onemogočen. Za več podrobnosti stopite v stik s skrbnikom."
"pad.impexp.exportdisabled": "Izvoz v format {{type}} je onemogočen. Za več podrobnosti stopite v stik z administratorjem.",
"pad.impexp.maxFileSize": "Datoteka je prevelika. Za povečanje dovoljene velikosti datoteke za uvoz se obrnite na administratorja spletnega mesta"
}

60
src/locales/sms.json Normal file
View File

@ -0,0 +1,60 @@
{
"@metadata": {
"authors": [
"Yupik"
]
},
"admin_plugins.description": "Deskriptt",
"admin_plugins.name": "Nõmm",
"admin_plugins.version": "Versio",
"admin_plugins_info.version": "Etherpad-versio",
"admin_plugins_info.version_number": "Versionââmar",
"admin_settings": "Asetõõzz",
"admin_settings.current_save.value": "Ruõkk asetõõzzid",
"admin_settings.page-title": "Asetõõzz - Etherpad",
"index.newPad": "Ođđ mošttʼtõspõʹmmai",
"index.createOpenPad": "leʼbe raaj leʼbe ääʹved mošttʼtõspõʹmmai nõõmin:",
"pad.toolbar.underline.title": "Vuâllacertldâsttmõš (CTRL-U)",
"pad.toolbar.undo.title": "Kååʹmet (Ctrl+Z)",
"pad.toolbar.savedRevision.title": "Ruõkk muttâz",
"pad.toolbar.settings.title": "Asetõõzz",
"pad.toolbar.showusers.title": "Čuäʼjet tän mošttʼtõspõʹmmai õõʹnnʼjid",
"pad.colorpicker.save": "Ruõkk",
"pad.colorpicker.cancel": "Jõõsk",
"pad.settings.padSettings": "Mošttʼtõspõʹmmai asetõõzz",
"pad.settings.chatandusers": "Čuäʹjet čääʹtt da õõʹnnʼjid",
"pad.settings.language": "Ǩiõll:",
"pad.settings.about": "Lââʹssteâđ",
"pad.settings.poweredBy": "Kääzzkõõzz vueiʹtlvâstt",
"pad.importExport.importSuccessful": "Oʹnnsti!",
"pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.modals.cancel": "Jõõsk",
"pad.modals.slowcommit.explanation": "Server ij vaʹstted.",
"pad.modals.deleted": "Jaukkuum.",
"pad.modals.deleted.explanation": "Tät mošttʼtõspõʹmmai lij jaukkuum.",
"pad.share": "Jueʼjj mošttʼtõspõʹmmai",
"pad.share.link": "Liŋkk",
"pad.chat": "Čäʹtt",
"pad.chat.writeMessage.placeholder": "Ǩeeʹrjet jiijjad saaǥǥ täzz",
"timeslider.toolbar.returnbutton": "Määʹcc mošttʼtõspõʹmma",
"timeslider.version": "Versio {{version}}",
"timeslider.saved": "Ruõkkum {{month}} {{day}}. peeiʹv {{year}}",
"timeslider.dateformat": "{{day}}.{{month}}.{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "ođđeeʹjjmannu",
"timeslider.month.february": "täʹlvvmannu",
"timeslider.month.march": "pâʹsslašttâm-mannu",
"timeslider.month.april": "njuhččmannu",
"timeslider.month.may": "vueʹssmannu",
"timeslider.month.june": "ǩieʹssmannu",
"timeslider.month.july": "sueiʹnnmannu",
"timeslider.month.august": "påʹrǧǧmannu",
"timeslider.month.september": "čõhččmannu",
"timeslider.month.october": "kålggmannu",
"timeslider.month.november": "skamm-mannu",
"timeslider.month.december": "rosttovmannu",
"pad.userlist.entername": "Ǩeeʹrjet jiijjad nõõm"
}

View File

@ -7,7 +7,7 @@
"Liridon"
]
},
"admin.page-title": "Paneli i Administratorit - Etherpad",
"admin.page-title": "Pult Përgjegjësi - Etherpad",
"admin_plugins": "Përgjegjës shtojcash",
"admin_plugins.available": "Shtojca të gatshme",
"admin_plugins.available_not-found": "Su gjetën shtojca.",
@ -63,7 +63,7 @@
"pad.colorpicker.save": "Ruaje",
"pad.colorpicker.cancel": "Anuloje",
"pad.loading": "Po ngarkohet…",
"pad.noCookie": "Su gjet dot cookie. Ju lutemi, lejoni cookie-t te shfletuesi juaj! Sesioni dhe rregullimet tuaja sdo të ruhen nga një sesion në tjetër. Kjo mund të vijë ngaqë Etherpad përfshihet brenda një iFrame në disa shfletues. Ju lutemi, sigurohuni që Etherpad-i të jetë në të njëjtën nënpërkatësi/përkatësi si iFrame-i mëmë.",
"pad.noCookie": "Su gjet dot cookie. Ju lutemi, lejoni cookie-t te shfletuesi juaj! Sesioni dhe rregullimet tuaja sdo të ruhen nga një sesion në tjetër. Kjo mund të vijë ngaqë, në disa shfletues, Etherpad përfshihet brenda një iFrame. Ju lutemi, sigurohuni që Etherpad-i të jetë në të njëjtën nënpërkatësi/përkatësi si iFrame-i mëmë.",
"pad.permissionDenied": "Skeni leje të hyni në këtë bllok",
"pad.settings.padSettings": "Rregullime Blloku",
"pad.settings.myView": "Pamja Ime",
@ -78,7 +78,7 @@
"pad.settings.about": "Mbi",
"pad.settings.poweredBy": "Bazuar në",
"pad.importExport.import_export": "Import/Eksport",
"pad.importExport.import": "Ngarkoni cilëndo kartelë teksti ose dokument",
"pad.importExport.import": "Ngarkoni cilëndo kartelë tekst ose dokument",
"pad.importExport.importSuccessful": "Me sukses!",
"pad.importExport.export": "Eksportojeni bllokun e tanishëm si:",
"pad.importExport.exportetherpad": "Etherpad",

View File

@ -9,6 +9,7 @@
"Obsuser",
"Srdjan m",
"Srđan",
"Zenfiric",
"Милан Јелисавчић"
]
},
@ -34,7 +35,6 @@
"pad.colorpicker.save": "Сачувај",
"pad.colorpicker.cancel": "Откажи",
"pad.loading": "Учитавам…",
"pad.noCookie": "Колачић није пронађен. Молимо да укључите колачиће у вашем прегледавачу!",
"pad.permissionDenied": "Немате дозволу да приступите овом паду",
"pad.settings.padSettings": "Подешавања пада",
"pad.settings.myView": "Мој приказ",

162
src/locales/sro.json Normal file
View File

@ -0,0 +1,162 @@
{
"@metadata": {
"authors": [
"Adr mm",
"F Samaritani"
]
},
"admin.page-title": "Pannellu amministrativu - Etherpad",
"admin_plugins": "Gestore de connetores",
"admin_plugins.available": "Connetores a disponimentu",
"admin_plugins.available_not-found": "Nissunu connetore a disponimentu",
"admin_plugins.available_fetching": "Recuperende...",
"admin_plugins.available_install.value": "Installa",
"admin_plugins.available_search.placeholder": "Chirca connetores de installare",
"admin_plugins.description": "Descritzione",
"admin_plugins.installed": "Connetores installados",
"admin_plugins.installed_fetching": "Recuperende connetores installados...",
"admin_plugins.installed_nothing": "No as installadu ancora nissunu connetore.",
"admin_plugins.installed_uninstall.value": "Disinstalla",
"admin_plugins.last-update": "Ùrtima atualizatzione",
"admin_plugins.name": "Nòmine",
"admin_plugins.page-title": "Gestore de connetores - Etherpad",
"admin_plugins.version": "Versione",
"admin_plugins_info": "Informatzione pro sa risolutzione de problemas",
"admin_plugins_info.parts": "Partes installadas",
"admin_plugins_info.plugins": "Connetores installados",
"admin_plugins_info.page-title": "Informatzione de su connetore - Etherpad",
"admin_plugins_info.version": "Versione de Etherpad",
"admin_plugins_info.version_latest": "Ùrtima versione a disponimentu",
"admin_plugins_info.version_number": "Nùmeru de versione",
"admin_settings": "Cunfiguratzione",
"admin_settings.current": "Cunfiguratzione atuale",
"admin_settings.current_restart.value": "Torra a aviare Etherpad",
"admin_settings.current_save.value": "Sarva sa cunfiguratzione",
"admin_settings.page-title": "Cunfiguratzione - Etherpad",
"index.newPad": "Pad nou",
"index.createOpenPad": "o crea/aberi unu pad cun su nòmine:",
"index.openPad": "aberi unu pad esistente cun su nòmine:",
"pad.toolbar.bold.title": "Grassetu (Ctrl+B)",
"pad.toolbar.italic.title": "Cursivu (Ctrl+I)",
"pad.toolbar.underline.title": "Sutaliniadu (Ctrl+U)",
"pad.toolbar.strikethrough.title": "Istangadu (Ctrl+5)",
"pad.toolbar.ol.title": "Lista numerada (Ctrl+Shift+N)",
"pad.toolbar.ul.title": "Lista cun puntos (Ctrl+Shift+L)",
"pad.toolbar.indent.title": "Indentatzione a dereta (Tab)",
"pad.toolbar.unindent.title": "Indentatzione a manca (Shift+Tab)",
"pad.toolbar.undo.title": "Iscontza (Ctrl+Z)",
"pad.toolbar.redo.title": "Torra a fàghere (Ctrl+Y)",
"pad.toolbar.clearAuthorship.title": "Lìmpia is colores de autoria (Ctrl+Shift+C)",
"pad.toolbar.import_export.title": "Importa/esporta dae/a formados de archìviu diferentes",
"pad.toolbar.timeslider.title": "Presentatzione cronologia",
"pad.toolbar.savedRevision.title": "Sarva sa versione",
"pad.toolbar.settings.title": "Cunfiguratzione",
"pad.toolbar.embed.title": "Cumpartzi e incòrpora custu Pad",
"pad.toolbar.showusers.title": "Ammustra is utentes in custu Pad",
"pad.colorpicker.save": "Sarva",
"pad.colorpicker.cancel": "Annulla",
"pad.loading": "Carrighende...",
"pad.noCookie": "Su testimòngiu no est istètiu agatadu. Permite is testimòngios in su navigadore tuo. Sa sessione e sa cunfiguratzione tuas no ant a èssere sarvadas intre bìsitas. Podet èssere pro more de s'inclusione de Etherpad comente iFrame in tzertos navigadores. Assegura·ti chi Etherpad s'agatat in su pròpiu sutadomìniu/domìniu chi s'iFrame printzipale",
"pad.permissionDenied": "Non tenes permissu pro atzèdere a custu pad",
"pad.settings.padSettings": "Cunfiguratzione de su pad",
"pad.settings.myView": "Sa visualizatzione mia",
"pad.settings.stickychat": "Ammustra semper sa tzarrada",
"pad.settings.chatandusers": "Ammustra sa tzarrada e is utentes",
"pad.settings.colorcheck": "Colores de autoria",
"pad.settings.linenocheck": "Nùmeros de lìnia",
"pad.settings.rtlcheck": "Cuntenutu dae manca a dereta",
"pad.settings.fontType": "Tipu de caràtere:",
"pad.settings.fontType.normal": "Normale",
"pad.settings.language": "Lìngua:",
"pad.settings.about": "Informatziones",
"pad.settings.poweredBy": "Realizadu cun",
"pad.importExport.import_export": "Importatzione/esportatzione",
"pad.importExport.import": "Càrriga un'archìviu de testu o unu documentu",
"pad.importExport.importSuccessful": "Carrigadu.",
"pad.importExport.export": "Esporta su pad atuale comente:",
"pad.importExport.exportetherpad": "Etherpad",
"pad.importExport.exporthtml": "HTML",
"pad.importExport.exportplain": "Testu sèmplitze",
"pad.importExport.exportword": "Microsoft Word",
"pad.importExport.exportpdf": "PDF",
"pad.importExport.exportopen": "ODF (Open Document Format)",
"pad.importExport.abiword.innerHTML": "Isceti is formados de testu sèmplitze o HTML podent èssere importados. Pro mètodos avantzados de importatzione, <a href=\"https://github.com/ether/etherpad-lite/wiki/How-to-enable-importing-and-exporting-different-file-formats-with-AbiWord\">installa AbiWord o LibreOffice</a>.",
"pad.modals.connected": "Connètidu.",
"pad.modals.reconnecting": "Connetende a su pad tuo...",
"pad.modals.forcereconnect": "Fortza sa connesione",
"pad.modals.reconnecttimer": "Torrende a connètere in",
"pad.modals.cancel": "Annulla",
"pad.modals.userdup": "Abertu in un'àtera ventana",
"pad.modals.userdup.explanation": "Podet èssere chi custu pad siat abertu in un'àtera ischeda de custu navigadore in custu ordinadore.",
"pad.modals.userdup.advice": "Torra a connètere pro impreare custa ventana.",
"pad.modals.unauth": "Chena autorizatzione",
"pad.modals.unauth.explanation": "Is permissos tuos funt istètios cambiados in su mentras chi fias bidende custa pàgina. Prova de ti torrare a connètere.",
"pad.modals.looping.explanation": "Nci funt problemas de comunicatzione cun su serbidore de sincronizatzione.",
"pad.modals.looping.cause": "Forsis sa connessione at impreadu unu serbidore intermediàriu (proxy) o unu firewall chi no est cumpatìbile.",
"pad.modals.initsocketfail": "Su serbidore no est atzessìbile.",
"pad.modals.initsocketfail.explanation": "Impossìbile connètere cun su serbidore de sincronizatzione.",
"pad.modals.initsocketfail.cause": "Podet èssere a càusa de unu problema cun su navigadore tuo o cun sa connessione de internet.",
"pad.modals.slowcommit.explanation": "Su serbidore non rispondet.",
"pad.modals.slowcommit.cause": "Podet èssere a càusa de problemas cun sa connessione de internet.",
"pad.modals.badChangeset.explanation": "Una modìfica tua est istètia cunsiderada illegale dae su serbidore de sincronizatzione.",
"pad.modals.badChangeset.cause": "Podet èssere a càusa de una cunfiguratzione de serbidore isballiada o calicunu àteru cumportamentu imprevistu. Iscrie a s'amministratzione de su servìtziu si pensas chi siat un'errore. Prova a connètere torra pro sighire a modificare.",
"pad.modals.corruptPad.explanation": "Su pad a su chi ses chirchende de atzèdere est dannadu.",
"pad.modals.corruptPad.cause": "Podet èssere a càusa de una cunfiguratzione de serbidore non curreta o pro unu cumportamentu imprevistu. Iscrie a s'amministratzione de su servìtziu.",
"pad.modals.deleted": "Cantzelladu.",
"pad.modals.deleted.explanation": "Pad cantzelladu.",
"pad.modals.rateLimited.explanation": "As imbiadu tropu messàgios a custu pad e t'at disconnètidu.",
"pad.modals.rejected.explanation": "Su serbidore at rifiutadu unu messàgiu imbiadu dae su navigadore tuo.",
"pad.modals.rejected.cause": "Podet èssere chi su serbidore siat istètiu atualizadu in su mentras chi fias bidende su pad, o podet èssere chi nci siat un'errore in Etherpad. Prova a atualizare sa pàgina.",
"pad.modals.disconnected": "Disconnètidu.",
"pad.modals.disconnected.explanation": "Connessione cun su serbidore pèrdida.",
"pad.modals.disconnected.cause": "Su serbidore no est a disponimentu. Iscrie a s'amministratzione de su servìtziu si su problema persistet.",
"pad.share": "Cumpartzi custu pad",
"pad.share.link": "Ligòngiu",
"pad.share.emebdcode": "Incòrpora URL",
"pad.chat": "Tzarrada",
"pad.chat.title": "Aberi sa tzarrada pro custu pad.",
"pad.chat.loadmessages": "Càrriga àteros messàgios",
"pad.chat.stick.title": "Apica sa tzarrada in s'ischermu",
"pad.chat.writeMessage.placeholder": "Iscrie su messàgiu tuo inoghe",
"timeslider.followContents": "Sighi is atualizatziones de cuntenutu de su pad",
"timeslider.pageTitle": "Cronologia {{appTitle}}",
"timeslider.toolbar.returnbutton": "Torra a su pad",
"timeslider.toolbar.authors": "Autores:",
"timeslider.toolbar.authorsList": "Nissunu autore",
"timeslider.toolbar.exportlink.title": "Esporta",
"timeslider.exportCurrent": "Esporta sa versione atuale comente:",
"timeslider.version": "Versione {{version}}",
"timeslider.saved": "Sarvadu su {{day}} de {{month}} de su {{year}}",
"timeslider.playPause": "Riprodutzione/pàusa de is cuntenutos de su pad",
"timeslider.backRevision": "Bae a una versione pretzedente de custu pad",
"timeslider.forwardRevision": "Bae a una versione imbeniente de custu pad",
"timeslider.dateformat": "{{day}}/{{month}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
"timeslider.month.january": "Ghennàrgiu",
"timeslider.month.february": "Freàrgiu",
"timeslider.month.march": "Martzu",
"timeslider.month.april": "Abrile",
"timeslider.month.may": "Maju",
"timeslider.month.june": "Làmpadas",
"timeslider.month.july": "Mese de argiolas",
"timeslider.month.august": "Austu",
"timeslider.month.september": "Cabudanni",
"timeslider.month.october": "Ledàmine",
"timeslider.month.november": "Onniasantu",
"timeslider.month.december": "Mese de idas",
"timeslider.unnamedauthors": "{{num}} {[plural(num) one: autore, other: autores ]} chena nòmine",
"pad.savedrevs.marked": "Custa revisione est istètia marcada comente revisione sarvada",
"pad.savedrevs.timeslider": "Podes bìdere is versiones sarvadas bisitende sa cronologia",
"pad.userlist.entername": "Inserta su nòmine tuo",
"pad.userlist.unnamed": "Chena nòmine",
"pad.editbar.clearcolors": "Seguru chi boles limpiare is colores de autoria de totu su documentu? Custa atzione no dda podes annullare",
"pad.impexp.importbutton": "Importa immoe",
"pad.impexp.importing": "Importende...",
"pad.impexp.confirmimport": "S'importatzione de un'archìviu at a subraiscrìere su testu atuale de su pad. Seguru chi boles sighire?",
"pad.impexp.convertFailed": "Impossìbile importare custu archìviu. Imprea unu formadu de documentu diferente o còpia e incolla a manu",
"pad.impexp.padHasData": "Impossìbile importare custu archìviu pro ite custu pad est istètiu giai modificadu. Importa·ddu in unu pad nou",
"pad.impexp.uploadFailed": "Errore in sa càrriga. Torra a provare",
"pad.impexp.importfailed": "Errore de importatzione",
"pad.impexp.copypaste": "Còpia e incolla",
"pad.impexp.exportdisabled": "S'esportatzione comente {{type}} est disativada. Iscrie a s'amministratzione de su sistema pro àteras informatziones.",
"pad.impexp.maxFileSize": "S'archìviu est tropu manu. Iscrie a s'amministratzione pro ismanniare sa dimensione permìtida pro s'importatzione"
}

View File

@ -3,7 +3,8 @@
"authors": [
"Aefgh39622",
"Andibecker",
"Patsagorn Y."
"Patsagorn Y.",
"Trisorn Triboon"
]
},
"admin.page-title": "แดชบอร์ดผู้ดูแลระบบ - Etherpad",
@ -16,12 +17,12 @@
"admin_plugins.description": "คำอธิบาย",
"admin_plugins.installed": "ปลั๊กอินที่ติดตั้ง",
"admin_plugins.installed_fetching": "กำลังเรียกปลั๊กอินที่ติดตั้ง…",
"admin_plugins.installed_nothing": "คุณยังไม่ได้ติดตั้งปลั๊กอินใดๆ",
"admin_plugins.installed_nothing": "คุณยังไม่ได้ติดตั้งปลั๊กอินใด ๆ",
"admin_plugins.installed_uninstall.value": "ถอนการติดตั้ง",
"admin_plugins.last-update": "การปรับปรุงครั้งล่าสุด",
"admin_plugins.name": "ชื่อ",
"admin_plugins.page-title": "ตัวจัดการปลั๊กอิน - Etherpad",
"admin_plugins.version": "เวอร์ชัน",
"admin_plugins.version": "เวอร์ชัน",
"admin_plugins_info": "ข้อมูลการแก้ไขปัญหา",
"admin_plugins_info.hooks": "ติดตั้งตะขอ",
"admin_plugins_info.hooks_client": "ตะขอฝั่งไคลเอ็นต์",
@ -35,7 +36,7 @@
"admin_settings": "การตั้งค่า",
"admin_settings.current": "การกำหนดค่าปัจจุบัน",
"admin_settings.current_example-devel": "ตัวอย่างเทมเพลตการตั้งค่าการพัฒนา",
"admin_settings.current_example-prod": "ตัวอย่างเทมเพลตการตั้งค่าการผลิต",
"admin_settings.current_example-prod": "ตัวอย่างแม่แบบการตั้งค่าการผลิต",
"admin_settings.current_restart.value": "รีสตาร์ท Etherpad",
"admin_settings.current_save.value": "บันทึกการตั้งค่า",
"admin_settings.page-title": "การตั้งค่า - Etherpad",
@ -74,9 +75,9 @@
"pad.settings.fontType": "ชนิดแบบอักษร:",
"pad.settings.language": "ภาษา:",
"pad.settings.about": "เกี่ยวกับ",
"pad.settings.poweredBy": "ขับเคลื่อนโดย $1",
"pad.settings.poweredBy": "ขับเคลื่อนโดย",
"pad.importExport.import_export": "นำเข้า/ส่งออก",
"pad.importExport.import": "อัปโหลดไฟล์ข้อความหรือเอกสารใดๆ",
"pad.importExport.import": "อัปโหลดไฟล์ข้อความหรือเอกสารใด ๆ",
"pad.importExport.importSuccessful": "สำเร็จ!",
"pad.importExport.export": "ส่งออกแผ่นจดบันทึกปัจจุบันเป็น:",
"pad.importExport.exportetherpad": "Etherpad",
@ -124,7 +125,7 @@
"pad.chat.title": "เปิดการแชทสำหรับแผ่นจดบันทึกนี้",
"pad.chat.loadmessages": "โหลดข้อความเพิ่มเติม",
"pad.chat.stick.title": "ปักการสนทนาไว้บนหน้าจอ",
"pad.chat.writeMessage.placeholder": "เขียนข้อความ...",
"pad.chat.writeMessage.placeholder": "เขียนข้อความของคุณที่นี่",
"timeslider.followContents": "ติดตามการอัพเดตเนื้อหาแพด",
"timeslider.pageTitle": "ตัวเลื่อนเวลา {{appTitle}}",
"timeslider.toolbar.returnbutton": "กลับไปแผ่นจดบันทึก",
@ -132,7 +133,7 @@
"timeslider.toolbar.authorsList": "ไม่มีผู้เขียน",
"timeslider.toolbar.exportlink.title": "ส่งออก",
"timeslider.exportCurrent": "ส่งออกรุ่นปัจจุบันเป็น:",
"timeslider.version": "รุ่น {{version}}",
"timeslider.version": "เวอร์ชัน {{version}}",
"timeslider.saved": "บันทึกแล้วเมื่อ {{day}} {{month}} {{year}}",
"timeslider.playPause": "เล่น / พักเนื้อหาแผ่นจดบันทึก",
"timeslider.backRevision": "กลับไปรุ่นแก้ไขเก่าของแผ่นจดบันทึกนี้",
@ -153,7 +154,7 @@
"timeslider.unnamedauthors": "{{num}} ผู้เขียนที่ไม่มีชื่อ",
"pad.savedrevs.marked": "รุ่นแก้ไขนี้ถูกทำเครื่องหมายเป็นรุ่นแก้ไขที่บันทึกแล้ว",
"pad.savedrevs.timeslider": "คุณสามารถดูรุ่นแก้ไขที่บันทึกแล้วโดยเยี่ยมชมตัวเลื่อนเวลา",
"pad.userlist.entername": "กรอกชื่อของคุณ",
"pad.userlist.entername": "ป้อนชื่อของคุณ",
"pad.userlist.unnamed": "ไม่มีชื่อ",
"pad.editbar.clearcolors": "ลบการเน้นความเป็นเจ้าของข้อความหรือไม่? การกระทำนี่ไม่สามารถย้อนได้",
"pad.impexp.importbutton": "นำเข้าตอนนี้",

View File

@ -5,6 +5,7 @@
"Base",
"Bunyk",
"DDPAT",
"Ice bulldog",
"Lxlalexlxl",
"Movses",
"Olvin",

Some files were not shown because too many files have changed in this diff Show More