Compare commits
1 Commits
android-v2
...
@joplin/to
Author | SHA1 | Date | |
---|---|---|---|
|
b490537c26 |
@@ -1,19 +1,10 @@
|
|||||||
_mydocs/
|
|
||||||
_releases/
|
|
||||||
.git/
|
|
||||||
.yarn/cache/
|
|
||||||
**/.DS_Store
|
|
||||||
**/node_modules
|
**/node_modules
|
||||||
Assets/
|
Assets/
|
||||||
docs/
|
.git/
|
||||||
lerna-debug.log
|
_releases/
|
||||||
packages/app-cli/
|
packages/app-desktop
|
||||||
packages/app-clipper/
|
packages/app-cli
|
||||||
packages/app-desktop/
|
packages/app-mobile
|
||||||
packages/app-mobile/
|
packages/app-clipper
|
||||||
packages/generator-joplin/
|
packages/generator-joplin
|
||||||
packages/plugin-repo-cli/
|
packages/plugin-repo-cli
|
||||||
packages/server/db-*.sqlite
|
|
||||||
packages/server/dist/
|
|
||||||
packages/server/logs/
|
|
||||||
packages/server/temp/
|
|
670
.eslintignore
62
.eslintrc.js
@@ -76,22 +76,17 @@ module.exports = {
|
|||||||
|
|
||||||
'no-array-constructor': ['error'],
|
'no-array-constructor': ['error'],
|
||||||
'radix': ['error'],
|
'radix': ['error'],
|
||||||
'eqeqeq': ['error', 'always'],
|
|
||||||
|
|
||||||
// Warn only for now because fixing everything would take too much
|
// Warn only for now because fixing everything would take too much
|
||||||
// refactoring, but new code should try to stick to it.
|
// refactoring, but new code should try to stick to it.
|
||||||
// 'complexity': ['warn', { max: 10 }],
|
// 'complexity': ['warn', { max: 10 }],
|
||||||
|
|
||||||
// Checks rules of Hooks
|
// Checks rules of Hooks
|
||||||
'@seiyab/react-hooks/rules-of-hooks': 'error',
|
'react-hooks/rules-of-hooks': 'error',
|
||||||
'@seiyab/react-hooks/exhaustive-deps': ['error', { 'ignoreThisDependency': 'props' }],
|
|
||||||
|
|
||||||
// Checks effect dependencies
|
// Checks effect dependencies
|
||||||
// Disable because of this: https://github.com/facebook/react/issues/16265
|
// Disable because of this: https://github.com/facebook/react/issues/16265
|
||||||
// "react-hooks/exhaustive-deps": "warn",
|
// "react-hooks/exhaustive-deps": "warn",
|
||||||
|
|
||||||
'promise/prefer-await-to-then': 'error',
|
|
||||||
|
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
// Formatting
|
// Formatting
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
@@ -138,12 +133,8 @@ module.exports = {
|
|||||||
'plugins': [
|
'plugins': [
|
||||||
'react',
|
'react',
|
||||||
'@typescript-eslint',
|
'@typescript-eslint',
|
||||||
// Need to use a fork of the official rules of hooks because of this bug:
|
'react-hooks',
|
||||||
// https://github.com/facebook/react/issues/16265
|
|
||||||
'@seiyab/eslint-plugin-react-hooks',
|
|
||||||
// 'react-hooks',
|
|
||||||
'import',
|
'import',
|
||||||
'promise',
|
|
||||||
],
|
],
|
||||||
'overrides': [
|
'overrides': [
|
||||||
{
|
{
|
||||||
@@ -180,55 +171,6 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
'@typescript-eslint/no-floating-promises': ['error'],
|
'@typescript-eslint/no-floating-promises': ['error'],
|
||||||
'@typescript-eslint/naming-convention': ['error',
|
|
||||||
// Naming conventions over the codebase is very inconsistent
|
|
||||||
// unfortunately and fixing it would be way too much work.
|
|
||||||
// In general, we use "strictCamelCase" for variable names.
|
|
||||||
|
|
||||||
// {
|
|
||||||
// selector: 'default',
|
|
||||||
// format: ['StrictPascalCase', 'strictCamelCase', 'snake_case', 'UPPER_CASE'],
|
|
||||||
// leadingUnderscore: 'allow',
|
|
||||||
// trailingUnderscore: 'allow',
|
|
||||||
// },
|
|
||||||
|
|
||||||
// Each rule below is made of two blocks: first the rule we
|
|
||||||
// actually want, and below exceptions to the rule.
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// ENUM
|
|
||||||
// -----------------------------------
|
|
||||||
|
|
||||||
{
|
|
||||||
selector: 'enumMember',
|
|
||||||
format: ['StrictPascalCase'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
selector: 'enumMember',
|
|
||||||
format: null,
|
|
||||||
'filter': {
|
|
||||||
'regex': '^(GET|POST|PUT|DELETE|PATCH|HEAD|SQLite|PostgreSQL|ASC|DESC|E2EE|OR|AND|UNION|INTERSECT|EXCLUSION|INCLUSION|EUR|GBP|USD|SJCL.*)$',
|
|
||||||
'match': true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
// -----------------------------------
|
|
||||||
// INTERFACE
|
|
||||||
// -----------------------------------
|
|
||||||
|
|
||||||
{
|
|
||||||
selector: 'interface',
|
|
||||||
format: ['StrictPascalCase'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
selector: 'interface',
|
|
||||||
format: null,
|
|
||||||
'filter': {
|
|
||||||
'regex': '^(RSA|RSAKeyPair)$',
|
|
||||||
'match': true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -9,8 +9,7 @@ assignees: ''
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
Please provide a clear and concise description of what the bug is. (In the section Steps To Reproduce.)
|
Please provide a clear and concise description of what the bug is. (In the section Steps To Reproduce.)
|
||||||
Include screenshots for UI problems if needed.
|
Include screenshots if needed.
|
||||||
DO NOT create screenshots of text !!! Copy and paste the text into a code block.
|
|
||||||
Please test using the latest Joplin release to make sure your issue has not already been fixed.
|
Please test using the latest Joplin release to make sure your issue has not already been fixed.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
74
.github/scripts/run_ci.sh
vendored
@@ -37,9 +37,6 @@ echo "GITHUB_EVENT_NAME=$GITHUB_EVENT_NAME"
|
|||||||
echo "GITHUB_REF=$GITHUB_REF"
|
echo "GITHUB_REF=$GITHUB_REF"
|
||||||
echo "RUNNER_OS=$RUNNER_OS"
|
echo "RUNNER_OS=$RUNNER_OS"
|
||||||
echo "GIT_TAG_NAME=$GIT_TAG_NAME"
|
echo "GIT_TAG_NAME=$GIT_TAG_NAME"
|
||||||
echo "BUILD_SEQUENCIAL=$BUILD_SEQUENCIAL"
|
|
||||||
echo "SERVER_REPOSITORY=$SERVER_REPOSITORY"
|
|
||||||
echo "SERVER_TAG_PREFIX=$SERVER_TAG_PREFIX"
|
|
||||||
|
|
||||||
echo "IS_CONTINUOUS_INTEGRATION=$IS_CONTINUOUS_INTEGRATION"
|
echo "IS_CONTINUOUS_INTEGRATION=$IS_CONTINUOUS_INTEGRATION"
|
||||||
echo "IS_PULL_REQUEST=$IS_PULL_REQUEST"
|
echo "IS_PULL_REQUEST=$IS_PULL_REQUEST"
|
||||||
@@ -49,19 +46,13 @@ echo "IS_MACOS=$IS_MACOS"
|
|||||||
|
|
||||||
echo "Node $( node -v )"
|
echo "Node $( node -v )"
|
||||||
echo "Npm $( npm -v )"
|
echo "Npm $( npm -v )"
|
||||||
echo "Yarn $( yarn -v )"
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Install packages
|
# Install packages
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
cd "$ROOT_DIR"
|
cd "$ROOT_DIR"
|
||||||
yarn install
|
npm install
|
||||||
testResult=$?
|
|
||||||
if [ $testResult -ne 0 ]; then
|
|
||||||
echo "Yarn installation failed. Search for 'exit code 1' in the log for more information."
|
|
||||||
exit $testResult
|
|
||||||
fi
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Run test units. Only do it for pull requests and dev branch because we don't
|
# Run test units. Only do it for pull requests and dev branch because we don't
|
||||||
@@ -71,23 +62,7 @@ fi
|
|||||||
if [ "$IS_PULL_REQUEST" == "1" ] || [ "$IS_DEV_BRANCH" = "1" ]; then
|
if [ "$IS_PULL_REQUEST" == "1" ] || [ "$IS_DEV_BRANCH" = "1" ]; then
|
||||||
echo "Step: Running tests..."
|
echo "Step: Running tests..."
|
||||||
|
|
||||||
# On Linux, we run the Joplin Server tests using PostgreSQL
|
npm run test-ci
|
||||||
if [ "$IS_LINUX" == "1" ]; then
|
|
||||||
echo "Running Joplin Server tests using PostgreSQL..."
|
|
||||||
sudo docker-compose --file docker-compose.db-dev.yml up -d
|
|
||||||
export JOPLIN_TESTS_SERVER_DB=pg
|
|
||||||
else
|
|
||||||
echo "Running Joplin Server tests using SQLite..."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Need this because we're getting this error:
|
|
||||||
#
|
|
||||||
# @joplin/lib: FATAL ERROR: Ineffective mark-compacts near heap limit
|
|
||||||
# Allocation failed - JavaScript heap out of memory
|
|
||||||
#
|
|
||||||
# https://stackoverflow.com/questions/38558989
|
|
||||||
export NODE_OPTIONS="--max-old-space-size=4096"
|
|
||||||
yarn run test-ci
|
|
||||||
testResult=$?
|
testResult=$?
|
||||||
if [ $testResult -ne 0 ]; then
|
if [ $testResult -ne 0 ]; then
|
||||||
exit $testResult
|
exit $testResult
|
||||||
@@ -99,10 +74,10 @@ fi
|
|||||||
# release randomly fail.
|
# release randomly fail.
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
if [ "$IS_PULL_REQUEST" == "1" ] || [ "$IS_DEV_BRANCH" = "1" ]; then
|
if [ "$IS_PULL_REQUEST" == "1" ]; then
|
||||||
echo "Step: Running linter..."
|
echo "Step: Running linter..."
|
||||||
|
|
||||||
yarn run linter-ci ./
|
npm run linter-ci ./
|
||||||
testResult=$?
|
testResult=$?
|
||||||
if [ $testResult -ne 0 ]; then
|
if [ $testResult -ne 0 ]; then
|
||||||
exit $testResult
|
exit $testResult
|
||||||
@@ -127,27 +102,6 @@ if [ "$IS_PULL_REQUEST" == "1" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# =============================================================================
|
|
||||||
# Check that we didn't lose any string due to gettext not being able to parse
|
|
||||||
# newly modified or added scripts. This is convenient to quickly view on GitHub
|
|
||||||
# what commit may have broken translation building. We run this on macOS because
|
|
||||||
# we need the latest version of gettext (and stable Ubuntu doesn't have it).
|
|
||||||
# =============================================================================
|
|
||||||
|
|
||||||
if [ "$IS_PULL_REQUEST" == "1" ] || [ "$IS_DEV_BRANCH" = "1" ]; then
|
|
||||||
if [ "$IS_MACOS" == "1" ]; then
|
|
||||||
echo "Step: Checking for lost translation strings..."
|
|
||||||
|
|
||||||
xgettext --version
|
|
||||||
|
|
||||||
node packages/tools/build-translation.js --missing-strings-check-only
|
|
||||||
testResult=$?
|
|
||||||
if [ $testResult -ne 0 ]; then
|
|
||||||
exit $testResult
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Find out if we should run the build or not. Electron-builder gets stuck when
|
# Find out if we should run the build or not. Electron-builder gets stuck when
|
||||||
# building PRs so we disable it in this case. The Linux build should provide
|
# building PRs so we disable it in this case. The Linux build should provide
|
||||||
@@ -163,27 +117,25 @@ if [ "$IS_PULL_REQUEST" == "1" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Build the Electron app or Docker image depending on the current tag.
|
# Prepare the Electron app and build it
|
||||||
#
|
#
|
||||||
# If the current tag is a desktop release tag (starts with "v", such as
|
# If the current tag is a desktop release tag (starts with "v", such as
|
||||||
# "v1.4.7"), we build and publish to GitHub. Otherwise we only build but don't
|
# "v1.4.7"), we build and publish to github
|
||||||
# publish to GitHub. It helps finding out any issue in pull requests and dev
|
#
|
||||||
# branch.
|
# Otherwise we only build but don't publish to GitHub. It helps finding
|
||||||
|
# out any issue in pull requests and dev branch.
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
cd "$ROOT_DIR/packages/app-desktop"
|
cd "$ROOT_DIR/packages/app-desktop"
|
||||||
|
|
||||||
if [[ $GIT_TAG_NAME = v* ]]; then
|
if [[ $GIT_TAG_NAME = v* ]]; then
|
||||||
echo "Step: Building and publishing desktop application..."
|
echo "Step: Building and publishing desktop application..."
|
||||||
# cd "$ROOT_DIR/packages/tools"
|
USE_HARD_LINKS=false npm run dist
|
||||||
# node bundleDefaultPlugins.js
|
elif [[ $GIT_TAG_NAME = server-v* ]] && [[ $IS_LINUX = 1 ]]; then
|
||||||
cd "$ROOT_DIR/packages/app-desktop"
|
|
||||||
USE_HARD_LINKS=false yarn run dist
|
|
||||||
elif [[ $IS_LINUX = 1 ]] && [[ $GIT_TAG_NAME = $SERVER_TAG_PREFIX-* ]]; then
|
|
||||||
echo "Step: Building Docker Image..."
|
echo "Step: Building Docker Image..."
|
||||||
cd "$ROOT_DIR"
|
cd "$ROOT_DIR"
|
||||||
yarn run buildServerDocker --tag-name $GIT_TAG_NAME --push-images --repository $SERVER_REPOSITORY
|
npm run buildServerDocker -- --tag-name $GIT_TAG_NAME
|
||||||
else
|
else
|
||||||
echo "Step: Building but *not* publishing desktop application..."
|
echo "Step: Building but *not* publishing desktop application..."
|
||||||
USE_HARD_LINKS=false yarn run dist --publish=never
|
USE_HARD_LINKS=false npm run dist -- --publish=never
|
||||||
fi
|
fi
|
||||||
|
25
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Configuration for probot-stale - https://github.com/probot/stale
|
||||||
|
# Number of days of inactivity before an issue becomes stale
|
||||||
|
daysUntilStale: 30
|
||||||
|
# Number of days of inactivity before a stale issue is closed
|
||||||
|
daysUntilClose: 7
|
||||||
|
# Issues with these labels will never be considered stale
|
||||||
|
exemptLabels:
|
||||||
|
- "good first issue"
|
||||||
|
- "upstream"
|
||||||
|
- "backlog"
|
||||||
|
- "high"
|
||||||
|
- "medium"
|
||||||
|
- "spec"
|
||||||
|
- "cannot reproduce"
|
||||||
|
# Label to use when marking an issue as stale
|
||||||
|
staleLabel: stale
|
||||||
|
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||||
|
markComment: >
|
||||||
|
Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs.
|
||||||
|
You may comment on the issue and I will leave it open.
|
||||||
|
Thank you for your contributions.
|
||||||
|
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||||
|
closeComment: >
|
||||||
|
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.
|
||||||
|
only: issues
|
23
.github/workflows/close-stale-issues.yml
vendored
@@ -1,23 +0,0 @@
|
|||||||
name: 'Close stale issues'
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 16 * * *'
|
|
||||||
permissions:
|
|
||||||
issues: write
|
|
||||||
jobs:
|
|
||||||
ProcessStaleIssues:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/stale@v4
|
|
||||||
with:
|
|
||||||
# Use this to do a dry run from a pull request
|
|
||||||
# debug-only: true
|
|
||||||
stale-issue-message: "Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? If you require support or are requesting an enhancement or feature then please create a topic on the [Joplin forum](https://discourse.joplinapp.org/). This issue may be closed if no further activity occurs. You may comment on the issue and I will leave it open. Thank you for your contributions."
|
|
||||||
days-before-stale: 30
|
|
||||||
days-before-close: 7
|
|
||||||
operations-per-run: 1000
|
|
||||||
exempt-issue-labels: 'good first issue,upstream,backlog,high,medium,spec,cannot reproduce,enhancement'
|
|
||||||
stale-issue-label: 'stale'
|
|
||||||
close-issue-message: 'Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, feel free to create a new issue with up-to-date information.'
|
|
||||||
# Don't process pull requests at all
|
|
||||||
days-before-pr-stale: -1
|
|
82
.github/workflows/github-actions-main.yml
vendored
@@ -5,7 +5,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, ubuntu-latest, windows-2019]
|
os: [macos-latest, ubuntu-latest, windows-2016]
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
# Silence apt-get update errors (for example when a module doesn't
|
# Silence apt-get update errors (for example when a module doesn't
|
||||||
@@ -19,18 +19,9 @@ jobs:
|
|||||||
sudo apt-get update || true
|
sudo apt-get update || true
|
||||||
sudo apt-get install -y gettext
|
sudo apt-get install -y gettext
|
||||||
sudo apt-get install -y libsecret-1-dev
|
sudo apt-get install -y libsecret-1-dev
|
||||||
sudo apt-get install -y translate-toolkit
|
|
||||||
|
|
||||||
- name: Install macOS dependencies
|
|
||||||
if: runner.os == 'macOS'
|
|
||||||
run: |
|
|
||||||
brew update
|
|
||||||
brew install gettext
|
|
||||||
brew install translate-toolkit
|
|
||||||
|
|
||||||
- name: Install Docker Engine
|
- name: Install Docker Engine
|
||||||
# if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/server-v')
|
if: runner.os == 'Linux' && startsWith(github.ref, 'refs/tags/server-v')
|
||||||
if: runner.os == 'Linux'
|
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install -y apt-transport-https
|
sudo apt-get install -y apt-transport-https
|
||||||
sudo apt-get install -y ca-certificates
|
sudo apt-get install -y ca-certificates
|
||||||
@@ -48,12 +39,7 @@ jobs:
|
|||||||
- uses: olegtarasov/get-tag@v2.1
|
- uses: olegtarasov/get-tag@v2.1
|
||||||
- uses: actions/setup-node@v2
|
- uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: '16'
|
node-version: '12'
|
||||||
|
|
||||||
- name: Install Yarn
|
|
||||||
run: |
|
|
||||||
# https://yarnpkg.com/getting-started/install
|
|
||||||
corepack enable
|
|
||||||
|
|
||||||
# Login to Docker only if we're on a server release tag. If we run this on
|
# Login to Docker only if we're on a server release tag. If we run this on
|
||||||
# a pull request it will fail because the PR doesn't have access to
|
# a pull request it will fail because the PR doesn't have access to
|
||||||
@@ -74,9 +60,6 @@ jobs:
|
|||||||
CSC_LINK: ${{ secrets.APPLE_CSC_LINK }}
|
CSC_LINK: ${{ secrets.APPLE_CSC_LINK }}
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||||
IS_CONTINUOUS_INTEGRATION: 1
|
IS_CONTINUOUS_INTEGRATION: 1
|
||||||
BUILD_SEQUENCIAL: 1
|
|
||||||
SERVER_REPOSITORY: joplin/server
|
|
||||||
SERVER_TAG_PREFIX: server
|
|
||||||
run: |
|
run: |
|
||||||
"${GITHUB_WORKSPACE}/.github/scripts/run_ci.sh"
|
"${GITHUB_WORKSPACE}/.github/scripts/run_ci.sh"
|
||||||
|
|
||||||
@@ -87,60 +70,7 @@ jobs:
|
|||||||
CSC_LINK: ${{ secrets.WINDOWS_CSC_LINK }}
|
CSC_LINK: ${{ secrets.WINDOWS_CSC_LINK }}
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||||
IS_CONTINUOUS_INTEGRATION: 1
|
IS_CONTINUOUS_INTEGRATION: 1
|
||||||
BUILD_SEQUENCIAL: 1
|
|
||||||
# To ensure that the operations stop on failure, all commands
|
|
||||||
# should be on one line with "&&" in between.
|
|
||||||
run: |
|
run: |
|
||||||
yarn install && cd packages/app-desktop && yarn run dist
|
npm install
|
||||||
|
cd packages/app-desktop
|
||||||
# Build and package the Windows app, without publishing it, just to
|
npm run dist
|
||||||
# verify that the build process hasn't been broken.
|
|
||||||
- name: Build Windows app (no publishing)
|
|
||||||
if: runner.os == 'Windows' && !startsWith(github.ref, 'refs/tags/v')
|
|
||||||
env:
|
|
||||||
IS_CONTINUOUS_INTEGRATION: 1
|
|
||||||
BUILD_SEQUENCIAL: 1
|
|
||||||
SERVER_REPOSITORY: joplin/server
|
|
||||||
SERVER_TAG_PREFIX: server
|
|
||||||
run: |
|
|
||||||
yarn install && cd packages/app-desktop && yarn run dist --publish=never
|
|
||||||
|
|
||||||
ServerDockerImage:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest]
|
|
||||||
steps:
|
|
||||||
|
|
||||||
- name: Install Docker Engine
|
|
||||||
run: |
|
|
||||||
sudo apt-get install -y apt-transport-https
|
|
||||||
sudo apt-get install -y ca-certificates
|
|
||||||
sudo apt-get install -y curl
|
|
||||||
sudo apt-get install -y gnupg
|
|
||||||
sudo apt-get install -y lsb-release
|
|
||||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
|
||||||
echo \
|
|
||||||
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
|
|
||||||
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
|
||||||
sudo apt-get update || true
|
|
||||||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
|
|
||||||
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: '16'
|
|
||||||
|
|
||||||
- name: Install Yarn
|
|
||||||
run: |
|
|
||||||
# https://yarnpkg.com/getting-started/install
|
|
||||||
corepack enable
|
|
||||||
|
|
||||||
- name: Build Docker Image
|
|
||||||
env:
|
|
||||||
BUILD_SEQUENCIAL: 1
|
|
||||||
run: |
|
|
||||||
yarn install
|
|
||||||
yarn run buildServerDocker --tag-name server-v0.0.0 --repository joplin/server
|
|
||||||
|
|
654
.gitignore
vendored
768
.yarn/releases/yarn-3.1.1.cjs
vendored
@@ -1,9 +0,0 @@
|
|||||||
nmHoistingLimits: workspaces
|
|
||||||
|
|
||||||
nodeLinker: node-modules
|
|
||||||
|
|
||||||
plugins:
|
|
||||||
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
|
|
||||||
spec: "@yarnpkg/plugin-workspace-tools"
|
|
||||||
|
|
||||||
yarnPath: .yarn/releases/yarn-3.1.1.cjs
|
|
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 246 KiB |
@@ -9,13 +9,11 @@ import PluginManager from 'tinymce/core/api/PluginManager';
|
|||||||
import * as Api from './api/Api';
|
import * as Api from './api/Api';
|
||||||
import * as Commands from './api/Commands';
|
import * as Commands from './api/Commands';
|
||||||
import * as Keyboard from './core/Keyboard';
|
import * as Keyboard from './core/Keyboard';
|
||||||
import * as Mouse from './core/Mouse'
|
|
||||||
import * as Buttons from './ui/Buttons';
|
import * as Buttons from './ui/Buttons';
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
PluginManager.add('joplinLists', function (editor) {
|
PluginManager.add('joplinLists', function (editor) {
|
||||||
Keyboard.setup(editor);
|
Keyboard.setup(editor);
|
||||||
Mouse.setup(editor);
|
|
||||||
Buttons.register(editor);
|
Buttons.register(editor);
|
||||||
Commands.register(editor);
|
Commands.register(editor);
|
||||||
|
|
||||||
|
@@ -1,26 +0,0 @@
|
|||||||
import { isJoplinChecklistItem } from '../listModel/JoplinListUtil';
|
|
||||||
|
|
||||||
|
|
||||||
const setup = function (editor) {
|
|
||||||
const editorClickHandler = (event) => {
|
|
||||||
if (!isJoplinChecklistItem(event.target)) return;
|
|
||||||
|
|
||||||
// We only process the click if it's within the checkbox itself (and not the label).
|
|
||||||
// That checkbox, based on
|
|
||||||
// the current styling is in the negative margin, so offsetX is negative when clicking
|
|
||||||
// on the checkbox itself, and positive when clicking on the label. This is strongly
|
|
||||||
// dependent on how the checkbox is styled, so if the style is changed, this might need
|
|
||||||
// to be updated too.
|
|
||||||
// For the styling, see:
|
|
||||||
// packages/renderer/MdToHtml/rules/checkbox.ts
|
|
||||||
//
|
|
||||||
// The previous solution was to use "pointer-event: none", which mostly work, however
|
|
||||||
// it means that links are no longer clickable when they are within the checkbox label.
|
|
||||||
if (event.offsetX >= 0) return;
|
|
||||||
|
|
||||||
editor.execCommand('ToggleJoplinChecklistItem', false, { element: event.target });
|
|
||||||
}
|
|
||||||
editor.on('click', editorClickHandler);
|
|
||||||
};
|
|
||||||
|
|
||||||
export { setup };
|
|
@@ -10,7 +10,7 @@ import * as Settings from '../api/Settings';
|
|||||||
import * as NodeType from '../core/NodeType';
|
import * as NodeType from '../core/NodeType';
|
||||||
import Editor from 'tinymce/core/api/Editor';
|
import Editor from 'tinymce/core/api/Editor';
|
||||||
import { isCustomList } from '../core/Util';
|
import { isCustomList } from '../core/Util';
|
||||||
import { findContainerListTypeFromEvent } from '../listModel/JoplinListUtil';
|
import { findContainerListTypeFromEvent, isJoplinChecklistItem } from '../listModel/JoplinListUtil';
|
||||||
|
|
||||||
const findIndex = function (list, predicate) {
|
const findIndex = function (list, predicate) {
|
||||||
for (let index = 0; index < list.length; index++) {
|
for (let index = 0; index < list.length; index++) {
|
||||||
@@ -38,11 +38,37 @@ const listState = function (editor: Editor, listName, options:any = {}) {
|
|||||||
buttonApi.setActive(listType === options.listType && lists.length > 0 && lists[0].nodeName === listName && !isCustomList(lists[0]));
|
buttonApi.setActive(listType === options.listType && lists.length > 0 && lists[0].nodeName === listName && !isCustomList(lists[0]));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const editorClickHandler = (event) => {
|
||||||
|
if (!isJoplinChecklistItem(event.target)) return;
|
||||||
|
|
||||||
|
// We only process the click if it's within the checkbox itself (and not the label).
|
||||||
|
// That checkbox, based on
|
||||||
|
// the current styling is in the negative margin, so offsetX is negative when clicking
|
||||||
|
// on the checkbox itself, and positive when clicking on the label. This is strongly
|
||||||
|
// dependent on how the checkbox is styled, so if the style is changed, this might need
|
||||||
|
// to be updated too.
|
||||||
|
// For the styling, see:
|
||||||
|
// packages/renderer/MdToHtml/rules/checkbox.ts
|
||||||
|
//
|
||||||
|
// The previous solution was to use "pointer-event: none", which mostly work, however
|
||||||
|
// it means that links are no longer clickable when they are within the checkbox label.
|
||||||
|
if (event.offsetX >= 0) return;
|
||||||
|
|
||||||
|
editor.execCommand('ToggleJoplinChecklistItem', false, { element: event.target });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.listType === 'joplinChecklist') {
|
||||||
|
editor.on('click', editorClickHandler);
|
||||||
|
}
|
||||||
|
|
||||||
editor.on('NodeChange', nodeChangeHandler);
|
editor.on('NodeChange', nodeChangeHandler);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
if (options.listType === 'joplinChecklist') {
|
||||||
|
editor.off('click', editorClickHandler);
|
||||||
|
}
|
||||||
editor.off('NodeChange', nodeChangeHandler);
|
editor.off('NodeChange', nodeChangeHandler);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
4
Assets/WebsiteAssets/css/font-awesome.min.css
vendored
Normal file
12
Assets/WebsiteAssets/css/fork-awesome.min.css
vendored
Normal file
@@ -18,18 +18,10 @@ a {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
ol, ul {
|
|
||||||
padding-left: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row > ul, ol {
|
|
||||||
margin-left: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#main-container {
|
#main-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
padding-bottom: 127px; /* Needs to be the height of the footer */
|
padding-bottom: 225px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.help-page-container img {
|
.help-page-container img {
|
||||||
@@ -121,10 +113,6 @@ blockquote {
|
|||||||
font-size: 16px !important;
|
font-size: 16px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-link {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sponsor-button i {
|
.sponsor-button i {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
@@ -188,11 +176,6 @@ h2 {
|
|||||||
padding-bottom: 0.5em;
|
padding-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: 1.3em;
|
|
||||||
margin-bottom: 0.8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.front-page h1 {
|
.front-page h1 {
|
||||||
font-size: 3em;
|
font-size: 3em;
|
||||||
}
|
}
|
||||||
@@ -304,12 +287,6 @@ p,
|
|||||||
/* margin-bottom: 10px; */
|
/* margin-bottom: 10px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
div.navbar-mobile-content a.sponsor-button {
|
|
||||||
padding: 4px 12px;
|
|
||||||
font-size: 0.9em;
|
|
||||||
margin-right: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#nav-section.white-bg a {
|
#nav-section.white-bg a {
|
||||||
color: #0557ba;
|
color: #0557ba;
|
||||||
}
|
}
|
||||||
@@ -523,17 +500,12 @@ div.navbar-mobile-content a.sponsor-button {
|
|||||||
|
|
||||||
.bottom-links {
|
.bottom-links {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border-top: 1px solid #d4d4d4;
|
border-top: 1px solid #d4d4d4;
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bottom-links .bottom-link {
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TOC */
|
/* TOC */
|
||||||
|
|
||||||
#toc ul {
|
#toc ul {
|
||||||
@@ -593,7 +565,7 @@ div.navbar-mobile-content a.sponsor-button {
|
|||||||
|
|
||||||
/* footer section */
|
/* footer section */
|
||||||
footer {
|
footer {
|
||||||
padding-top: 30px;
|
padding-top: 50px;
|
||||||
padding-bottom: 30px;
|
padding-bottom: 30px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
@@ -604,7 +576,6 @@ footer a,
|
|||||||
footer p {
|
footer p {
|
||||||
color: #90b1d9;
|
color: #90b1d9;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
footer a:hover {
|
footer a:hover {
|
||||||
@@ -628,53 +599,6 @@ footer .right-links a {
|
|||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer .footer-right {
|
|
||||||
margin-left: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer .social-links {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
border-bottom: 1px solid #315885;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer .social-links a:hover {
|
|
||||||
color: #e8f3ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer .social-links i {
|
|
||||||
margin-left: 15px;
|
|
||||||
font-size: 22px;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer .bottom-links-row {
|
|
||||||
padding-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer .bottom-links-row p {
|
|
||||||
font-size: 1.1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************
|
|
||||||
WHAT'S NEW PAGE
|
|
||||||
*****************************************************************/
|
|
||||||
|
|
||||||
.news-page .container > .content-wrapper,
|
|
||||||
.news-item-page .container > .content-wrapper {
|
|
||||||
/* Set the line width so that there's no more than 75 characters per line */
|
|
||||||
/* https://baymard.com/blog/line-length-readability */
|
|
||||||
max-width: 650px;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.news-page .main-content img,
|
|
||||||
.news-item-page .main-content img {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
IN THE PRESS
|
IN THE PRESS
|
||||||
The "In the press" section height needs to be adjusted as the
|
The "In the press" section height needs to be adjusted as the
|
||||||
@@ -728,23 +652,6 @@ footer .bottom-links-row p {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************
|
|
||||||
MEDIUM VIEW
|
|
||||||
- Make menu bar elements smaller and closer to each others
|
|
||||||
so that everything fit.
|
|
||||||
*****************************************************************/
|
|
||||||
|
|
||||||
@media (max-width: 990px) {
|
|
||||||
#nav-section > .container {
|
|
||||||
max-width: 960px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#nav-section .button-link {
|
|
||||||
padding: 4px 10px;
|
|
||||||
font-size: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
NARROW VIEW
|
NARROW VIEW
|
||||||
- Top right menu is displayed
|
- Top right menu is displayed
|
||||||
@@ -754,24 +661,7 @@ footer .bottom-links-row p {
|
|||||||
#main-container {
|
#main-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
padding-bottom: 130px;
|
padding-bottom: 260px;
|
||||||
}
|
|
||||||
|
|
||||||
#menu-mobile .social-links {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#menu-mobile .social-links a {
|
|
||||||
margin-left: 15px;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#menu-mobile .social-links .social-link-mastodon,
|
|
||||||
#menu-mobile .social-links .social-link-reddit,
|
|
||||||
#menu-mobile .social-links .social-link-patreon {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.front-page h1 {
|
.front-page h1 {
|
||||||
@@ -891,7 +781,7 @@ footer .bottom-links-row p {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#menu-mobile .button-link {
|
#menu-mobile .button-link {
|
||||||
padding: 4px 12px;
|
padding: 10px 15px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
}
|
}
|
||||||
@@ -937,25 +827,6 @@ footer .bottom-links-row p {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************
|
|
||||||
VERY NARROW VIEW
|
|
||||||
eg for Galaxy Fold
|
|
||||||
*****************************************************************/
|
|
||||||
|
|
||||||
@media (max-width: 350px) {
|
|
||||||
|
|
||||||
#nav-section .navbar-mobile-content a.sponsor-button {
|
|
||||||
background-color: transparent;
|
|
||||||
color: #0557ba !important;
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#nav-section .navbar-mobile-content a.sponsor-button .sponsor-button-label {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
PLANS PAGE
|
PLANS PAGE
|
||||||
*****************************************************************/
|
*****************************************************************/
|
||||||
@@ -977,7 +848,7 @@ footer .bottom-links-row p {
|
|||||||
|
|
||||||
.help-page-container {
|
.help-page-container {
|
||||||
padding-top: 90px;
|
padding-top: 90px;
|
||||||
padding-bottom: 70px;
|
padding-bottom: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.donate-links {
|
.donate-links {
|
||||||
@@ -991,7 +862,7 @@ footer .bottom-links-row p {
|
|||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
padding: 30px 20px;
|
padding: 30px 20px;
|
||||||
padding-bottom: 30px;
|
padding-bottom: 30px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 50px;
|
||||||
margin-top: 40px;
|
margin-top: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1016,7 +887,7 @@ footer .bottom-links-row p {
|
|||||||
background: linear-gradient(251.85deg, #0b4f99 -11.85%, #002d61 104.73%);
|
background: linear-gradient(251.85deg, #0b4f99 -11.85%, #002d61 104.73%);
|
||||||
box-shadow: 0px 4px 16px rgba(105, 132, 172, 0.13);
|
box-shadow: 0px 4px 16px rgba(105, 132, 172, 0.13);
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
padding-top: 40px;
|
padding-top: 50px;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1034,11 +905,6 @@ footer .bottom-links-row p {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.plan-group .joplin-cloud-login-info {
|
|
||||||
margin-bottom: 40px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plan-group .plan-price-yearly-per-year {
|
.plan-group .plan-price-yearly-per-year {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
@@ -1073,10 +939,6 @@ footer .bottom-links-row p {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.joplin-cloud-feature-list table {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.price-row .plan-type {
|
.price-row .plan-type {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -1085,7 +947,6 @@ footer .bottom-links-row p {
|
|||||||
|
|
||||||
.price-row .plan-type img {
|
.price-row .plan-type img {
|
||||||
width: 65px;
|
width: 65px;
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.price-row .plan-price {
|
.price-row .plan-price {
|
||||||
|
BIN
Assets/WebsiteAssets/fonts/forkawesome-webfont.eot
Normal file
2849
Assets/WebsiteAssets/fonts/forkawesome-webfont.svg
Normal file
After Width: | Height: | Size: 470 KiB |
BIN
Assets/WebsiteAssets/fonts/forkawesome-webfont.ttf
Normal file
BIN
Assets/WebsiteAssets/fonts/forkawesome-webfont.woff
Normal file
BIN
Assets/WebsiteAssets/fonts/forkawesome-webfont.woff2
Normal file
Before Width: | Height: | Size: 292 KiB |
Before Width: | Height: | Size: 382 KiB |
Before Width: | Height: | Size: 167 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 144 KiB |
Before Width: | Height: | Size: 189 KiB |
Before Width: | Height: | Size: 201 KiB |
Before Width: | Height: | Size: 206 KiB |
Before Width: | Height: | Size: 107 KiB |
Before Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 246 KiB |
Before Width: | Height: | Size: 183 KiB |
Before Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 188 KiB |
Before Width: | Height: | Size: 244 KiB |
Before Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 261 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 128 KiB |
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 131 KiB |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 158 KiB |
Before Width: | Height: | Size: 133 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 119 KiB |
Before Width: | Height: | Size: 141 KiB |
Before Width: | Height: | Size: 241 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 84 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 6.5 KiB |