♻️ Icons and Styles build refactor.
6
.gitignore
vendored
|
@ -20,11 +20,7 @@ node_modules
|
||||||
/frontend/target/
|
/frontend/target/
|
||||||
/frontend/dist/
|
/frontend/dist/
|
||||||
/frontend/out/
|
/frontend/out/
|
||||||
/frontend/resources/public/js/compiled/**
|
/frontend/resources/public/*
|
||||||
/frontend/resources/public/css
|
|
||||||
/frontend/resources/public/js
|
|
||||||
/frontend/resources/public/view
|
|
||||||
/frontend/resources/public/index.html
|
|
||||||
/docker/frontend/dist
|
/docker/frontend/dist
|
||||||
/docker/backend/dist
|
/docker/backend/dist
|
||||||
/media
|
/media
|
||||||
|
|
|
@ -51,6 +51,7 @@ RUN curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
|
||||||
|
|
||||||
COPY files/bashrc /root/.bashrc
|
COPY files/bashrc /root/.bashrc
|
||||||
COPY files/vimrc /root/.vimrc
|
COPY files/vimrc /root/.vimrc
|
||||||
|
COPY files/phantomjs-mock /usr/bin/phantomjs
|
||||||
|
|
||||||
ARG EXTERNAL_UID=1000
|
ARG EXTERNAL_UID=1000
|
||||||
|
|
||||||
|
@ -68,7 +69,6 @@ RUN set -ex; \
|
||||||
USER uxbox
|
USER uxbox
|
||||||
WORKDIR /home/uxbox
|
WORKDIR /home/uxbox
|
||||||
|
|
||||||
COPY files/package.json /home/uxbox/package.json
|
|
||||||
COPY files/bashrc /home/uxbox/.bashrc
|
COPY files/bashrc /home/uxbox/.bashrc
|
||||||
COPY files/zshrc /home/uxbox/.zshrc
|
COPY files/zshrc /home/uxbox/.zshrc
|
||||||
COPY files/vimrc /home/uxbox/.vimrc
|
COPY files/vimrc /home/uxbox/.vimrc
|
||||||
|
@ -83,9 +83,6 @@ RUN set -ex; \
|
||||||
bash -c "source .nvm/nvm.sh && nvm alias default $NODE_VERSION"; \
|
bash -c "source .nvm/nvm.sh && nvm alias default $NODE_VERSION"; \
|
||||||
bash -c "source .nvm/nvm.sh && nvm use default";
|
bash -c "source .nvm/nvm.sh && nvm use default";
|
||||||
|
|
||||||
RUN set -ex; \
|
|
||||||
bash -c "source .nvm/nvm.sh && npm install";
|
|
||||||
|
|
||||||
EXPOSE 3449
|
EXPOSE 3449
|
||||||
EXPOSE 6060
|
EXPOSE 6060
|
||||||
EXPOSE 9090
|
EXPOSE 9090
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#!/usr/bin/env zsh
|
#!/usr/bin/env zsh
|
||||||
|
|
||||||
set -ex
|
set -ex
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
#!/usr/bin/env zsh
|
#!/usr/bin/env zsh
|
||||||
|
|
||||||
set -e;
|
set -e;
|
||||||
|
source ~/.zshrc
|
||||||
|
|
||||||
echo "[init.sh] Setting up local permissions."
|
echo "[init.sh] Setting up local permissions."
|
||||||
sudo chown -R uxbox /home/uxbox/local
|
sudo chown -R uxbox /home/uxbox/local
|
||||||
|
|
||||||
|
echo "[init.sh] Installing node dependencies"
|
||||||
|
pushd /home/uxbox/uxbox/frontend/
|
||||||
|
npm ci
|
||||||
|
popd
|
||||||
|
|
||||||
echo "[init.sh] Ready!"
|
echo "[init.sh] Ready!"
|
||||||
tail -f /dev/null
|
tail -f /dev/null
|
||||||
|
|
2
docker/devenv/files/phantomjs-mock
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
echo "2.1.1"
|
|
@ -1,81 +1,87 @@
|
||||||
const autoprefixer = require('gulp-autoprefixer');
|
|
||||||
const cleancss = require("gulp-clean-css");
|
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const l = require("lodash");
|
||||||
|
|
||||||
|
const CleanCSS = require("clean-css");
|
||||||
const gulp = require("gulp");
|
const gulp = require("gulp");
|
||||||
const gulpif = require("gulp-if");
|
const gulpif = require("gulp-if");
|
||||||
const gzip = require("gulp-gzip");
|
const gzip = require("gulp-gzip");
|
||||||
const l = require("lodash");
|
|
||||||
const mustache = require("gulp-mustache");
|
const mustache = require("gulp-mustache");
|
||||||
const rename = require("gulp-rename");
|
const rename = require("gulp-rename");
|
||||||
|
const svgSprite = require("gulp-svg-sprite");
|
||||||
|
|
||||||
|
const mkdirp = require("mkdirp");
|
||||||
const rimraf = require("rimraf");
|
const rimraf = require("rimraf");
|
||||||
const scss = require("gulp-sass");
|
const sass = require("sass");
|
||||||
|
const autoprefixer = require('autoprefixer')
|
||||||
|
const postcss = require('postcss')
|
||||||
|
|
||||||
const paths = {};
|
const paths = {};
|
||||||
paths.app = "./resources/";
|
paths.resources = "./resources/";
|
||||||
paths.output = "./resources/public/";
|
paths.output = "./resources/public/";
|
||||||
|
paths.build = "./target/build/";
|
||||||
paths.dist = "./target/dist/";
|
paths.dist = "./target/dist/";
|
||||||
paths.scss = paths.app + "styles/**/*.scss";
|
paths.scss = "./resources/styles/**/*.scss";
|
||||||
|
|
||||||
/***********************************************
|
/***********************************************
|
||||||
* Helper Tasks
|
* Helpers
|
||||||
***********************************************/
|
***********************************************/
|
||||||
|
|
||||||
gulp.task("clean", function(next) {
|
|
||||||
rimraf(paths.output + "css/", function() {
|
|
||||||
rimraf(paths.output + "js/", function() {
|
|
||||||
next()
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task("dist:clean", function(next) {
|
|
||||||
rimraf(paths.dist, next);
|
|
||||||
});
|
|
||||||
|
|
||||||
function makeAutoprefixer() {
|
|
||||||
return autoprefixer('last 2 version');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function isProduction() {
|
function isProduction() {
|
||||||
return (process.env.NODE_ENV === 'production');
|
return (process.env.NODE_ENV === 'production');
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************
|
|
||||||
* Development
|
|
||||||
***********************************************/
|
|
||||||
|
|
||||||
// Styles
|
|
||||||
|
|
||||||
function scssPipeline(options) {
|
function scssPipeline(options) {
|
||||||
return function() {
|
const write = (_path, data) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fs.writeFile(_path, data, function(err) {
|
||||||
|
if (err) { reject(err); }
|
||||||
|
else { resolve(); }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const render = (input) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
sass.render({file: input}, async function(err, result) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err.formatted);
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve(result.css);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const postprocess = (data, input, output) => {
|
||||||
|
return postcss([autoprefixer])
|
||||||
|
.process(data, {map: false, from: input, to: output})
|
||||||
|
};
|
||||||
|
|
||||||
|
return function(next) {
|
||||||
const input = options.input;
|
const input = options.input;
|
||||||
const output = options.output;
|
const output = options.output;
|
||||||
|
|
||||||
return gulp.src(input)
|
return mkdirp(path.dirname(output))
|
||||||
.pipe(scss({
|
.then(() => render(input))
|
||||||
style: "expanded",
|
.then((res) => postprocess(res, input, output))
|
||||||
errLogToConsole: false
|
.then((res) => write(output, res))
|
||||||
}).on("error", (err) => {
|
.catch((err) => null)
|
||||||
console.log(err.messageFormatted);
|
.then(() => {
|
||||||
}))
|
next();
|
||||||
.pipe(makeAutoprefixer())
|
});
|
||||||
.pipe(gulpif(isProduction, cleancss()))
|
|
||||||
.pipe(gulp.dest(output));
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
gulp.task("scss:main", scssPipeline({
|
// Templates
|
||||||
input: paths.app + "styles/main.scss",
|
|
||||||
output: paths.output + "css/"
|
|
||||||
}));
|
|
||||||
|
|
||||||
// gulp.task("scss:view", scssPipeline({
|
function readSvgSprite() {
|
||||||
// input: paths.app + "styles/view.scss",
|
const path = paths.build + "/icons-sprite/symbol/svg/sprite.symbol.svg";
|
||||||
// output: paths.output + "css/"
|
const content = fs.readFileSync(path, {encoding: "utf8"});
|
||||||
// }));
|
return content;
|
||||||
|
}
|
||||||
gulp.task("scss", gulp.parallel("scss:main"));
|
|
||||||
|
|
||||||
function readLocales() {
|
function readLocales() {
|
||||||
const path = __dirname + "/resources/locales.json";
|
const path = __dirname + "/resources/locales.json";
|
||||||
|
@ -94,8 +100,6 @@ function readLocales() {
|
||||||
return JSON.stringify(result);
|
return JSON.stringify(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Templates
|
|
||||||
|
|
||||||
function templatePipeline(options) {
|
function templatePipeline(options) {
|
||||||
return function() {
|
return function() {
|
||||||
const input = options.input;
|
const input = options.input;
|
||||||
|
@ -103,9 +107,11 @@ function templatePipeline(options) {
|
||||||
const ts = Math.floor(new Date());
|
const ts = Math.floor(new Date());
|
||||||
|
|
||||||
const locales = readLocales();
|
const locales = readLocales();
|
||||||
|
const icons = readSvgSprite();
|
||||||
|
|
||||||
const tmpl = mustache({
|
const tmpl = mustache({
|
||||||
ts: ts,
|
ts: ts,
|
||||||
|
ic: icons,
|
||||||
tr: JSON.stringify(locales),
|
tr: JSON.stringify(locales),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -116,30 +122,91 @@ function templatePipeline(options) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
gulp.task("template:main", templatePipeline({
|
/***********************************************
|
||||||
input: paths.app + "templates/index.mustache",
|
* Generic
|
||||||
output: paths.output
|
***********************************************/
|
||||||
|
|
||||||
|
gulp.task("scss:main", scssPipeline({
|
||||||
|
input: paths.resources + "styles/main.scss",
|
||||||
|
output: paths.build + "css/main.css"
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// gulp.task("template:view", templatePipeline({
|
gulp.task("scss", gulp.parallel("scss:main"));
|
||||||
// input: paths.app + "templates/view.mustache",
|
|
||||||
// output: paths.output + "view/"
|
|
||||||
// }));
|
|
||||||
|
|
||||||
gulp.task("templates", gulp.parallel("template:main"));
|
gulp.task("svg:sprite", function() {
|
||||||
|
return gulp.src(paths.resources + "images/icons/*.svg")
|
||||||
|
.pipe(rename({prefix: 'icon-'}))
|
||||||
|
.pipe(svgSprite({mode:{symbol: {inline: true}}}))
|
||||||
|
.pipe(gulp.dest(paths.build + "icons-sprite/"));
|
||||||
|
});
|
||||||
|
|
||||||
// Entry Point
|
gulp.task("template:main", templatePipeline({
|
||||||
|
input: paths.resources + "templates/index.mustache",
|
||||||
|
output: paths.build
|
||||||
|
}));
|
||||||
|
|
||||||
|
gulp.task("templates", gulp.series("svg:sprite", "template:main"));
|
||||||
|
|
||||||
|
/***********************************************
|
||||||
|
* Development
|
||||||
|
***********************************************/
|
||||||
|
|
||||||
|
gulp.task("dev:clean", function(next) {
|
||||||
|
rimraf(paths.output, function() {
|
||||||
|
rimraf(paths.build, next);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("dev:copy:images", function() {
|
||||||
|
return gulp.src(paths.resources + "images/**/*")
|
||||||
|
.pipe(gulp.dest(paths.output + "images/"));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("dev:copy:css", function() {
|
||||||
|
return gulp.src(paths.build + "css/**/*")
|
||||||
|
.pipe(gulp.dest(paths.output + "css/"));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("dev:copy:icons-sprite", function() {
|
||||||
|
return gulp.src(paths.build + "icons-sprite/**/*")
|
||||||
|
.pipe(gulp.dest(paths.output + "icons-sprite/"));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("dev:copy:templates", function() {
|
||||||
|
return gulp.src(paths.build + "index.html")
|
||||||
|
.pipe(gulp.dest(paths.output));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("dev:copy:fonts", function() {
|
||||||
|
return gulp.src(paths.resources + "fonts/**/*")
|
||||||
|
.pipe(gulp.dest(paths.output + "fonts/"));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("dev:copy", gulp.parallel("dev:copy:images",
|
||||||
|
"dev:copy:css",
|
||||||
|
"dev:copy:fonts",
|
||||||
|
"dev:copy:icons-sprite",
|
||||||
|
"dev:copy:templates"));
|
||||||
|
|
||||||
|
gulp.task("dev:dirs", function(next) {
|
||||||
|
mkdirp("./resources/public/css/")
|
||||||
|
.then(() => next())
|
||||||
|
});
|
||||||
|
|
||||||
gulp.task("watch:main", function() {
|
gulp.task("watch:main", function() {
|
||||||
gulp.watch(paths.scss, gulp.task("scss"));
|
gulp.watch(paths.scss, gulp.series("scss", "dev:copy:css"));
|
||||||
gulp.watch([paths.app + "templates/*.mustache",
|
|
||||||
paths.app + "locales.json"],
|
gulp.watch([paths.resources + "templates/*.mustache",
|
||||||
gulp.task("templates"));
|
paths.resources + "locales.json",
|
||||||
|
paths.resources + "images/**/*"],
|
||||||
|
gulp.series("templates", "dev:copy:images", "dev:copy:icons-sprite"));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("watch", gulp.series(
|
gulp.task("watch", gulp.series(
|
||||||
|
"dev:dirs",
|
||||||
gulp.parallel("scss", "templates"),
|
gulp.parallel("scss", "templates"),
|
||||||
gulp.task("watch:main")
|
"dev:copy",
|
||||||
|
"watch:main"
|
||||||
));
|
));
|
||||||
|
|
||||||
/***********************************************
|
/***********************************************
|
||||||
|
@ -147,53 +214,41 @@ gulp.task("watch", gulp.series(
|
||||||
***********************************************/
|
***********************************************/
|
||||||
|
|
||||||
gulp.task("dist:clean", function(next) {
|
gulp.task("dist:clean", function(next) {
|
||||||
rimraf(paths.dist, next);
|
rimraf(paths.dist, function() {
|
||||||
|
rimraf(paths.build, next);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Templates
|
gulp.task("dist:copy:templates", function() {
|
||||||
|
return gulp.src(paths.build + "index.html")
|
||||||
gulp.task("dist:template:main", templatePipeline({
|
.pipe(gulp.dest(paths.dist));
|
||||||
input: paths.app + "templates/index.mustache",
|
|
||||||
output: paths.dist,
|
|
||||||
}));
|
|
||||||
|
|
||||||
// gulp.task("dist:template:view", templatePipeline({
|
|
||||||
// input: paths.app + "view.mustache",
|
|
||||||
// output: paths.dist + "view/",
|
|
||||||
// }));
|
|
||||||
|
|
||||||
gulp.task("dist:templates", gulp.parallel("dist:template:main"));
|
|
||||||
|
|
||||||
// Styles
|
|
||||||
|
|
||||||
gulp.task("dist:scss:main", scssPipeline({
|
|
||||||
input: paths.app + "styles/main.scss",
|
|
||||||
output: paths.dist + "css/"
|
|
||||||
}));
|
|
||||||
|
|
||||||
// gulp.task("dist:scss:view", scssPipeline({
|
|
||||||
// input: paths.app + "styles/view.scss",
|
|
||||||
// output: paths.dist + "css/"
|
|
||||||
// }));
|
|
||||||
|
|
||||||
gulp.task("dist:scss", gulp.parallel("dist:scss:main"));
|
|
||||||
|
|
||||||
// Copy
|
|
||||||
|
|
||||||
gulp.task("dist:copy:fonts", function() {
|
|
||||||
return gulp.src(paths.output + "/fonts/**/*")
|
|
||||||
.pipe(gulp.dest(paths.dist + "fonts/"));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("dist:copy:images", function() {
|
gulp.task("dist:copy:images", function() {
|
||||||
return gulp.src(paths.output + "/images/**/*")
|
return gulp.src(paths.resources + "images/**/*")
|
||||||
.pipe(gulp.dest(paths.dist + "images/"));
|
.pipe(gulp.dest(paths.dist + "images/"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
gulp.task("dist:copy:styles", function() {
|
||||||
|
return gulp.src(paths.build + "css/**/*")
|
||||||
|
.pipe(gulp.dest(paths.dist + "css/"));
|
||||||
|
});
|
||||||
|
|
||||||
gulp.task("dist:copy", gulp.parallel("dist:copy:fonts", "dist:copy:images"));
|
gulp.task("dist:copy:icons-sprite", function() {
|
||||||
|
return gulp.src(paths.build + "icons-sprite/**/*")
|
||||||
|
.pipe(gulp.dest(paths.dist + "icons-sprite/"));
|
||||||
|
});
|
||||||
|
|
||||||
// GZip
|
gulp.task("dist:copy:fonts", function() {
|
||||||
|
return gulp.src(paths.resources + "/fonts/**/*")
|
||||||
|
.pipe(gulp.dest(paths.dist + "fonts/"));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("dist:copy", gulp.parallel("dist:copy:fonts",
|
||||||
|
"dist:copy:icons-sprite",
|
||||||
|
"dist:copy:styles",
|
||||||
|
"dist:copy:templates",
|
||||||
|
"dist:copy:images"));
|
||||||
|
|
||||||
gulp.task("dist:gzip", function() {
|
gulp.task("dist:gzip", function() {
|
||||||
return gulp.src(`${paths.dist}**/!(*.gz|*.br|*.jpg|*.png)`)
|
return gulp.src(`${paths.dist}**/!(*.gz|*.br|*.jpg|*.png)`)
|
||||||
|
@ -201,11 +256,9 @@ gulp.task("dist:gzip", function() {
|
||||||
.pipe(gulp.dest(paths.dist));
|
.pipe(gulp.dest(paths.dist));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Entry Point
|
gulp.task("dist", gulp.series(
|
||||||
|
"dist:clean",
|
||||||
gulp.task("dist", gulp.parallel(
|
"scss",
|
||||||
gulp.task("dist:templates"),
|
"templates",
|
||||||
gulp.task("dist:scss"),
|
"dist:copy"
|
||||||
gulp.task("dist:copy")
|
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
4982
frontend/package-lock.json
generated
Normal file
|
@ -8,21 +8,23 @@
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/uxbox/uxbox"
|
"url": "https://github.com/uxbox/uxbox"
|
||||||
},
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"defaults"
|
||||||
|
],
|
||||||
"scripts": {},
|
"scripts": {},
|
||||||
"devDependencies": {
|
"dependencies": {
|
||||||
|
"autoprefixer": "^9.7.4",
|
||||||
|
"clean-css": "^4.2.3",
|
||||||
"gulp": "4.0.2",
|
"gulp": "4.0.2",
|
||||||
"gulp-autoprefixer": "^7.0.1",
|
|
||||||
"gulp-clean-css": "^4.2.0",
|
|
||||||
"gulp-gzip": "^1.4.2",
|
"gulp-gzip": "^1.4.2",
|
||||||
"gulp-if": "^3.0.0",
|
"gulp-if": "^3.0.0",
|
||||||
"gulp-mustache": "^4.1.2",
|
"gulp-mustache": "^4.1.2",
|
||||||
"gulp-plumber": "^1.2.1",
|
|
||||||
"gulp-rename": "^2.0.0",
|
"gulp-rename": "^2.0.0",
|
||||||
"gulp-sass": "^4.0.2",
|
"gulp-svg-sprite": "^1.5.0",
|
||||||
"rimraf": "^3.0.0"
|
"mkdirp": "^1.0.3",
|
||||||
},
|
"postcss": "^7.0.27",
|
||||||
"dependencies": {
|
"rimraf": "^3.0.0",
|
||||||
"source-map-support": "^0.5.16",
|
"sass": "^1.26.0",
|
||||||
"transformation-matrix": "^2.2.0"
|
"source-map-support": "^0.5.16"
|
||||||
}
|
}
|
||||||
}
|
}
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 114 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 70 KiB |