Merge branch 'develop' of ssh://git.bstly.de:222/_Bastler/partey_workadventure

This commit is contained in:
_Bastler 2022-02-27 14:39:42 +01:00
commit 51719660d9
832 changed files with 836 additions and 5115 deletions

View File

@ -56,6 +56,14 @@ jobs:
ADMIN_URL: "//localhost:80" ADMIN_URL: "//localhost:80"
working-directory: "front" working-directory: "front"
- name: "Build iframe-api"
run: yarn run build-iframe-api
working-directory: "front"
- name: "Typecheck"
run: yarn run typecheck
working-directory: "front"
- name: "Svelte check" - name: "Svelte check"
run: yarn run svelte-check run: yarn run svelte-check
working-directory: "front" working-directory: "front"
@ -165,4 +173,3 @@ jobs:
- name: "Prettier" - name: "Prettier"
run: yarn run pretty-check run: yarn run pretty-check
working-directory: "back" working-directory: "back"

View File

@ -22,31 +22,10 @@ jobs:
run: cat package.json run: cat package.json
working-directory: "front/packages/iframe-api-typings" working-directory: "front/packages/iframe-api-typings"
- name: Install Protoc
uses: arduino/setup-protoc@v1
with:
version: '3.x'
- name: "Install dependencies" - name: "Install dependencies"
run: yarn install run: yarn install
working-directory: "front" working-directory: "front"
- name: "Install messages dependencies"
run: yarn install
working-directory: "messages"
- name: "Build proto messages"
run: yarn run ts-proto && yarn run copy-to-front-ts-proto && yarn run json-copy-to-front
working-directory: "messages"
- name: "Create index.html"
run: ./templater.sh
working-directory: "front"
- name: "Generate i18n files"
run: yarn run typesafe-i18n
working-directory: "front"
- name: "Build" - name: "Build"
run: yarn run build-typings run: yarn run build-typings
env: env:
@ -54,13 +33,6 @@ jobs:
ADMIN_URL: "//localhost:80" ADMIN_URL: "//localhost:80"
working-directory: "front" working-directory: "front"
# We build the front to generate the typings of iframe_api, then we copy those typings in a separate package.
- name: Copy typings to package dir
run: cp front/dist/src/iframe_api.d.ts front/packages/iframe-api-typings/iframe_api.d.ts
- name: Copy typings to package dir (2)
run: cp -R front/dist/src/Api front/packages/iframe-api-typings/Api
- name: Install dependencies in package - name: Install dependencies in package
run: yarn install run: yarn install
working-directory: "front/packages/iframe-api-typings" working-directory: "front/packages/iframe-api-typings"

1
.gitignore vendored
View File

@ -4,7 +4,6 @@
.vscode .vscode
Vagrantfile Vagrantfile
docker-compose.override.yaml docker-compose.override.yaml
docker-compose.prod.yaml
*.DS_Store *.DS_Store
maps/yarn.lock maps/yarn.lock
maps/dist/computer.js maps/dist/computer.js

View File

@ -1,8 +1,10 @@
# protobuf build # protobuf build
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as messages FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as messages
WORKDIR /usr/src WORKDIR /usr/src
COPY messages/yarn.lock messages/package.json ./
RUN yarn install
COPY messages . COPY messages .
RUN yarn install && yarn proto RUN yarn proto
# typescript build # typescript build
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder
@ -18,9 +20,9 @@ RUN yarn run tsc
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d
WORKDIR /usr/src WORKDIR /usr/src
COPY back/yarn.lock back/package.json ./ COPY back/yarn.lock back/package.json ./
COPY --from=builder /usr/src/dist /usr/src/dist
ENV NODE_ENV=production ENV NODE_ENV=production
RUN yarn install --production RUN yarn install --production
COPY --from=builder /usr/src/dist /usr/src/dist
USER node USER node
CMD ["yarn", "run", "runprod"] CMD ["yarn", "run", "runprod"]

View File

@ -53,7 +53,7 @@ class MapFetcher {
const resolver = new Resolver(); const resolver = new Resolver();
addresses = await promisify(resolver.resolve).bind(resolver)(urlObj.hostname); addresses = await promisify(resolver.resolve).bind(resolver)(urlObj.hostname);
} else { } else {
addresses = [ urlObj.hostname ]; addresses = [urlObj.hostname];
} }
for (const address of addresses) { for (const address of addresses) {

View File

@ -1,89 +0,0 @@
version: "3.3"
services:
reverse-proxy:
image: traefik:v2.5
command:
- --log.level=WARN
- --providers.docker
- --entryPoints.web.address=:80
ports:
- "9999:80" # port is used to proxy through apache with ssl
depends_on:
- pusher
- front
volumes:
- /var/run/docker.sock:/var/run/docker.sock
front:
build:
context: ./
dockerfile: front/Dockerfile
args:
DEBUG_MODE: "$DEBUG_MODE"
JITSI_URL: $JITSI_URL
JITSI_PRIVATE_MODE: "$JITSI_PRIVATE_MODE"
PUSHER_URL: /pusher
ADMIN_URL: /admin # this is only set to avoid compiling errors, currently not used otherways
TURN_SERVER: "${TURN_SERVER}"
TURN_USER: "${TURN_USER}"
TURN_PASSWORD: "${TURN_PASSWORD}"
MAX_PER_GROUP: "${MAX_PER_GROUP}"
MAX_USERNAME_LENGTH: "${MAX_USERNAME_LENGTH}"
START_ROOM_URL: "${START_ROOM_URL}"
DISABLE_NOTIFICATIONS: "${DISABLE_NOTIFICATIONS}"
SKIP_RENDER_OPTIMIZATIONS: "${SKIP_RENDER_OPTIMIZATIONS}"
labels:
- "traefik.http.routers.front.rule=PathPrefix(`/`)"
- "traefik.http.routers.front.entryPoints=web"
- "traefik.http.services.front.loadbalancer.server.port=80"
- "traefik.http.routers.front.service=front"
pusher:
build:
context: ./
dockerfile: pusher/Dockerfile
environment:
SECRET_JITSI_KEY: "${SECRET_JITSI_KEY}"
SECRET_KEY: ${SECRET_KEY}
API_URL: back:50051
ADMIN_API_URL: "${ADMIN_API_URL}"
ADMIN_API_TOKEN: "${ADMIN_API_TOKEN}"
JITSI_URL: ${JITSI_URL}
JITSI_ISS: ${JITSI_ISS}
FRONT_URL : ${FRONT_URL}
OPID_CLIENT_ID: ${OPID_CLIENT_ID}
OPID_CLIENT_SECRET: ${OPID_CLIENT_SECRET}
OPID_CLIENT_ISSUER: ${OPID_CLIENT_ISSUER}
labels:
- "traefik.http.middlewares.strip-pusher-prefix.stripprefix.prefixes=/pusher"
- "traefik.http.routers.pusher.rule=PathPrefix(`/pusher`)"
- "traefik.http.routers.pusher.middlewares=strip-pusher-prefix@docker"
- "traefik.http.routers.pusher.entryPoints=web"
- "traefik.http.services.pusher.loadbalancer.server.port=8080"
- "traefik.http.routers.pusher.service=pusher"
back:
build:
context: ./
dockerfile: back/Dockerfile
environment:
SECRET_KEY: ${SECRET_KEY}
STARTUP_COMMAND_1: yarn install
SECRET_JITSI_KEY: "${SECRET_JITSI_KEY}"
ADMIN_API_TOKEN: "${ADMIN_API_TOKEN}"
ADMIN_API_URL: "${ADMIN_API_URL}"
JITSI_URL: ${JITSI_URL}
JITSI_ISS: ${JITSI_ISS}
MAX_PER_GROUP: ${MAX_PER_GROUP}
TURN_STATIC_AUTH_SECRET: "${TURN_STATIC_AUTH_SECRET}"
REDIS_HOST: redis
labels:
- "traefik.http.middlewares.strip-api-prefix.stripprefix.prefixes=/api"
- "traefik.http.routers.back.rule=PathPrefix(`/api`)"
- "traefik.http.routers.back.middlewares=strip-api-prefix@docker"
- "traefik.http.routers.back.entryPoints=web"
- "traefik.http.services.back.loadbalancer.server.port=8080"
- "traefik.http.routers.back.service=back"
redis:
image: redis:6

View File

@ -9,10 +9,7 @@ services:
build: build:
context: ./ context: ./
dockerfile: front/Dockerfile dockerfile: front/Dockerfile
environment: command: /bin/sh -c "/templater.sh && envsubst < /usr/share/nginx/html/env-config.template.js > /usr/share/nginx/html/env-config.js && exec nginx -g 'daemon off;'"
STARTUP_COMMAND_1: 'envsubst < dist/env-config.template.js > dist/env-config.js'
STARTUP_COMMAND_2: ''
command: apache2-foreground
volumes: [] volumes: []
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
@ -29,9 +26,6 @@ services:
build: build:
context: ./ context: ./
dockerfile: pusher/Dockerfile dockerfile: pusher/Dockerfile
environment:
STARTUP_COMMAND_1: ''
STARTUP_COMMAND_2: ''
command: yarn run runprod command: yarn run runprod
volumes: [] volumes: []
@ -40,8 +34,5 @@ services:
build: build:
context: ./ context: ./
dockerfile: back/Dockerfile dockerfile: back/Dockerfile
environment:
STARTUP_COMMAND_1: ''
STARTUP_COMMAND_2: ''
command: yarn run runprod command: yarn run runprod
volumes: [] volumes: []

141
docker-compose.prod.yaml Normal file
View File

@ -0,0 +1,141 @@
version: "3.3"
services:
reverse-proxy:
image: traefik:v2.5.2
command:
- --log.level=WARN
- --providers.docker
- --entryPoints.web.address=:80
ports:
- "9999:80"
depends_on:
- pusher
- front
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: ${RESTART_POLICY}
front:
build:
context: ./
dockerfile: front/Dockerfile
environment:
DEBUG_MODE: "$DEBUG_MODE"
START_ROOM_URL: "${START_ROOM_URL}"
PUSHER_URL: /pusher
ADMIN_URL: /admin
UPLOADER_URL: /uploader
ICON_URL: /icon
STUN_SERVER: "$STUN_SERVER"
TURN_SERVER: "${TURN_SERVER}"
SKIP_RENDER_OPTIMIZATIONS: "${SKIP_RENDER_OPTIMIZATIONS}"
DISABLE_NOTIFICATIONS: "${DISABLE_NOTIFICATIONS}"
TURN_USER: "${TURN_USER}"
TURN_PASSWORD: "${TURN_PASSWORD}"
JITSI_URL: $JITSI_URL
JITSI_PRIVATE_MODE: "$JITSI_PRIVATE_MODE"
MAX_USERNAME_LENGTH: "${MAX_USERNAME_LENGTH}"
MAX_PER_GROUP: "${MAX_PER_GROUP}"
DISPLAY_TERMS_OF_USE: "$DISPLAY_TERMS_OF_USE"
CONTACT_URL: "${PROFILE_URL}"
PROFILE_URL: "${PROFILE_URL}"
DISABLE_ANONYMOUS: "$DISABLE_ANONYMOUS"
OPID_LOGIN_SCREEN_PROVIDER: "$OPID_LOGIN_SCREEN_PROVIDER"
FALLBACK_LOCALE: "${FALLBACK_LOCALE}"
labels:
- "traefik.http.routers.front.rule=PathPrefix(`/`)"
- "traefik.http.routers.front.entryPoints=web"
- "traefik.http.services.front.loadbalancer.server.port=80"
- "traefik.http.routers.front.service=front"
restart: ${RESTART_POLICY}
pusher:
build:
context: ./
dockerfile: pusher/Dockerfile
environment:
SECRET_KEY: ${SECRET_KEY}
ALLOW_ARTILLERY: "$ALLOW_ARTILLERY"
API_URL: back:50051
ADMIN_API_URL: "${ADMIN_API_URL}"
ADMIN_URL: "${ADMIN_URL}"
ADMIN_API_TOKEN: "${ADMIN_API_TOKEN}"
ADMIN_SOCKETS_TOKEN: "${ADMIN_SOCKETS_TOKEN}"
CPU_OVERHEAT_THRESHOLD: $CPU_OVERHEAT_THRESHOLD
JITSI_URL: ${JITSI_URL}
JITSI_ISS: ${JITSI_ISS}
SECRET_JITSI_KEY: "${SECRET_JITSI_KEY}"
PUSHER_HTTP_PORT: "$PUSHER_HTTP_PORT"
SOCKET_IDLE_TIMER: "$SOCKET_IDLE_TIMER"
PUSHER_FORCE_ROOM_UPDATE : $PUSHER_FORCE_ROOM_UPDATE
FRONT_URL : $FRONT_URL
OPID_CLIENT_ID: $OPID_CLIENT_ID
OPID_CLIENT_SECRET: $OPID_CLIENT_SECRET
OPID_CLIENT_ISSUER: $OPID_CLIENT_ISSUER
OPID_CLIENT_REDIRECT_URL: $OPID_CLIENT_REDIRECT_URL
OPID_PROFILE_SCREEN_PROVIDER: $OPID_PROFILE_SCREEN_PROVIDER
OPID_ADDITIONAL_SCOPES: $OPID_ADDITIONAL_SCOPES
OPID_USERNAME_CLAIM: $OPID_USERNAME_CLAIM
OPID_LOCALE_CLAIM: $OPID_LOCALE_CLAIM
DISABLE_ANONYMOUS: $DISABLE_ANONYMOUS
labels:
- "traefik.http.middlewares.strip-pusher-prefix.stripprefix.prefixes=/pusher"
- "traefik.http.routers.pusher.rule=PathPrefix(`/pusher`)"
- "traefik.http.routers.pusher.middlewares=strip-pusher-prefix@docker"
- "traefik.http.routers.pusher.entryPoints=web"
- "traefik.http.services.pusher.loadbalancer.server.port=8080"
- "traefik.http.routers.pusher.service=pusher"
restart: ${RESTART_POLICY}
back:
build:
context: ./
dockerfile: back/Dockerfile
environment:
MINIMUM_DISTANCE: $MINIMUM_DISTANCE
GROUP_RADIUS: $GROUP_RADIUS
ALLOW_ARTILLERY: "$ALLOW_ARTILLERY"
ADMIN_API_URL: "${ADMIN_API_URL}"
ADMIN_API_TOKEN: "${ADMIN_API_TOKEN}"
CPU_OVERHEAT_THRESHOLD: $CPU_OVERHEAT_THRESHOLD
JITSI_URL: ${JITSI_URL}
JITSI_ISS: ${JITSI_ISS}
SECRET_JITSI_KEY: "${SECRET_JITSI_KEY}"
HTTP_PORT: "$HTTP_PORT"
GRPC_PORT: "$GRPC_PORT"
TURN_STATIC_AUTH_SECRET: "${TURN_STATIC_AUTH_SECRET}"
MAX_PER_GROUP: ${MAX_PER_GROUP}
REDIS_HOST: redis
REDIS_PORT: "$REDIS_PORT"
REDIS_PASSWORD: $REDIS_PASSWORD
STORE_VARIABLES_FOR_LOCAL_MAPS: "$STORE_VARIABLES_FOR_LOCAL_MAPS"
labels:
- "traefik.http.middlewares.strip-api-prefix.stripprefix.prefixes=/api"
- "traefik.http.routers.back.rule=PathPrefix(`/api`)"
- "traefik.http.routers.back.middlewares=strip-api-prefix@docker"
- "traefik.http.routers.back.entryPoints=web"
- "traefik.http.services.back.loadbalancer.server.port=8080"
- "traefik.http.routers.back.service=back"
restart: ${RESTART_POLICY}
redis:
image: redis:6
restart: ${RESTART_POLICY}
icon:
image: matthiasluedtke/iconserver:v3.13.0
environment:
DISABLE_BROWSE_PAGES: "true"
METRICS_PATH: "disable"
SERVER_MODE: "download"
labels:
- "traefik.http.middlewares.strip-icon-prefix.stripprefix.prefixes=/icon"
- "traefik.http.routers.icon.rule=PathPrefix(`/icon`)"
- "traefik.http.routers.icon.middlewares=strip-icon-prefix@docker"
- "traefik.http.routers.icon.entryPoints=web"
- "traefik.http.services.icon.loadbalancer.server.port=8080"
- "traefik.http.routers.icon.service=icon"
restart: ${RESTART_POLICY}

View File

@ -52,7 +52,6 @@ services:
MAX_USERNAME_LENGTH: "$MAX_USERNAME_LENGTH" MAX_USERNAME_LENGTH: "$MAX_USERNAME_LENGTH"
DISABLE_ANONYMOUS: "$DISABLE_ANONYMOUS" DISABLE_ANONYMOUS: "$DISABLE_ANONYMOUS"
OPID_LOGIN_SCREEN_PROVIDER: "$OPID_LOGIN_SCREEN_PROVIDER" OPID_LOGIN_SCREEN_PROVIDER: "$OPID_LOGIN_SCREEN_PROVIDER"
LIVE_RELOAD: "$LIVE_RELOAD:-true"
command: yarn run start command: yarn run start
volumes: volumes:
- ./front:/usr/src/app - ./front:/usr/src/app

View File

@ -9,9 +9,11 @@ On your map, you can define special zones (meeting rooms) that will trigger the
In order to create Jitsi meet zones: In order to create Jitsi meet zones:
* You must create a specific layer. * You must create a specific layer.
* In layer properties, you MUST add a "`jitsiRoom`" property (of type "`string`"). The value of the property is the name of the room in Jitsi. Note: the name of the room will be "slugified" and prepended with the name of the instance of the map (so that different instances of the map have different rooms) * In layer properties, you MUST add a "`jitsiRoom`" property (of type "`string`"). The value of the property is the name of the room in Jitsi. Note: the name of the room will be "slugified" and prepended with the name of the instance of the map (so that different instances of the map have different rooms)
* You may also use "jitsiWidth" property (of type "number" between 0 and 100) to control the width of the iframe containing the meeting room. * You may also use "jitsiWidth" property (of type "number" between 0 and 100) to control the width of the iframe containing the meeting room.
You can have this layer (i.e. your meeting area) to be selectable as the precise location for your meeting using the [Google Calendar integration for Work Adventure](/integrations/google-calendar). To do so, you must set the `meetingRoomLabel` property. You can provide any name that you would like your meeting room to have (as a string).
## Triggering of the "Jitsi meet" action ## Triggering of the "Jitsi meet" action

13
front/.gitignore vendored
View File

@ -1,16 +1,7 @@
/node_modules/ /node_modules/
/dist/*.js dist/
/dist/*.js.map
/dist/*.js.LICENSE.txt
/dist/main.*.css
/dist/main.*.css.map
/dist/tests/
/yarn-error.log /yarn-error.log
/package-lock.json /package-lock.json
/dist/webpack.config.js
/dist/webpack.config.js.map
/dist/src
/dist/fonts
/dist/*.png
*.sh *.sh
!templater.sh !templater.sh
/public/iframe_api.js

View File

@ -1,72 +1,27 @@
# protobuf build # protobuf build
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as messages FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as messages
WORKDIR /usr/src WORKDIR /usr/src
COPY messages/yarn.lock messages/package.json ./
RUN yarn install
COPY messages . COPY messages .
RUN yarn install && yarn ts-proto RUN yarn ts-proto
# typescript build
# webpack build
FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder FROM node:14.18.2-buster-slim@sha256:20bedf0c09de887379e59a41c04284974f5fb529cf0e13aab613473ce298da3d as builder
WORKDIR /usr/src WORKDIR /usr/src
COPY front/yarn.lock front/package.json ./ COPY front/yarn.lock front/package.json ./
RUN yarn install --ignore-engines RUN yarn install
COPY front . COPY front .
COPY --from=messages /usr/src/ts-proto-generated/protos src/Messages/ts-proto-generated COPY --from=messages /usr/src/ts-proto-generated/protos src/Messages/ts-proto-generated
RUN sed -i 's/import { Observable } from "rxjs";/import type { Observable } from "rxjs";/g' src/Messages/ts-proto-generated/messages.ts RUN sed -i 's/import { Observable } from "rxjs";/import type { Observable } from "rxjs";/g' src/Messages/ts-proto-generated/messages.ts
COPY --from=messages /usr/src/JsonMessages src/Messages/JsonMessages COPY --from=messages /usr/src/JsonMessages src/Messages/JsonMessages
RUN yarn run typesafe-i18n && yarn run build-iframe-api && yarn build
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
&& apt-get install -y \
gettext-base
RUN rm dist/iframe.html
RUN yarn run typesafe-i18n
RUN yarn run build
RUN ./templater.sh
# passing arguments as environment
ARG DEBUG_MODE
ARG JITSI_URL
ARG JITSI_PRIVATE_MODE
ARG PUSHER_URL
ARG ICON_URL
ARG ADMIN_URL
ARG STUN_SERVER
ARG TURN_SERVER
ARG TURN_USER
ARG TURN_PASSWORD
ARG MAX_PER_GROUP
ARG MAX_USERNAME_LENGTH
ARG PROFILE_URL
ARG START_ROOM_URL
ARG DISABLE_NOTIFICATIONS
ARG SKIP_RENDER_OPTIMIZATIONS
ARG OPID_LOGIN_SCREEN_PROVIDER
ENV DEBUG_MODE=$DEBUG_MODE
ENV JITSI_URL=$JITSI_URL
ENV JITSI_PRIVATE_MODE=$JITSI_PRIVATE_MODE
ENV PUSHER_URL=$PUSHER_URL
ENV ICON_URL=$ICON_URL
ENV ADMIN_URL=$ADMIN_URL
ENV STUN_SERVER=$STUN_SERVER
ENV TURN_SERVER=$TURN_SERVER
ENV TURN_USER=$TURN_USER
ENV TURN_PASSWORD=$TURN_PASSWORD
ENV MAX_PER_GROUP=$MAX_PER_GROUP
ENV MAX_USERNAME_LENGTH=$MAX_USERNAME_LENGTH
ENV PROFILE_URL=$PROFILE_URL
ENV START_ROOM_URL=$START_ROOM_URL
ENV DISABLE_NOTIFICATIONS=$DISABLE_NOTIFICATIONS
ENV SKIP_RENDER_OPTIMIZATIONS=$SKIP_RENDER_OPTIMIZATIONS
ENV OPID_LOGIN_SCREEN_PROVIDER=$OPID_LOGIN_SCREEN_PROVIDER
RUN envsubst < dist/env-config.template.js > dist/env-config.js
# final production image # final production image
FROM nginx:mainline-alpine FROM nginx:mainline-alpine
COPY front/nginx-vhost.conf /etc/nginx/conf.d/default.conf
COPY front/nginx.conf /etc/nginx/conf.d/default.conf
COPY front/templater.sh /
COPY --from=builder /usr/src/dist /usr/share/nginx/html COPY --from=builder /usr/src/dist /usr/share/nginx/html
RUN cat /usr/share/nginx/html/env-config.js
CMD ["/bin/sh", "-c", "/templater.sh && envsubst < /usr/share/nginx/html/env-config.template.js > /usr/share/nginx/html/env-config.js && exec nginx -g 'daemon off;'"]

View File

@ -1,7 +0,0 @@
index.html
/js/
/fonts/
style.*.css
!env-config.template.js
*.png
!/resources/**

View File

@ -1,27 +0,0 @@
window.env = {
SKIP_RENDER_OPTIMIZATIONS: '${SKIP_RENDER_OPTIMIZATIONS}',
DISABLE_NOTIFICATIONS: '${DISABLE_NOTIFICATIONS}',
PUSHER_URL: '${PUSHER_URL}',
UPLOADER_URL: '${UPLOADER_URL}',
ADMIN_URL: '${ADMIN_URL}',
CONTACT_URL: '${CONTACT_URL}',
PROFILE_URL: '${PROFILE_URL}',
ICON_URL: '${ICON_URL}',
DEBUG_MODE: '${DEBUG_MODE}',
STUN_SERVER: '${STUN_SERVER}',
TURN_SERVER: '${TURN_SERVER}',
TURN_USER: '${TURN_USER}',
TURN_PASSWORD: '${TURN_PASSWORD}',
JITSI_URL: '${JITSI_URL}',
JITSI_PRIVATE_MODE: '${JITSI_PRIVATE_MODE}',
START_ROOM_URL: '${START_ROOM_URL}',
MAX_USERNAME_LENGTH: '${MAX_USERNAME_LENGTH}',
MAX_PER_GROUP: '${MAX_PER_GROUP}',
DISPLAY_TERMS_OF_USE: '${DISPLAY_TERMS_OF_USE}',
POSTHOG_API_KEY: '${POSTHOG_API_KEY}',
POSTHOG_URL: '${POSTHOG_URL}',
NODE_ENV: '${NODE_ENV}',
DISABLE_ANONYMOUS: '${DISABLE_ANONYMOUS}',
OPID_LOGIN_SCREEN_PROVIDER: '${OPID_LOGIN_SCREEN_PROVIDER}',
FALLBACK_LOCALE: '${FALLBACK_LOCALE}',
};

View File

@ -1,22 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<script src="/iframe_api.js" ></script>
<script>
// Note: this is a huge XSS flow as we allow anyone to load a Javascript file in our domain.
// This file must ABSOLUTELY be removed from the Docker images/deployments and is only here
// for development purpose (because dynamically generated iframes are not working with
// webpack hot reload due to an issue with rights)
const urlParams = new URLSearchParams(window.location.search);
const scriptUrl = urlParams.get('script');
const script = document.createElement('script');
script.type = "module";
script.src = scriptUrl;
if (urlParams.get('moduleMode') === 'true') {
script.type = "module";
}
document.head.append(script);
</script>
</head>
</html>

View File

@ -1,5 +0,0 @@
/*This file is a workaround to allow phaser to load directly this font */
@font-face {
font-family: "Press Start 2P";
src: url("/fonts/press-start-2p-latin-400-normal.woff2") format('woff2');
}

View File

@ -1,49 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="452.388px" height="452.388px" viewBox="0 0 452.388 452.388" style="enable-background:new 0 0 452.388 452.388;"
xml:space="preserve">
<g>
<g id="Layer_8_38_">
<path d="M441.677,43.643H10.687C4.785,43.643,0,48.427,0,54.329v297.425c0,5.898,4.785,10.676,10.687,10.676h162.069v25.631
c0,0.38,0.074,0.722,0.112,1.089h-23.257c-5.407,0-9.796,4.389-9.796,9.795c0,5.408,4.389,9.801,9.796,9.801h158.506
c5.406,0,9.795-4.389,9.795-9.801c0-5.406-4.389-9.795-9.795-9.795h-23.256c0.032-0.355,0.115-0.709,0.115-1.089V362.43H441.7
c5.898,0,10.688-4.782,10.688-10.676V54.329C452.37,48.427,447.589,43.643,441.677,43.643z M422.089,305.133
c0,5.903-4.784,10.687-10.683,10.687H40.96c-5.898,0-10.684-4.783-10.684-10.687V79.615c0-5.898,4.786-10.684,10.684-10.684
h370.446c5.898,0,10.683,4.785,10.683,10.684V305.133z M303.942,290.648H154.025c0-29.872,17.472-55.661,42.753-67.706
c-15.987-10.501-26.546-28.571-26.546-49.13c0-32.449,26.306-58.755,58.755-58.755c32.448,0,58.753,26.307,58.753,58.755
c0,20.553-10.562,38.629-26.545,49.13C286.475,234.987,303.942,260.781,303.942,290.648z"/>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,16 @@
import { defineConfig } from "vite";
import { resolve } from "path";
export default defineConfig({
publicDir: false,
build: {
outDir: "public",
emptyOutDir: false,
lib: {
entry: resolve(__dirname, "src/iframe_api.ts"),
name: "iframe_api",
formats: ["cjs"],
fileName: () => "iframe_api.js",
},
},
});

View File

@ -27,8 +27,8 @@
<meta name="msapplication-TileImage" content="static/images/favicons/ms-icon-144x144.png"> <meta name="msapplication-TileImage" content="static/images/favicons/ms-icon-144x144.png">
<meta name="theme-color" content="#000000"> <meta name="theme-color" content="#000000">
<script src="/env-config.js"></script>
<base href="/"> <base href="/">
<style>/*hide cowebsite container before scss is loaded*/#cowebsite { visibility: collapse };</style>
<title>Partey</title> <title>Partey</title>
</head> </head>
@ -63,5 +63,6 @@
</div> </div>
<div id="cowebsite-buffer"></div> <div id="cowebsite-buffer"></div>
</div> </div>
<script type="module" src="/src/index.ts"></script>
</body> </body>
</html> </html>

View File

@ -1,13 +0,0 @@
server {
listen 80;
listen [::]:80;
server_name localhost;
access_log off;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}

48
front/nginx.conf Normal file
View File

@ -0,0 +1,48 @@
server {
listen 80;
listen [::]:80;
server_name localhost;
access_log off;
gzip on;
gzip_comp_level 6;
gzip_min_length 1000;
gzip_proxied any;
gzip_disable "msie6";
gzip_types
application/atom+xml
application/geo+json
application/javascript
application/x-javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/xhtml+xml
application/xml
font/eot
font/otf
font/ttf
image/svg+xml
text/css
text/javascript
text/plain
text/xml;
# serve static assets (that have a cache busting hash) with an efficient cache policy
location /assets {
root /usr/share/nginx/html;
expires 1y;
add_header Cache-Control "public";
}
location / {
root /usr/share/nginx/html;
index index.html;
}
location ~ ^/[@_]/ {
try_files $uri $uri/ /index.html;
}
}

View File

@ -4,42 +4,32 @@
"main": "index.js", "main": "index.js",
"license": "SEE LICENSE IN LICENSE.txt", "license": "SEE LICENSE IN LICENSE.txt",
"devDependencies": { "devDependencies": {
"@geprog/vite-plugin-env-config": "^4.0.0",
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.36",
"@tsconfig/svelte": "^1.0.10", "@tsconfig/svelte": "^1.0.10",
"@types/google-protobuf": "^3.7.3", "@types/google-protobuf": "^3.7.3",
"@types/jasmine": "^3.5.10", "@types/jasmine": "^3.5.10",
"@types/mini-css-extract-plugin": "^1.4.3",
"@types/node": "^15.3.0", "@types/node": "^15.3.0",
"@types/quill": "^1.3.7", "@types/quill": "^1.3.7",
"@types/uuidv4": "^5.0.0", "@types/uuidv4": "^5.0.0",
"@types/webpack-dev-server": "^3.11.4",
"@typescript-eslint/eslint-plugin": "^5.6.0", "@typescript-eslint/eslint-plugin": "^5.6.0",
"@typescript-eslint/parser": "^5.6.0", "@typescript-eslint/parser": "^5.6.0",
"css-loader": "^5.2.4",
"css-minimizer-webpack-plugin": "^3.3.1",
"eslint": "^8.4.1", "eslint": "^8.4.1",
"eslint-plugin-svelte3": "^3.2.1", "eslint-plugin-svelte3": "^3.2.1",
"fork-ts-checker-webpack-plugin": "^6.5.0",
"html-webpack-plugin": "^5.3.1",
"jasmine": "^3.5.0", "jasmine": "^3.5.0",
"lint-staged": "^11.0.0", "lint-staged": "^11.0.0",
"mini-css-extract-plugin": "^1.6.0",
"node-polyfill-webpack-plugin": "^1.1.2",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prettier": "^2.3.1", "prettier": "^2.3.1",
"prettier-plugin-svelte": "^2.5.0", "prettier-plugin-svelte": "^2.5.0",
"sass": "^1.32.12", "sass": "^1.49.7",
"sass-loader": "^11.1.0", "svelte": "^3.46.3",
"svelte": "^3.38.2",
"svelte-check": "^2.1.0", "svelte-check": "^2.1.0",
"svelte-loader": "^3.1.1", "svelte-preprocess": "^4.10.2",
"svelte-preprocess": "^4.7.3",
"ts-loader": "^9.2.6",
"ts-node": "^10.4.0", "ts-node": "^10.4.0",
"tsconfig-paths": "^3.9.0", "tsconfig-paths": "^3.9.0",
"typescript": "^4.5.3", "typescript": "^4.5.3",
"webpack": "^5.37.0", "vite": "^2.7.13",
"webpack-cli": "^4.7.0", "vite-plugin-rewrite-all": "^0.1.2"
"webpack-dev-server": "^3.11.2"
}, },
"dependencies": { "dependencies": {
"@16bits/nes.css": "^2.3.2", "@16bits/nes.css": "^2.3.2",
@ -48,13 +38,14 @@
"@types/simple-peer": "^9.11.1", "@types/simple-peer": "^9.11.1",
"@types/socket.io-client": "^1.4.32", "@types/socket.io-client": "^1.4.32",
"axios": "^0.21.2", "axios": "^0.21.2",
"buffer": "^6.0.3",
"cancelable-promise": "^4.2.1", "cancelable-promise": "^4.2.1",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"deep-copy-ts": "^0.5.0", "deep-copy-ts": "^0.5.0",
"dompurify" : "^2.3.6",
"easystarjs": "^0.4.4", "easystarjs": "^0.4.4",
"generic-type-guard": "^3.2.0", "generic-type-guard": "^3.4.2",
"google-protobuf": "^3.13.0", "google-protobuf": "^3.13.0",
"nes.css": "^2.3.0",
"phaser": "^3.54.0", "phaser": "^3.54.0",
"phaser-animated-tiles": "workadventure/phaser-animated-tiles#da68bbededd605925621dd4f03bd27e69284b254", "phaser-animated-tiles": "workadventure/phaser-animated-tiles#da68bbededd605925621dd4f03bd27e69284b254",
"phaser3-rex-plugins": "^1.1.42", "phaser3-rex-plugins": "^1.1.42",
@ -64,7 +55,6 @@
"quill-delta-to-html": "^0.12.0", "quill-delta-to-html": "^0.12.0",
"retry-axios": "^2.6.0", "retry-axios": "^2.6.0",
"rxjs": "^6.6.3", "rxjs": "^6.6.3",
"sanitize-html": "^2.5.0",
"simple-peer": "^9.11.0", "simple-peer": "^9.11.0",
"socket.io-client": "^2.3.0", "socket.io-client": "^2.3.0",
"standardized-audio-context": "^25.2.4", "standardized-audio-context": "^25.2.4",
@ -74,11 +64,13 @@
"zod": "^3.11.6" "zod": "^3.11.6"
}, },
"scripts": { "scripts": {
"start": "run-p templater serve svelte-check-watch typesafe-i18n-watch", "start": "run-p templater serve watch-iframe-api svelte-check-watch typesafe-i18n-watch",
"templater": "cross-env ./templater.sh", "templater": "cross-env ./templater.sh",
"serve": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack.json\" webpack serve --open", "serve": "cross-env vite --host",
"build": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack.json\" NODE_ENV=production webpack", "build": "cross-env vite build",
"build-typings": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack.json\" NODE_ENV=production BUILD_TYPINGS=1 webpack", "build-iframe-api": "vite --config iframe-api.vite.config.ts build",
"watch-iframe-api": "yarn run build-iframe-api --watch",
"build-typings": "cross-env tsc --project tsconfig-for-iframe-api-typings.json",
"test": "cross-env TS_NODE_PROJECT=\"tsconfig-for-jasmine.json\" ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json", "test": "cross-env TS_NODE_PROJECT=\"tsconfig-for-jasmine.json\" ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json",
"lint": "node_modules/.bin/eslint src/ tests/ --ext .ts,.svelte", "lint": "node_modules/.bin/eslint src/ tests/ --ext .ts,.svelte",
"fix": "node_modules/.bin/eslint --fix src/ tests/ --ext .ts,.svelte", "fix": "node_modules/.bin/eslint --fix src/ tests/ --ext .ts,.svelte",
@ -87,6 +79,7 @@
"svelte-check": "svelte-check --fail-on-warnings --fail-on-hints --compiler-warnings \"a11y-no-onchange:ignore,a11y-autofocus:ignore,a11y-media-has-caption:ignore\"", "svelte-check": "svelte-check --fail-on-warnings --fail-on-hints --compiler-warnings \"a11y-no-onchange:ignore,a11y-autofocus:ignore,a11y-media-has-caption:ignore\"",
"pretty": "yarn prettier --write 'src/**/*.{ts,svelte}'", "pretty": "yarn prettier --write 'src/**/*.{ts,svelte}'",
"pretty-check": "yarn prettier --check 'src/**/*.{ts,svelte}'", "pretty-check": "yarn prettier --check 'src/**/*.{ts,svelte}'",
"typecheck": "tsc --noEmit",
"typesafe-i18n": "typesafe-i18n --no-watch", "typesafe-i18n": "typesafe-i18n --no-watch",
"typesafe-i18n-watch": "typesafe-i18n" "typesafe-i18n-watch": "typesafe-i18n"
}, },

View File

@ -1 +1 @@
iframe_api.d.ts *.d.ts

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 779 B

After

Width:  |  Height:  |  Size: 779 B

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

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