Compare commits
3 commits
24c65543cc
...
7c173d8436
| Author | SHA1 | Date | |
|---|---|---|---|
| 7c173d8436 | |||
| 62779a783d | |||
| acbfed004d |
16 changed files with 28266 additions and 22 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "godot"]
|
||||||
|
path = godot
|
||||||
|
url = ../xrforge-godot.git
|
||||||
1
godot
Submodule
1
godot
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 79e8669ca609782aa6fa9eeed259d9621697f460
|
||||||
|
|
@ -51,7 +51,10 @@ $ manyfold/cli/manyfold run -v ./experiences:/mnt/experiences
|
||||||
| `APPNAME` | `manyfold` | manyfold instance name |
|
| `APPNAME` | `manyfold` | manyfold instance name |
|
||||||
| `HOMEPAGE` | `/models` | show '/models' URL as homepage (use `/` for manyfold default) |
|
| `HOMEPAGE` | `/models` | show '/models' URL as homepage (use `/` for manyfold default) |
|
||||||
| `THEME` | `default` | bootstrap theme |
|
| `THEME` | `default` | bootstrap theme |
|
||||||
|
| `GODOT_VERSION` | `4.4.1-stable`| godot editor version |
|
||||||
|
| `GODOT_TEMPLATE_ZIP` | `` | godot template zip URL or file (default is empty godot project) |
|
||||||
| `RUNTESTS` | `0` | set to `1` to run XRForge related [/test](test) scripts |
|
| `RUNTESTS` | `0` | set to `1` to run XRForge related [/test](test) scripts |
|
||||||
|
| `DEV` | `` | enable development mode (disables caching, sets `bin/dev` as entrypoint) |
|
||||||
| `NO_PUBLIC_ONLY` | `` | disable public only models |
|
| `NO_PUBLIC_ONLY` | `` | disable public only models |
|
||||||
| `NO_OVERLAYFS` | `` | disable the filesystem overlay mechanism |
|
| `NO_OVERLAYFS` | `` | disable the filesystem overlay mechanism |
|
||||||
| `NO_DEFAULTDB` | `` | disable the default xrforge db (activates manyfold installer) |
|
| `NO_DEFAULTDB` | `` | disable the default xrforge db (activates manyfold installer) |
|
||||||
|
|
@ -60,7 +63,8 @@ $ manyfold/cli/manyfold run -v ./experiences:/mnt/experiences
|
||||||
| `NO_PACKAGEALL` | `` | don't package all experiences every hour to /usr/src/app/public/experiences.zip |
|
| `NO_PACKAGEALL` | `` | don't package all experiences every hour to /usr/src/app/public/experiences.zip |
|
||||||
| `RCLONE_REMOTE` | `` | specify **single** rclone remote name (without semicolon) to mount (default: mount all rclone remotes)|
|
| `RCLONE_REMOTE` | `` | specify **single** rclone remote name (without semicolon) to mount (default: mount all rclone remotes)|
|
||||||
| `UPLOAD_PATH` | `/mnt/experiences`| specify default library where user-files are uploaded (regular dir or mounted rclone path) |
|
| `UPLOAD_PATH` | `/mnt/experiences`| specify default library where user-files are uploaded (regular dir or mounted rclone path) |
|
||||||
| `FEDERATE_DRIVE_PATH` | `/mnt/experiences`| serve path over HTTP (so other instances can add it as a remote). Specify `0` to disable |
|
| `FEDERATE_DRIVE_HOST` | `http://localhost:3215` | host adress which other hosts can use to access the federate drive |
|
||||||
|
| `FEDERATE_DRIVE_PATH` | `/mnt` | serve path over HTTP (so other instances can add it as a remote). Specify `0` to disable |
|
||||||
| `FEDERATE_DRIVE_PORT` | `3215` | specify default library where user-files are uploaded (regular dir or mounted rclone path) |
|
| `FEDERATE_DRIVE_PORT` | `3215` | specify default library where user-files are uploaded (regular dir or mounted rclone path) |
|
||||||
| `FEDERATE_DRIVE_USER` | `` | specify HTTP AUTH credentials (`user` e.g.) for restricted sharing |
|
| `FEDERATE_DRIVE_USER` | `` | specify HTTP AUTH credentials (`user` e.g.) for restricted sharing |
|
||||||
| `FEDERATE_DRIVE_PW` | `` | specify HTTP AUTH credentials (`pass` e.g.) for restricted sharing |
|
| `FEDERATE_DRIVE_PW` | `` | specify HTTP AUTH credentials (`pass` e.g.) for restricted sharing |
|
||||||
|
|
@ -171,3 +175,12 @@ In theory, federated drives can still be reacted upon, but by integrating with X
|
||||||
|
|
||||||
> Perhaps in the future this will also work for rclone remotes, by writing a `hourly`-script which scans them and fires `inotify_MODIFY` accordingly.
|
> Perhaps in the future this will also work for rclone remotes, by writing a `hourly`-script which scans them and fires `inotify_MODIFY` accordingly.
|
||||||
|
|
||||||
|
# Customization
|
||||||
|
|
||||||
|
See the [manyfold](https://github.com/manyfold3d/manyfold) repository.
|
||||||
|
For a quick dev-environment run:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ mkdir /dev
|
||||||
|
$ manyfold/cli/manyfold.sh run -e DEV=1
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,9 @@
|
||||||
oci=$(which podman || which docker)
|
oci=$(which podman || which docker)
|
||||||
test -n "$APPNAME" || APPNAME=xrforge
|
test -n "$APPNAME" || APPNAME=xrforge
|
||||||
test -n "$UPLOAD_PATH" || UPLOAD_PATH=/mnt/experiences
|
test -n "$UPLOAD_PATH" || UPLOAD_PATH=/mnt/experiences
|
||||||
test -n "$THEME" || THEME=vapor # xrforge (public/assets/themes/xrforge.css gives err)
|
test -n "$THEME" || THEME=slate
|
||||||
test -n "$HOMEPAGE" || HOMEPAGE=/models
|
test -n "$HOMEPAGE" || HOMEPAGE=/models
|
||||||
|
test -n "$GODOT_VERSION" || GODOT_VERSION=4.4.1-stable
|
||||||
db=/config/manyfold.sqlite3
|
db=/config/manyfold.sqlite3
|
||||||
|
|
||||||
# utility funcs
|
# utility funcs
|
||||||
|
|
@ -27,11 +28,13 @@ run(){
|
||||||
debug ${oci} run "$@" -p 8790:3214 -p 8791:3215 --name xrforge \
|
debug ${oci} run "$@" -p 8790:3214 -p 8791:3215 --name xrforge \
|
||||||
-e SECRET_KEY_BASE=lkjwljlkwejrlkjek34k234l \
|
-e SECRET_KEY_BASE=lkjwljlkwejrlkjek34k234l \
|
||||||
-e DATABASE_ADAPTER=sqlite3 \
|
-e DATABASE_ADAPTER=sqlite3 \
|
||||||
|
-e FEDERATE_DRIVE_HOST=http://localhost:8791 \
|
||||||
-e SUDO_RUN_UNSAFELY=enabled \
|
-e SUDO_RUN_UNSAFELY=enabled \
|
||||||
-e MULTIUSER=enabled \
|
-e MULTIUSER=enabled \
|
||||||
-e FEDERATION=enabled \
|
-e FEDERATION=enabled \
|
||||||
-e THEME=$THEME \
|
-e THEME=$THEME \
|
||||||
-e HOMEPAGE=$HOMEPAGE \
|
-e HOMEPAGE=$HOMEPAGE \
|
||||||
|
-e GODOT_VERSION=4.4.1-stable \
|
||||||
-e FEDERATE_DRIVE_CACHE=5s \
|
-e FEDERATE_DRIVE_CACHE=5s \
|
||||||
--cap-add SYS_ADMIN --security-opt apparmor:unconfined --device /dev/fuse \
|
--cap-add SYS_ADMIN --security-opt apparmor:unconfined --device /dev/fuse \
|
||||||
xrforge
|
xrforge
|
||||||
|
|
@ -81,7 +84,10 @@ start_hook_daemon(){
|
||||||
$0 infinite 86400 hook daily &
|
$0 infinite 86400 hook daily &
|
||||||
$0 infinite 3600 hook hourly &
|
$0 infinite 3600 hook hourly &
|
||||||
# trigger hooks when files change in /mnt/experiences
|
# trigger hooks when files change in /mnt/experiences
|
||||||
inotifywait -r -m $UPLOAD_PATH | awk '$2 ~ /(CREATE|MODIFY|MOVED_TO|DELETE)/ { system("'$0' hook inotify_"$2" "$1""$3) }' &
|
find /mnt -type d -mindepth 1 -maxdepth 1 | while read dir; do
|
||||||
|
echocolor "[$APPNAME]" "listening to inotify events in $dir"
|
||||||
|
inotifywait -r -m $dir | awk '$2 ~ /(CREATE|MODIFY|MOVED_TO|DELETE)/ { system("'$0' hook inotify_"$2" "$1""$3) }' &
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -119,6 +125,7 @@ mount_dir(){
|
||||||
find /mnt -type d -mindepth 1 -maxdepth 1 | while read dir; do
|
find /mnt -type d -mindepth 1 -maxdepth 1 | while read dir; do
|
||||||
echocolor "[$APPNAME]" "mounting $dir as library"
|
echocolor "[$APPNAME]" "mounting $dir as library"
|
||||||
add_lib_to_db "$dir"
|
add_lib_to_db "$dir"
|
||||||
|
ln -s "$dir" /usr/src/app/public/.
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,7 +175,7 @@ rename_app(){
|
||||||
sed -i 's|powered_by_html:.*|powered_by_html: Radically opensource-powered by <a href="https://forgejo.isvery.ninja/coderofsalvation/xrforge">XR Forge</a>, <a href="https://manifold.app" target="_blank">Manyfold</a>, <a href="https://xrfragment.org">XR Fragments</a> and <a href="https://nixos.org" target="_blank">NIX</a>|g' /usr/src/app/config/locales/*.yml
|
sed -i 's|powered_by_html:.*|powered_by_html: Radically opensource-powered by <a href="https://forgejo.isvery.ninja/coderofsalvation/xrforge">XR Forge</a>, <a href="https://manifold.app" target="_blank">Manyfold</a>, <a href="https://xrfragment.org">XR Fragments</a> and <a href="https://nixos.org" target="_blank">NIX</a>|g' /usr/src/app/config/locales/*.yml
|
||||||
|
|
||||||
sed -i 's|Models|Experiences|g' /usr/src/app/config/locales/*.yml /usr/src/app/config/locales/*/*.yml
|
sed -i 's|Models|Experiences|g' /usr/src/app/config/locales/*.yml /usr/src/app/config/locales/*/*.yml
|
||||||
sed -i 's|Model|Experience|g' /usr/src/app/config/locales/*.yml /usr/src/app/config/locales/*.yml
|
sed -i 's|Model|Experience|g' /usr/src/app/config/locales/*.yml /usr/src/app/config/locales/*/*.yml
|
||||||
}
|
}
|
||||||
|
|
||||||
start_syslog(){
|
start_syslog(){
|
||||||
|
|
@ -198,17 +205,16 @@ force_public(){
|
||||||
|
|
||||||
get_xrfragment_assets(){
|
get_xrfragment_assets(){
|
||||||
test -n "$NO_ASSETS" && return 0 # nothing to do here
|
test -n "$NO_ASSETS" && return 0 # nothing to do here
|
||||||
test -d /mnt/assets || {
|
test -d /mnt/asset || {
|
||||||
echocolor "fetching XR Fragments assets & templates"
|
echocolor "fetching XR Fragments asset & templates"
|
||||||
mkdir -p /mnt/assets/xrfragment /mnt/templates/xrfragment
|
mkdir -p /mnt/asset/xrfragment /mnt/templates/xrfragment
|
||||||
cd /tmp
|
cd /tmp
|
||||||
timeout 50 wget "https://codeberg.org/coderofsalvation/xrfragment/archive/main.zip"
|
timeout 50 wget "https://codeberg.org/coderofsalvation/xrfragment/archive/main.zip"
|
||||||
unzip main.zip
|
unzip main.zip
|
||||||
cp -r xrfragment/assets/library /mnt/assets/xrfragment/\#1
|
cp -r xrfragment/assets/library /mnt/asset/xrfragment/\#1
|
||||||
cp -r xrfragment/assets/template /mnt/templates/xrfragment/\#2
|
cp -r xrfragment/assets/template /mnt/templates/xrfragment/\#2
|
||||||
rm -rf main.zip xrfragment
|
|
||||||
}
|
}
|
||||||
add_lib_to_db /mnt/assets
|
add_lib_to_db /mnt/asset
|
||||||
add_lib_to_db /mnt/templates
|
add_lib_to_db /mnt/templates
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,15 +228,22 @@ boot(){
|
||||||
set_homepage
|
set_homepage
|
||||||
set_theme
|
set_theme
|
||||||
set_modelpath
|
set_modelpath
|
||||||
mount_dir
|
|
||||||
mount_rclone
|
mount_rclone
|
||||||
set_upload_path
|
set_upload_path
|
||||||
start_hook_daemon
|
|
||||||
force_public
|
force_public
|
||||||
get_xrfragment_assets
|
get_xrfragment_assets
|
||||||
|
mount_dir
|
||||||
|
start_hook_daemon
|
||||||
scan_libraries &
|
scan_libraries &
|
||||||
hook boot # emit unixy hook-event (/root/hook.d/boot/* scripts)
|
hook boot # emit unixy hook-event (/root/hook.d/boot/* scripts)
|
||||||
|
|
||||||
|
# enable development mode (disables template caching etc)
|
||||||
|
test -n "$DEV" && {
|
||||||
|
sed -i 's|^exec.*|exec s6-setuidgid $PUID:$PGID bin/dev|g' /usr/src/app/bin/docker-entrypoint.sh
|
||||||
|
sed -i 's|config.enable_reloading = false|config.enable_reloading = true|g' /usr/src/app/config/environments/production.rb
|
||||||
|
apk add vim
|
||||||
|
}
|
||||||
|
|
||||||
exec "$@" # exec prevents error 's6-overlay-suexec: fatal: can only run as pid 1'
|
exec "$@" # exec prevents error 's6-overlay-suexec: fatal: can only run as pid 1'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
6
manyfold/root/hook.d/boot/godot.sh
Executable file
6
manyfold/root/hook.d/boot/godot.sh
Executable file
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/sh
|
||||||
|
test -z "$GODOT_VERSION" && exit 0 # nothing to do
|
||||||
|
wget "https://github.com/godotengine/godot/releases/download/${GODOT_VERSION}/Godot_v${GODOT_VERSION}_web_editor.zip" -O /root/godot.zip
|
||||||
|
cd /usr/src/app/public/godot
|
||||||
|
unzip /root/godot.zip
|
||||||
|
cp index.override.html index.html # make index.html autoload a manyfold zip-file (passed via HTTP query)
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
test -z "$FEDERATE_DRIVE_PATH" && FEDERATE_DRIVE_PATH=/mnt/experiences
|
test -z "$FEDERATE_DRIVE_HOST" && FEDERATE_DRIVE_HOST=http://localhost:3215
|
||||||
|
test -z "$FEDERATE_DRIVE_PATH" && FEDERATE_DRIVE_PATH=/mnt
|
||||||
test -z "$FEDERATE_DRIVE_PORT" && FEDERATE_DRIVE_PORT=3215
|
test -z "$FEDERATE_DRIVE_PORT" && FEDERATE_DRIVE_PORT=3215
|
||||||
test -z "$FEDERATE_DRIVE_CACHE" && FEDERATE_DRIVE_CACHE=1m0s
|
test -z "$FEDERATE_DRIVE_CACHE" && FEDERATE_DRIVE_CACHE=1m0s
|
||||||
|
|
||||||
|
|
|
||||||
11
manyfold/root/hook.d/inotify_MODIFY/package_godot_zip.sh
Executable file
11
manyfold/root/hook.d/inotify_MODIFY/package_godot_zip.sh
Executable file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/sh
|
||||||
|
echo "$1" | grep datapackage || exit 0 # nothing to do
|
||||||
|
dir=$(dirname $1)
|
||||||
|
cd "$dir"
|
||||||
|
echo "[package_experience.sh] zipping $dir.zip"
|
||||||
|
|
||||||
|
# overwrite empty godot template project-zip with given URL
|
||||||
|
test -n "$GODOT_TEMPLATE_ZIP" && timeout 50 wget "$GODOT_TEMPLATE_ZIP" -O ~/template_godot.zip
|
||||||
|
|
||||||
|
cp ~/template_godot.zip package_godot.zip
|
||||||
|
zip package_godot.zip *.glb *.usdz *.obj
|
||||||
BIN
manyfold/root/template_godot.zip
Normal file
BIN
manyfold/root/template_godot.zip
Normal file
Binary file not shown.
5
manyfold/test/rclone.sh
Executable file
5
manyfold/test/rclone.sh
Executable file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
which rclone &>/dev/null || { echo "[!] rclone not installed"; exit 0; }
|
||||||
|
|
||||||
|
test -d /mnt/models || { echo "[!] /mnt/models does not exist"; exit 0; }
|
||||||
25
manyfold/usr/src/app/app/components/dropdown_item.rb
Normal file
25
manyfold/usr/src/app/app/components/dropdown_item.rb
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Components::DropdownItem < Components::Base
|
||||||
|
include Phlex::Rails::Helpers::LinkTo
|
||||||
|
|
||||||
|
def initialize(icon:, label:, path:, method: nil, aria_label: nil, confirm: nil, target: nil)
|
||||||
|
@icon = icon
|
||||||
|
@label = label
|
||||||
|
@path = path
|
||||||
|
@method = method
|
||||||
|
@aria_label = aria_label
|
||||||
|
@confirm = confirm
|
||||||
|
@target = target
|
||||||
|
end
|
||||||
|
|
||||||
|
def view_template
|
||||||
|
li do
|
||||||
|
link_to @path, method: @method, class: "dropdown-item", aria: {label: @aria_label}, data: {confirm: @confirm}, target: @target do
|
||||||
|
Icon(icon: @icon, label: @label)
|
||||||
|
whitespace
|
||||||
|
span { @label }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
125
manyfold/usr/src/app/app/components/model_card.rb
Normal file
125
manyfold/usr/src/app/app/components/model_card.rb
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Components::ModelCard < Components::Base
|
||||||
|
include Phlex::Rails::Helpers::ImageTag
|
||||||
|
include Phlex::Rails::Helpers::Sanitize
|
||||||
|
include Phlex::Rails::Helpers::LinkTo
|
||||||
|
|
||||||
|
register_output_helper :status_badges
|
||||||
|
register_output_helper :server_indicator
|
||||||
|
register_value_helper :policy
|
||||||
|
|
||||||
|
def initialize(model:)
|
||||||
|
@model = model
|
||||||
|
end
|
||||||
|
|
||||||
|
def view_template
|
||||||
|
div class: "col mb-4" do
|
||||||
|
div class: "card preview-card" do
|
||||||
|
div(class: "card-header position-absolute w-100 top-0 z-3 bg-body-secondary text-secondary-emphasis opacity-75") { server_indicator @model } if @model.remote?
|
||||||
|
PreviewFrame(object: @model)
|
||||||
|
div(class: "card-body") { info_row }
|
||||||
|
actions
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def title
|
||||||
|
div class: "card-title" do
|
||||||
|
a "data-editable-field": "model[name]", "data-editable-path": model_path(@model), contenteditable: "plaintext-only", "data-controller": "editable", "data-action": "focus->editable#onFocus blur->editable#onBlur" do
|
||||||
|
@model.name
|
||||||
|
end
|
||||||
|
if @model.sensitive
|
||||||
|
whitespace
|
||||||
|
Icon(icon: "explicit", label: Model.human_attribute_name(:sensitive))
|
||||||
|
end
|
||||||
|
whitespace
|
||||||
|
AccessIndicator(object: @model)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def open_button
|
||||||
|
if @model.remote?
|
||||||
|
link_to @model.federails_actor.profile_url, {class: "btn btn-primary btn-sm", "aria-label": translate("components.model_card.open_button.label", name: @model.name)} do
|
||||||
|
span { "⁂" }
|
||||||
|
whitespace
|
||||||
|
span { t("components.model_card.open_button.text") }
|
||||||
|
end
|
||||||
|
else
|
||||||
|
link_to t("components.model_card.open_button.text"), @model, {class: "btn btn-primary btn-sm", "aria-label": translate("components.model_card.open_button.label", name: @model.name)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def credits
|
||||||
|
ul class: "list-unstyled" do
|
||||||
|
if @model.remote?
|
||||||
|
if (creator = @model.federails_actor.extensions["attributedTo"])
|
||||||
|
li { creator target: creator["url"], name: creator["name"] }
|
||||||
|
end
|
||||||
|
if (collection = @model.federails_actor.extensions["context"])
|
||||||
|
li { collection target: collection["url"], name: collection["name"] }
|
||||||
|
end
|
||||||
|
else
|
||||||
|
li { creator target: @model.creator, name: @model.creator.name } if @model.creator
|
||||||
|
li { collection target: @model.collection, name: @model.collection.name } if @model.collection
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def creator(target:, name:)
|
||||||
|
Icon icon: "person", label: Creator.model_name.human
|
||||||
|
whitespace
|
||||||
|
link_to name, target, "aria-label": [Creator.model_name.human, name].join(": ")
|
||||||
|
end
|
||||||
|
|
||||||
|
def collection(target:, name:)
|
||||||
|
Icon icon: "collection", label: Collection.model_name.human
|
||||||
|
whitespace
|
||||||
|
link_to name, target, "aria-label": [Collection.model_name.human, name].join(": ")
|
||||||
|
end
|
||||||
|
|
||||||
|
def caption
|
||||||
|
if @model.caption
|
||||||
|
span class: "card-subtitle text-muted" do
|
||||||
|
sanitize @model.caption
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def info_row
|
||||||
|
div class: "row" do
|
||||||
|
div class: "col" do
|
||||||
|
title
|
||||||
|
caption
|
||||||
|
end
|
||||||
|
div class: "col-auto" do
|
||||||
|
small do
|
||||||
|
credits
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def actions
|
||||||
|
div class: "card-footer" do
|
||||||
|
div class: "row" do
|
||||||
|
div class: "col" do
|
||||||
|
#open_button
|
||||||
|
#whitespace
|
||||||
|
status_badges @model
|
||||||
|
end
|
||||||
|
div class: "col col-auto" do
|
||||||
|
BurgerMenu do
|
||||||
|
DropdownItem(icon: "app", label: "Open in Godot Web" , path: "/godot/?url="+"/"+@model.library.name+"/"+@model.path.gsub("#","%23")+"/package_godot.zip", aria_label: translate("components.model_card.edit_button.label", name: @model.name), target: "_blank" )
|
||||||
|
DropdownItem(icon: "pencil", label: t("components.model_card.edit_button.text"), path: model_path(@model), aria_label: translate("components.model_card.edit_button.label", name: @model.name))
|
||||||
|
|
||||||
|
DropdownItem(icon: "trash", label: t("components.model_card.delete_button.text"), path: model_path(@model), method: :delete, aria_label: translate("components.model_card.delete_button.label", name: @model.name), confirm: translate("models.destroy.confirm")) if policy(@model).destroy?
|
||||||
|
DropdownItem(icon: "flag", label: t("general.report", type: ""), path: new_model_report_path(@model)) if SiteSettings.multiuser_enabled?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -72,7 +72,13 @@
|
||||||
<td>
|
<td>
|
||||||
<i class="bi bi-file-zip" role="img"></i>
|
<i class="bi bi-file-zip" role="img"></i>
|
||||||
</td>
|
</td>
|
||||||
<td><%= link_to @model.path+".zip", @model.path+".zip" %></td>
|
<td><%= link_to "zip archive", "/"+@model.library.name+"/"+@model.path.gsub("#","%23")+".zip" %></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<i class="bi bi-controller" role="img"></i>
|
||||||
|
</td>
|
||||||
|
<td><%= link_to "Godot project", "/"+@model.library.name+"/"+@model.path.gsub("#","%23")+"/package_godot.zip" %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% if @model.collection %>
|
<% if @model.collection %>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
Rails.application.configure do
|
||||||
|
config.content_security_policy_nonce_generator = lambda do |request|
|
||||||
|
# Always exclude /godot/* from CSP
|
||||||
|
if request.path.start_with?("/godot/")
|
||||||
|
nil
|
||||||
|
elsif !(Rails.env.development? && ENV.fetch("SCOUT_DEV_TRACE", false) == "true")
|
||||||
|
request.session.id.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
327
manyfold/usr/src/app/public/assets/roundel-1d688b1e.svg
Normal file
327
manyfold/usr/src/app/public/assets/roundel-1d688b1e.svg
Normal file
|
|
@ -0,0 +1,327 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="128.27411mm"
|
||||||
|
height="145.65482mm"
|
||||||
|
viewBox="0 0 128.27411 145.65482"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
xml:space="preserve"
|
||||||
|
inkscape:export-filename="../../../../../Downloads/xrforge.svg"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
sodipodi:docname="logo.svg"
|
||||||
|
inkscape:dataloss="true"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
|
id="namedview7"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#ffffff"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:showpageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="1"
|
||||||
|
inkscape:deskcolor="#505050"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.56323837"
|
||||||
|
inkscape:cx="226.36952"
|
||||||
|
inkscape:cy="409.24058"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1030"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="26"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" /><defs
|
||||||
|
id="defs2"><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient12286"><stop
|
||||||
|
style="stop-color:#ea0bfe;stop-opacity:0.11569338;"
|
||||||
|
offset="0"
|
||||||
|
id="stop12282" /><stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop12284" /></linearGradient><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient12159"><stop
|
||||||
|
style="stop-color:#fe83ff;stop-opacity:0.35045233;"
|
||||||
|
offset="0"
|
||||||
|
id="stop12155" /><stop
|
||||||
|
style="stop-color:#3c9cff;stop-opacity:0.32712477;"
|
||||||
|
offset="1"
|
||||||
|
id="stop12157" /></linearGradient><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient12153"><stop
|
||||||
|
style="stop-color:#fe83ff;stop-opacity:0.29342434;"
|
||||||
|
offset="0"
|
||||||
|
id="stop12149" /><stop
|
||||||
|
style="stop-color:#3c9cff;stop-opacity:0.31577286;"
|
||||||
|
offset="1"
|
||||||
|
id="stop12151" /></linearGradient><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient12139"><stop
|
||||||
|
style="stop-color:#ea0bfe;stop-opacity:0.50826901;"
|
||||||
|
offset="0"
|
||||||
|
id="stop12135" /><stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop12137" /></linearGradient><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient12102"><stop
|
||||||
|
style="stop-color:#fe83ff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop12098" /><stop
|
||||||
|
style="stop-color:#3c9cff;stop-opacity:0.81848603;"
|
||||||
|
offset="1"
|
||||||
|
id="stop12100" /></linearGradient><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient7688"><stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop7684" /><stop
|
||||||
|
style="stop-color:#ff13f3;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop7686" /></linearGradient><linearGradient
|
||||||
|
id="linearGradient6742"><stop
|
||||||
|
style="stop-color:#276fff;stop-opacity:1"
|
||||||
|
offset="0"
|
||||||
|
id="stop6738" /><stop
|
||||||
|
style="stop-color:#ff16bc;stop-opacity:1"
|
||||||
|
offset="1"
|
||||||
|
id="stop6740" /></linearGradient><linearGradient
|
||||||
|
xlink:href="#linearGradient6742"
|
||||||
|
id="linearGradient8637"
|
||||||
|
x1="154.78049"
|
||||||
|
y1="24.048252"
|
||||||
|
x2="273.12695"
|
||||||
|
y2="24.048252"
|
||||||
|
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient7688"
|
||||||
|
id="linearGradient7692"
|
||||||
|
x1="115.42191"
|
||||||
|
y1="-2.709012"
|
||||||
|
x2="117.16759"
|
||||||
|
y2="131.87457"
|
||||||
|
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient12102"
|
||||||
|
id="linearGradient12104"
|
||||||
|
x1="54.029213"
|
||||||
|
y1="71.733955"
|
||||||
|
x2="176.85757"
|
||||||
|
y2="71.733955"
|
||||||
|
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient12159"
|
||||||
|
id="linearGradient12108"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="54.029213"
|
||||||
|
y1="71.733955"
|
||||||
|
x2="176.85757"
|
||||||
|
y2="71.733955"
|
||||||
|
gradientTransform="translate(0,4.7625002)" /><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient12153"
|
||||||
|
id="linearGradient12112"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(0,19.579173)"
|
||||||
|
x1="54.029213"
|
||||||
|
y1="71.733955"
|
||||||
|
x2="176.85757"
|
||||||
|
y2="71.733955" /><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient12286"
|
||||||
|
id="linearGradient12141"
|
||||||
|
x1="137.33427"
|
||||||
|
y1="88.766113"
|
||||||
|
x2="177.37935"
|
||||||
|
y2="88.766113"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.2850723,0,0,1.2367478,-50.791853,-16.999519)" /><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient12139"
|
||||||
|
id="linearGradient12239"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="137.33427"
|
||||||
|
y1="88.766113"
|
||||||
|
x2="177.37935"
|
||||||
|
y2="88.766113"
|
||||||
|
gradientTransform="matrix(-1.2669282,0,0,1.2603766,278.3952,-19.18513)" /><filter
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
inkscape:label="Drop Shadow"
|
||||||
|
id="filter12743"
|
||||||
|
x="-0.079006463"
|
||||||
|
y="-0.2479955"
|
||||||
|
width="1.1580434"
|
||||||
|
height="1.4959902"><feFlood
|
||||||
|
flood-opacity="1"
|
||||||
|
flood-color="rgb(204,26,255)"
|
||||||
|
result="flood"
|
||||||
|
id="feFlood12733" /><feComposite
|
||||||
|
in="flood"
|
||||||
|
in2="SourceGraphic"
|
||||||
|
operator="in"
|
||||||
|
result="composite1"
|
||||||
|
id="feComposite12735" /><feGaussianBlur
|
||||||
|
in="composite1"
|
||||||
|
stdDeviation="1.1"
|
||||||
|
result="blur"
|
||||||
|
id="feGaussianBlur12737" /><feOffset
|
||||||
|
dx="0"
|
||||||
|
dy="0"
|
||||||
|
result="offset"
|
||||||
|
id="feOffset12739" /><feComposite
|
||||||
|
in="SourceGraphic"
|
||||||
|
in2="offset"
|
||||||
|
operator="over"
|
||||||
|
result="composite2"
|
||||||
|
id="feComposite12741" /></filter><filter
|
||||||
|
style="color-interpolation-filters:sRGB"
|
||||||
|
inkscape:label="Drop Shadow"
|
||||||
|
id="filter13745"
|
||||||
|
x="-0.13448349"
|
||||||
|
y="-0.73597109"
|
||||||
|
width="1.268967"
|
||||||
|
height="2.4719422"><feFlood
|
||||||
|
flood-opacity="1"
|
||||||
|
flood-color="rgb(26,135,255)"
|
||||||
|
result="flood"
|
||||||
|
id="feFlood13735" /><feComposite
|
||||||
|
in="flood"
|
||||||
|
in2="SourceGraphic"
|
||||||
|
operator="in"
|
||||||
|
result="composite1"
|
||||||
|
id="feComposite13737" /><feGaussianBlur
|
||||||
|
in="composite1"
|
||||||
|
stdDeviation="4.48865"
|
||||||
|
result="blur"
|
||||||
|
id="feGaussianBlur13739" /><feOffset
|
||||||
|
dx="0"
|
||||||
|
dy="0"
|
||||||
|
result="offset"
|
||||||
|
id="feOffset13741" /><feComposite
|
||||||
|
in="SourceGraphic"
|
||||||
|
in2="offset"
|
||||||
|
operator="over"
|
||||||
|
result="composite2"
|
||||||
|
id="feComposite13743" /></filter><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient12286"
|
||||||
|
id="linearGradient14475"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.2850723,0,0,1.2367478,-50.791853,-16.999519)"
|
||||||
|
x1="137.33427"
|
||||||
|
y1="88.766113"
|
||||||
|
x2="177.37935"
|
||||||
|
y2="88.766113" /></defs><g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-51.358538,-4.8451999)"><path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:2.3;stroke-dasharray:none"
|
||||||
|
id="path1638-3"
|
||||||
|
inkscape:flatsided="true"
|
||||||
|
sodipodi:sides="6"
|
||||||
|
sodipodi:cx="138.75616"
|
||||||
|
sodipodi:cy="263.41873"
|
||||||
|
sodipodi:r1="70.000412"
|
||||||
|
sodipodi:r2="60.622131"
|
||||||
|
sodipodi:arg1="-2.6179939"
|
||||||
|
sodipodi:arg2="-2.0943951"
|
||||||
|
inkscape:rounded="0"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 78.134029,228.41853 60.622131,-35.00021 60.62214,35.0002 0,70.00042 -60.62213,35.0002 -60.62214,-35.0002 z"
|
||||||
|
inkscape:transform-center-x="-4.0923148e-06"
|
||||||
|
inkscape:transform-center-y="-2.6621219e-06"
|
||||||
|
transform="matrix(1.0382846,0,0,1.0210168,-28.572793,-191.28234)" /><g
|
||||||
|
id="g12126"
|
||||||
|
inkscape:label="lines"><path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:url(#linearGradient12104);stroke-width:0.5;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 54.029427,71.745371 176.85736,71.722537"
|
||||||
|
id="path12042"
|
||||||
|
inkscape:label="line" /><path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:url(#linearGradient12108);stroke-width:0.6;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 54.029427,76.507874 176.85736,76.48504"
|
||||||
|
id="path12106"
|
||||||
|
inkscape:label="line" /><path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:url(#linearGradient12112);stroke-width:0.8;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 54.029427,91.32455 176.85736,91.301716"
|
||||||
|
id="path12110"
|
||||||
|
inkscape:label="line" /><path
|
||||||
|
style="fill:url(#linearGradient12239);fill-opacity:1;stroke:none;stroke-width:2.416;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 104.40252,71.315371 53.668551,108.90527 v 5.16648 z"
|
||||||
|
id="path12133-5" /><path
|
||||||
|
style="fill:url(#linearGradient14475);fill-opacity:1;stroke:none;stroke-width:2.41042;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 125.69256,71.804339 51.46081,36.885251 v 5.06963 z"
|
||||||
|
id="path12133" /><path
|
||||||
|
style="fill:url(#linearGradient12141);fill-opacity:1;stroke:none;stroke-width:2.41042;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 115.37951,70.94784 5.14781,74.3852 c 0,0 -4.42958,5.94658 -10.22727,-0.9757 z"
|
||||||
|
id="path12280"
|
||||||
|
sodipodi:nodetypes="cccc" /></g><path
|
||||||
|
style="fill:url(#linearGradient7692);fill-opacity:1;stroke:none;stroke-width:2.3;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 53.906377,71.659657 H 177.09207 l 0.24519,40.701533 -61.93861,35.18517 -61.54407,-35.3442 z"
|
||||||
|
id="path7625"
|
||||||
|
sodipodi:nodetypes="cccccc" /><g
|
||||||
|
id="g4494"
|
||||||
|
transform="matrix(2.7825702,0,0,3.2095953,58.857189,44.497537)"
|
||||||
|
style="filter:url(#filter12743)"><g
|
||||||
|
transform="translate(-47.668322,-15.505759)"
|
||||||
|
id="g113"><g
|
||||||
|
transform="scale(0.26458)"
|
||||||
|
style="font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal"
|
||||||
|
aria-label="SEARXR"
|
||||||
|
id="g111"><path
|
||||||
|
id="path105"
|
||||||
|
style="font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;opacity:1;fill:#f7f7f7;fill-opacity:0.996078;stroke:url(#linearGradient8637);stroke-width:3.77953;stroke-miterlimit:4;stroke-dasharray:none"
|
||||||
|
d="m 158.51953,0.12890625 c -1.12928,0.0104375 -2.33343,0.0380832 -3.58789,0.09375 -0.30457,-0.13399831 -0.0547,13.73632775 -0.0547,13.73632775 2.81897,0.06348 6.79437,-0.315067 8.33985,1.041016 3.97475,3.093961 3.19147,2.418039 5.77734,5.003906 2.58587,2.585868 5.23601,5.171945 7.95117,7.757813 l -21.2931,18.782442 c -1.29339,1.292984 -2.45529,1.570562 8.42537,1.302881 9.59316,-0.08935 8.19237,0.720755 10.73745,-1.137203 7.83955,-6.121602 9.61287,-7.470425 12.32804,-10.185491 3.0599,2.434819 5.75483,4.092804 10.43494,7.218213 0,0 4.56752,2.32698 9.03546,3.466611 5.1614,0.869711 19.0651,0.856505 19.62872,0.659979 h 4.7207 c 0,0 0.0977,-8.957996 0.16992,-16.066407 0.12771,-10.909788 2.17195,-13.091574 4.75781,-15.80664 2.71507,-2.715066 6.01188,-2.072266 9.89063,-2.072266 h 21.3457 V 0.15429688 h -21.3457 c -7.6279,0 -14.15766,2.71429962 -19.58789,8.14453122 -5.30093,5.3009329 -7.95117,11.7666269 -7.95117,19.3945309 v 9.097657 c -2.05016,0.03977 -4.12643,0.0029 -5.92969,-0.160157 -1.85798,-0.167898 -4.68413,-1.320736 -8.3076,-3.088808 0,0 -4.88583,-3.065166 -7.4717,-5.780332 l 15.00318,-15.777875 c 1.25994,-1.325002 3.90091,-4.6189385 8.52807,-9.5834534 1.63566,-1.75491056 0.84973,-2.31134101 -4.04101,-2.19531248 -2.41247,0.00862 -6.69149,0.0175781 -8.63086,0.0175781 -1.81008,0 -3.42548,0.71063042 -4.84766,2.13281258 L 186.83594,18.064453 c -2.71507,-2.585867 -5.36541,-5.171945 -7.95117,-7.757812 l -7.95118,-7.9511722 c -1.42218,-1.42217213 -3.03953,-2.13281255 -4.84961,-2.13281255 -1.45453,0 -4.17661,-0.12506257 -7.56445,-0.09375 z"
|
||||||
|
transform="matrix(1.0000126,0,0,1.0000126,27.273414,60.371154)" /><path
|
||||||
|
d="m 267.38547,88.252296 c 0,-7.665647 2.6505,-14.161997 7.9515,-19.48895 5.4303,-5.456886 11.96,-8.185379 19.588,-8.185379 h 37.34533 v 13.837416 h -37.34533 c -3.8788,0 -7.1758,1.364246 -9.8909,4.092639 -2.5859,2.728493 -3.8788,5.976618 -3.8788,9.744475 v 19.634563 h -13.77 z"
|
||||||
|
style="font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;fill:#f7f7f7;fill-opacity:0.997356;stroke:#54438e;stroke-width:3.78882;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path103" /><rect
|
||||||
|
style="fill:#f7f7f7;fill-opacity:0.996078;stroke:none;stroke-width:3.77958"
|
||||||
|
id="rect1105"
|
||||||
|
width="29.440615"
|
||||||
|
height="9.8188734"
|
||||||
|
x="269.93423"
|
||||||
|
y="62.516171" /></g></g><path
|
||||||
|
d="m 40.243755,6.8720423 -9.0863,-0.04493 c 0,0 -1.8872,0.04494 -1.8423,1.5727 0.04493,1.5277999 1.8772,1.4827999 1.8772,1.4827999 h 9.0514 z"
|
||||||
|
stroke="#000000"
|
||||||
|
stroke-width="0.26458px"
|
||||||
|
id="path117"
|
||||||
|
style="fill:#fefefe;fill-opacity:1;stroke:#54438e;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /></g><text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:19.7556px;font-family:Montserrat;-inkscape-font-specification:'Montserrat Bold';text-align:center;text-anchor:middle;fill:#ffffff;stroke:#ffffff;stroke-width:0.5;stroke-dasharray:none"
|
||||||
|
x="69.809654"
|
||||||
|
y="107.18471"
|
||||||
|
id="text1004"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan1002"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:100;font-stretch:normal;font-size:19.7556px;font-family:Montserrat;-inkscape-font-specification:'Montserrat Thin';stroke-width:0.5;stroke-dasharray:none"
|
||||||
|
x="69.809654"
|
||||||
|
y="107.18471">[</tspan></text><text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:19.7556px;font-family:Montserrat;-inkscape-font-specification:'Montserrat Bold';text-align:center;text-anchor:middle;fill:#ffffff;stroke:#ffffff;stroke-width:0.5;stroke-dasharray:none"
|
||||||
|
x="160.00148"
|
||||||
|
y="107.33738"
|
||||||
|
id="text1004-3"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan1002-6"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:100;font-stretch:normal;font-size:19.7556px;font-family:Montserrat;-inkscape-font-specification:'Montserrat Thin';stroke-width:0.5;stroke-dasharray:none"
|
||||||
|
x="160.00148"
|
||||||
|
y="107.33738">]</tspan></text><text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-weight:100;font-size:16.2278px;font-family:Montserrat;-inkscape-font-specification:'Montserrat Thin';text-align:center;letter-spacing:0.529167px;writing-mode:tb-rl;text-orientation:upright;text-anchor:middle;fill:#020202;fill-opacity:1;stroke:#000000;stroke-width:2.3;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter13745)"
|
||||||
|
x="85.100029"
|
||||||
|
y="91.992111"
|
||||||
|
id="text3268"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3266"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16.2278px;font-family:Montserrat;-inkscape-font-specification:'Montserrat Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.3;stroke-opacity:1"
|
||||||
|
x="85.100029"
|
||||||
|
y="91.992111">XR Forge</tspan></text></g></svg>
|
||||||
|
After Width: | Height: | Size: 16 KiB |
27680
manyfold/usr/src/app/public/assets/themes/vapor-9dfc85d7.css
Normal file
27680
manyfold/usr/src/app/public/assets/themes/vapor-9dfc85d7.css
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -762,6 +762,24 @@ document.getElementById('startButton').onclick = function () {
|
||||||
startEditor(zip);
|
startEditor(zip);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function(){
|
||||||
|
setTimeout( () => {
|
||||||
|
if( document.location.search ){
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const url = urlParams.get('url');
|
||||||
|
if( url ){
|
||||||
|
fetch( url.replace('#','%23') )
|
||||||
|
.then( (res) => res.arrayBuffer() )
|
||||||
|
.then( (a) => {
|
||||||
|
console.dir(a)
|
||||||
|
return a
|
||||||
|
})
|
||||||
|
.then( (ab) => startEditor(ab) )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},500 )
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Loading…
Add table
Reference in a new issue