diff --git a/CHANGES.md b/CHANGES.md
index 7c759be733..193ca53fb2 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -26,6 +26,13 @@ The initial prototype is completly reworked for provide a more consistent API
and to have proper validation and params decoding. All the details can be found
on [its own changelog](library/CHANGES.md)
+**Penpot migrate from Redis to Valkey**
+
+As [Valkey](https://valkey.io/) is an opne-souce fork of [Redis](https://redis.io/)
+version 7.2.4, this version of Penpot will be compatible with Redis but may diverge
+in future versions. Therefore, **migration from Redis to ValKey is recommended for all
+on-premises instances** that want to keep up to date.
+
### :heart: Community contributions (Thank you!)
### :sparkles: New features & Enhancements
@@ -45,6 +52,7 @@ on [its own changelog](library/CHANGES.md)
- Update google fonts (at 2025/05/19) [Taiga 10792](https://tree.taiga.io/project/penpot/us/10792)
- Add tooltip component to DS [Taiga 9220](https://tree.taiga.io/project/penpot/us/9220)
- Allow multi file token export [Taiga #10144](https://tree.taiga.io/project/penpot/us/10144)
+- Add Serbian language
### :bug: Bugs fixed
@@ -54,7 +62,9 @@ on [its own changelog](library/CHANGES.md)
- Fix element positioning on the right side to adjust to grid [#11073](https://tree.taiga.io/project/penpot/issue/11073)
- Fix palette is over sidebar [#11160](https://tree.taiga.io/project/penpot/issue/11160)
- Fix font size input not displaying "mixed" when multiple texts are selected [Taiga #11177](https://tree.taiga.io/project/penpot/issue/11177)
-
+- Misalignments at Create account [Taiga #11315](https://tree.taiga.io/project/penpot/issue/11315)
+- Fix issue with importing files where flex/grid is used [Taiga #11334](https://tree.taiga.io/project/penpot/issue/11334)
+- Fix wrong color in the export progress bar [Taiga #11299](https://tree.taiga.io/project/penpot/issue/11299)
## 2.7.2
diff --git a/common/deps.edn b/common/deps.edn
index bffd94a026..f6e54ae876 100644
--- a/common/deps.edn
+++ b/common/deps.edn
@@ -28,7 +28,7 @@
integrant/integrant {:mvn/version "0.13.1"}
funcool/tubax {:mvn/version "2021.05.20-0"}
- funcool/cuerdas {:mvn/version "2025.05.26-411"}
+ funcool/cuerdas {:mvn/version "2025.06.16-414"}
funcool/promesa
{:git/sha "f52f58cfacf62f59eab717e2637f37729d0cc383"
:git/url "https://github.com/funcool/promesa"}
diff --git a/common/src/app/common/files/shapes_helpers.cljc b/common/src/app/common/files/shapes_helpers.cljc
index fa1ba12bd0..a6421f9405 100644
--- a/common/src/app/common/files/shapes_helpers.cljc
+++ b/common/src/app/common/files/shapes_helpers.cljc
@@ -91,10 +91,10 @@
parent-id (or parent-id (get selected-obj :parent-id))
base-parent (get objects parent-id)
- layout-props
+ layout-attrs
(when (and (= 1 (count selected))
(ctl/any-layout? base-parent))
- (select-keys selected-obj ctl/layout-item-props))
+ (select-keys selected-obj ctl/layout-child-attrs))
target-cell-id
(if (and (nil? target-cell-id)
@@ -129,8 +129,8 @@
:parent-id parent-id
:shapes (into [] selected))
- (some? layout-props)
- (d/patch-object layout-props)
+ (some? layout-attrs)
+ (d/patch-object layout-attrs)
;; Frames from shapes will not be displayed in viewer and no clipped
(or (not= frame-id uuid/zero) without-fill?)
diff --git a/common/src/app/common/types/path.cljc b/common/src/app/common/types/path.cljc
index b06c72afbe..65336fe2d5 100644
--- a/common/src/app/common/types/path.cljc
+++ b/common/src/app/common/types/path.cljc
@@ -104,36 +104,11 @@
(impl/path-data
(reduce apply-to-index (vec content) modifiers))))
-(defn- transform-content-legacy
- [content transform]
- (if (some? transform)
- (let [set-tr
- (fn [params px py]
- (let [tr-point (-> (gpt/point (get params px) (get params py))
- (gpt/transform transform))]
- (assoc params
- px (:x tr-point)
- py (:y tr-point))))
-
- transform-params
- (fn [{:keys [x c1x c2x] :as params}]
- (cond-> params
- (some? x) (set-tr :x :y)
- (some? c1x) (set-tr :c1x :c1y)
- (some? c2x) (set-tr :c2x :c2y)))]
-
- (into []
- (map #(update % :params transform-params))
- content))
- content))
-
(defn transform-content
"Applies a transformation matrix over content and returns a new
content as PathData instance."
[content transform]
- #_(segment/transform-content content transform)
- (some-> (transform-content-legacy (vec content) transform)
- (impl/from-plain)))
+ (segment/transform-content content transform))
(defn move-content
[content move-vec]
diff --git a/common/src/app/common/types/path/impl.cljc b/common/src/app/common/types/path/impl.cljc
index cb973ca70e..bc948d9f5c 100644
--- a/common/src/app/common/types/path/impl.cljc
+++ b/common/src/app/common/types/path/impl.cljc
@@ -65,34 +65,34 @@
(let [t (buf/read-short buffer offset)]
(case t
(1 2)
- (let [x (buf/read-float buffer (+ offset 20))
- y (buf/read-float buffer (+ offset 24))
- x (+ (* x a) (* y c) e)
- y (+ (* x b) (* y d) f)]
- (buf/write-float buffer (+ offset 20) x)
- (buf/write-float buffer (+ offset 24) y))
+ (let [x (buf/read-float buffer (+ offset 20))
+ y (buf/read-float buffer (+ offset 24))
+ x' (+ (* x a) (* y c) e)
+ y' (+ (* x b) (* y d) f)]
+ (buf/write-float buffer (+ offset 20) x')
+ (buf/write-float buffer (+ offset 24) y'))
3
- (let [c1x (buf/read-float buffer (+ offset 4))
- c1y (buf/read-float buffer (+ offset 8))
- c2x (buf/read-float buffer (+ offset 12))
- c2y (buf/read-float buffer (+ offset 16))
- x (buf/read-float buffer (+ offset 20))
- y (buf/read-float buffer (+ offset 24))
+ (let [c1x (buf/read-float buffer (+ offset 4))
+ c1y (buf/read-float buffer (+ offset 8))
+ c2x (buf/read-float buffer (+ offset 12))
+ c2y (buf/read-float buffer (+ offset 16))
+ x (buf/read-float buffer (+ offset 20))
+ y (buf/read-float buffer (+ offset 24))
- c1x (+ (* c1x a) (* c1y c) e)
- c1y (+ (* c1x b) (* c1y d) f)
- c2x (+ (* c2x a) (* c2y c) e)
- c2y (+ (* c2x b) (* c2y d) f)
- x (+ (* x a) (* y c) e)
- y (+ (* x b) (* y d) f)]
+ c1x' (+ (* c1x a) (* c1y c) e)
+ c1y' (+ (* c1x b) (* c1y d) f)
+ c2x' (+ (* c2x a) (* c2y c) e)
+ c2y' (+ (* c2x b) (* c2y d) f)
+ x' (+ (* x a) (* y c) e)
+ y' (+ (* x b) (* y d) f)]
- (buf/write-float buffer (+ offset 4) c1x)
- (buf/write-float buffer (+ offset 8) c1y)
- (buf/write-float buffer (+ offset 12) c2x)
- (buf/write-float buffer (+ offset 16) c2y)
- (buf/write-float buffer (+ offset 20) x)
- (buf/write-float buffer (+ offset 24) y))
+ (buf/write-float buffer (+ offset 4) c1x')
+ (buf/write-float buffer (+ offset 8) c1y')
+ (buf/write-float buffer (+ offset 12) c2x')
+ (buf/write-float buffer (+ offset 16) c2y')
+ (buf/write-float buffer (+ offset 20) x')
+ (buf/write-float buffer (+ offset 24) y'))
nil)))
diff --git a/common/src/app/common/types/shape.cljc b/common/src/app/common/types/shape.cljc
index aac6b018e8..ed0ba5ae3a 100644
--- a/common/src/app/common/types/shape.cljc
+++ b/common/src/app/common/types/shape.cljc
@@ -313,7 +313,7 @@
:title "Shape"}
[:group
[:merge {:title "GroupShape"}
- ctsl/schema:layout-attrs
+ ctsl/schema:layout-child-attrs
schema:group-attrs
schema:shape-generic-attrs
schema:shape-geom-attrs
@@ -321,8 +321,8 @@
[:frame
[:merge {:title "FrameShape"}
+ ctsl/schema:layout-child-attrs
ctsl/schema:layout-attrs
- ::ctsl/layout-attrs
schema:frame-attrs
schema:shape-generic-attrs
schema:shape-geom-attrs
@@ -332,14 +332,14 @@
[:bool
[:merge {:title "BoolShape"}
- ctsl/schema:layout-attrs
+ ctsl/schema:layout-child-attrs
schema:bool-attrs
schema:shape-generic-attrs
schema:shape-base-attrs]]
[:rect
[:merge {:title "RectShape"}
- ctsl/schema:layout-attrs
+ ctsl/schema:layout-child-attrs
schema:rect-attrs
schema:shape-generic-attrs
schema:shape-geom-attrs
@@ -347,7 +347,7 @@
[:circle
[:merge {:title "CircleShape"}
- ctsl/schema:layout-attrs
+ ctsl/schema:layout-child-attrs
schema:circle-attrs
schema:shape-generic-attrs
schema:shape-geom-attrs
@@ -355,7 +355,7 @@
[:image
[:merge {:title "ImageShape"}
- ctsl/schema:layout-attrs
+ ctsl/schema:layout-child-attrs
schema:image-attrs
schema:shape-generic-attrs
schema:shape-geom-attrs
@@ -363,7 +363,7 @@
[:svg-raw
[:merge {:title "SvgRawShape"}
- ctsl/schema:layout-attrs
+ ctsl/schema:layout-child-attrs
schema:svg-raw-attrs
schema:shape-generic-attrs
schema:shape-geom-attrs
@@ -371,14 +371,14 @@
[:path
[:merge {:title "PathShape"}
- ctsl/schema:layout-attrs
+ ctsl/schema:layout-child-attrs
schema:path-attrs
schema:shape-generic-attrs
schema:shape-base-attrs]]
[:text
[:merge {:title "TextShape"}
- ctsl/schema:layout-attrs
+ ctsl/schema:layout-child-attrs
schema:text-attrs
schema:shape-generic-attrs
schema:shape-geom-attrs
@@ -682,23 +682,6 @@
:r3
:r4})
-(def ^:private layout-extract-props
- #{:layout
- :layout-flex-dir
- :layout-gap-type
- :layout-gap
- :layout-wrap-type
- :layout-align-items
- :layout-align-content
- :layout-justify-items
- :layout-justify-content
- :layout-padding-type
- :layout-padding
- :layout-grid-dir
- :layout-grid-rows
- :layout-grid-columns
- :layout-grid-cells})
-
(defn extract-props
"Retrieves an object with the 'pasteable' properties for a shape."
[shape]
@@ -729,9 +712,8 @@
(assoc-props node txt/text-node-attrs)))
props)))
- (extract-layout-props
- [props shape]
- (d/patch-object props (select-keys shape layout-extract-props)))]
+ (extract-layout-attrs [props shape]
+ (d/patch-object props (select-keys shape ctsl/layout-attrs)))]
(let [;; For texts we don't extract the fill
extract-props
@@ -739,7 +721,7 @@
(-> shape
(select-keys extract-props)
(cond-> (cfh/text-shape? shape) (extract-text-props shape))
- (cond-> (ctsl/any-layout? shape) (extract-layout-props shape))))))
+ (cond-> (ctsl/any-layout? shape) (extract-layout-attrs shape))))))
(defn patch-props
"Given the object of `extract-props` applies it to a shape. Adapt the shape if necesary"
@@ -764,7 +746,7 @@
(d/patch-object (select-keys props txt/text-node-attrs))))))))))
(patch-layout-props [shape props]
- (let [shape (d/patch-object shape (select-keys props layout-extract-props))]
+ (let [shape (d/patch-object shape (select-keys props ctsl/layout-attrs))]
(cond-> shape
(ctsl/grid-layout? shape)
(ctsl/assign-cells objects))))]
diff --git a/common/src/app/common/types/shape/layout.cljc b/common/src/app/common/types/shape/layout.cljc
index e66016502f..10051ee759 100644
--- a/common/src/app/common/types/shape/layout.cljc
+++ b/common/src/app/common/types/shape/layout.cljc
@@ -43,7 +43,6 @@
;; :layout-item-absolute ;; boolean
;; :layout-item-z-index ;; int
-
(def layout-types
#{:flex :grid})
@@ -74,49 +73,6 @@
(def justify-items-types
#{:start :end :center :stretch})
-(def layout-item-props
- [:layout-item-margin
- :layout-item-margin-type
- :layout-item-h-sizing
- :layout-item-v-sizing
- :layout-item-max-h
- :layout-item-min-h
- :layout-item-max-w
- :layout-item-min-w
- :layout-item-absolute
- :layout-item-z-index])
-
-(sm/register!
- ^{::sm/type ::layout-attrs}
- [:map {:title "LayoutAttrs"}
- [:layout {:optional true} [::sm/one-of layout-types]]
- [:layout-flex-dir {:optional true} [::sm/one-of flex-direction-types]]
- [:layout-gap {:optional true}
- [:map
- [:row-gap {:optional true} ::sm/safe-number]
- [:column-gap {:optional true} ::sm/safe-number]]]
- [:layout-gap-type {:optional true} [::sm/one-of gap-types]]
- [:layout-wrap-type {:optional true} [::sm/one-of wrap-types]]
- [:layout-padding-type {:optional true} [::sm/one-of padding-type]]
- [:layout-padding {:optional true}
- [:map
- [:p1 ::sm/safe-number]
- [:p2 ::sm/safe-number]
- [:p3 ::sm/safe-number]
- [:p4 ::sm/safe-number]]]
- [:layout-justify-content {:optional true} [::sm/one-of justify-content-types]]
- [:layout-justify-items {:optional true} [::sm/one-of justify-items-types]]
- [:layout-align-content {:optional true} [::sm/one-of align-content-types]]
- [:layout-align-items {:optional true} [::sm/one-of align-items-types]]
-
- [:layout-grid-dir {:optional true} [::sm/one-of grid-direction-types]]
- [:layout-grid-rows {:optional true}
- [:vector {:gen/max 2} ::grid-track]]
- [:layout-grid-columns {:optional true}
- [:vector {:gen/max 2} ::grid-track]]
- [:layout-grid-cells {:optional true}
- [:map-of {:gen/max 5} ::sm/uuid ::grid-cell]]])
-
;; Grid types
(def grid-track-types
#{:percent :flex :auto :fixed})
@@ -130,29 +86,59 @@
(def grid-cell-justify-self-types
#{:auto :start :center :end :stretch})
-(sm/register!
- ^{::sm/type ::grid-cell}
- [:map {:title "GridCell"}
- [:id ::sm/uuid]
- [:area-name {:optional true} :string]
- [:row ::sm/safe-int]
- [:row-span ::sm/safe-int]
- [:column ::sm/safe-int]
- [:column-span ::sm/safe-int]
- [:position {:optional true} [::sm/one-of grid-position-types]]
- [:align-self {:optional true} [::sm/one-of grid-cell-align-self-types]]
- [:justify-self {:optional true} [::sm/one-of grid-cell-justify-self-types]]
- [:shapes
- [:vector {:gen/max 1} ::sm/uuid]]])
+(def ^:private schema:grid-cell
+ [:map {:title "GridCell"}
+ [:id ::sm/uuid]
+ [:area-name {:optional true} :string]
+ [:row ::sm/safe-int]
+ [:row-span ::sm/safe-int]
+ [:column ::sm/safe-int]
+ [:column-span ::sm/safe-int]
+ [:position {:optional true} [::sm/one-of grid-position-types]]
+ [:align-self {:optional true} [::sm/one-of grid-cell-align-self-types]]
+ [:justify-self {:optional true} [::sm/one-of grid-cell-justify-self-types]]
+ [:shapes
+ [:vector {:gen/max 1} ::sm/uuid]]])
-(sm/register!
- ^{::sm/type ::grid-track}
- [:map {:title "GridTrack"}
- [:type [::sm/one-of grid-track-types]]
- [:value {:optional true} [:maybe ::sm/safe-number]]])
+(def ^:private schema:grid-track
+ [:map {:title "GridTrack"}
+ [:type [::sm/one-of grid-track-types]]
+ [:value {:optional true} [:maybe ::sm/safe-number]]])
-(def check-grid-track!
- (sm/check-fn ::grid-track))
+(def schema:layout-attrs
+ [:map {:title "LayoutAttrs"}
+ [:layout {:optional true} [::sm/one-of layout-types]]
+ [:layout-flex-dir {:optional true} [::sm/one-of flex-direction-types]]
+ [:layout-gap {:optional true}
+ [:map
+ [:row-gap {:optional true} ::sm/safe-number]
+ [:column-gap {:optional true} ::sm/safe-number]]]
+ [:layout-gap-type {:optional true} [::sm/one-of gap-types]]
+ [:layout-wrap-type {:optional true} [::sm/one-of wrap-types]]
+ [:layout-padding-type {:optional true} [::sm/one-of padding-type]]
+ [:layout-padding {:optional true}
+ [:map
+ [:p1 ::sm/safe-number]
+ [:p2 ::sm/safe-number]
+ [:p3 ::sm/safe-number]
+ [:p4 ::sm/safe-number]]]
+ [:layout-justify-content {:optional true} [::sm/one-of justify-content-types]]
+ [:layout-justify-items {:optional true} [::sm/one-of justify-items-types]]
+ [:layout-align-content {:optional true} [::sm/one-of align-content-types]]
+ [:layout-align-items {:optional true} [::sm/one-of align-items-types]]
+ [:layout-grid-dir {:optional true} [::sm/one-of grid-direction-types]]
+ [:layout-grid-rows {:optional true}
+ [:vector {:gen/max 2} schema:grid-track]]
+ [:layout-grid-columns {:optional true}
+ [:vector {:gen/max 2} schema:grid-track]]
+ [:layout-grid-cells {:optional true}
+ [:map-of {:gen/max 5} ::sm/uuid schema:grid-cell]]])
+
+(def ^:private check-grid-track
+ (sm/check-fn schema:grid-track))
+
+(def layout-attrs
+ (sm/keys schema:layout-attrs))
;; LAYOUT CHILDREN
@@ -168,7 +154,7 @@
(def item-align-self-types
#{:start :end :center :stretch})
-(def schema:layout-attrs
+(def schema:layout-child-attrs
[:map {:title "LayoutChildAttrs"}
[:layout-item-margin-type {:optional true} [::sm/one-of item-margin-types]]
[:layout-item-margin {:optional true}
@@ -187,6 +173,9 @@
[:layout-item-absolute {:optional true} :boolean]
[:layout-item-z-index {:optional true} ::sm/safe-number]])
+(def layout-child-attrs
+ (sm/keys schema:layout-child-attrs))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SCHEMAS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -194,8 +183,6 @@
(def valid-layouts
#{:flex :grid})
-(sm/register! ::layout [::sm/one-of valid-layouts])
-
(defn flex-layout?
([objects id]
(flex-layout? (get objects id)))
@@ -754,9 +741,7 @@
([type parent value]
(add-grid-track type parent value nil))
([type parent value index]
- (dm/assert!
- "expected a valid grid definition for `value`"
- (check-grid-track! value))
+ (assert (check-grid-track value))
(let [[tracks-prop tracks-prop-other prop prop-other prop-span prop-span-other]
(if (= type :column)
diff --git a/common/test/common_tests/types/path_data_test.cljc b/common/test/common_tests/types/path_data_test.cljc
index b96d0e8458..aef996608a 100644
--- a/common/test/common_tests/types/path_data_test.cljc
+++ b/common/test/common_tests/types/path_data_test.cljc
@@ -25,6 +25,15 @@
{:command :curve-to :params {:c1x 368.0 :c1y 737.0 :c2x 310.0 :c2y 681.0 :x 264.0 :y 634.0}}
{:command :close-path :params {}}])
+(def sample-content-square
+ [{:command :move-to, :params {:x 0, :y 0}}
+ {:command :line-to, :params {:x 10, :y 0}}
+ {:command :line-to, :params {:x 10, :y 10}}
+ {:command :line-to, :params {:x 10, :y 0}}
+ {:command :line-to, :params {:x 0, :y 10}}
+ {:command :line-to, :params {:x 0, :y 0}}
+ {:command :close-path :params {}}])
+
(def sample-content-large
[{:command :move-to :params {:x 480.0 :y 839.0}}
{:command :line-to :params {:x 439.0 :y 802.0}}
@@ -179,6 +188,42 @@
(t/is (= (vec result1) result2))
(t/is (= result2 result3))))
+(t/deftest path-transform-3
+ (let [matrix (gmt/rotate-matrix 42 (gpt/point 0 0))
+ content (path/content sample-content-square)
+
+ result1 (path/transform-content content matrix)
+ result2 (transform-plain-content sample-content-square matrix)
+ result3 (transform-plain-content content matrix)]
+
+ (t/is (= (count result1) (count result2)))
+ (doseq [[seg-a seg-b] (map vector result1 result2)]
+ (t/is (= (:command seg-a)
+ (:command seg-b)))
+
+ (let [params-a (get seg-a :params)
+ params-b (get seg-b :params)]
+
+ (t/is (mth/close? (get params-a :x 0)
+ (get params-b :x 0)))
+ (t/is (mth/close? (get params-a :y 0)
+ (get params-b :y 0)))))
+
+
+ (doseq [[seg-a seg-b] (map vector result1 result3)]
+ (t/is (= (:command seg-a)
+ (:command seg-b)))
+
+ (let [params-a (get seg-a :params)
+ params-b (get seg-b :params)]
+
+ (t/is (mth/close? (get params-a :x 0)
+ (get params-b :x 0)))
+ (t/is (mth/close? (get params-a :y 0)
+ (get params-b :y 0)))))))
+
+
+
(defn- content->points
"Given a content return all points.
@@ -278,15 +323,6 @@
(t/is (= result2 expect))
(t/is (= result3 expect))))
-(def sample-content-square
- [{:command :move-to, :params {:x 0, :y 0}}
- {:command :line-to, :params {:x 10, :y 0}}
- {:command :line-to, :params {:x 10, :y 10}}
- {:command :line-to, :params {:x 10, :y 0}}
- {:command :line-to, :params {:x 0, :y 10}}
- {:command :line-to, :params {:x 0, :y 0}}
- {:command :close-path :params {}}])
-
(t/deftest points-to-content
(let [initial [(gpt/point 0.0 0.0)
(gpt/point 10.0 10.0)
diff --git a/docker/devenv/files/bashrc b/docker/devenv/files/bashrc
index 6dcc66f191..bb098b2f17 100644
--- a/docker/devenv/files/bashrc
+++ b/docker/devenv/files/bashrc
@@ -1,5 +1,7 @@
#!/usr/bin/env bash
+EMSDK_QUIET=1 . /usr/local/emsdk/emsdk_env.sh;
+
alias l='ls --color -GFlh'
alias rm='rm -r'
alias ls='ls --color -F'
diff --git a/docker/images/docker-compose.yaml b/docker/images/docker-compose.yaml
index a5fc6b57e7..42cb16ce10 100644
--- a/docker/images/docker-compose.yaml
+++ b/docker/images/docker-compose.yaml
@@ -111,7 +111,7 @@ services:
depends_on:
penpot-postgres:
condition: service_healthy
- penpot-redis:
+ penpot-valkey:
condition: service_healthy
networks:
@@ -148,10 +148,10 @@ services:
PENPOT_DATABASE_USERNAME: penpot
PENPOT_DATABASE_PASSWORD: penpot
- ## Redis is used for the websockets notifications. Don't touch unless the redis
- ## container has different parameters or different name.
+ ## Valkey (or previously redis) is used for the websockets notifications. Don't touch
+ ## unless the valkey container has different parameters or different name.
- PENPOT_REDIS_URI: redis://penpot-redis/0
+ PENPOT_REDIS_URI: redis://penpot-valkey/0
## Default configuration for assets storage: using filesystem based with all files
## stored in a docker volume.
@@ -195,7 +195,7 @@ services:
restart: always
depends_on:
- penpot-redis:
+ penpot-valkey:
condition: service_healthy
networks:
@@ -206,8 +206,8 @@ services:
# communicate with the frontend.
PENPOT_PUBLIC_URI: http://penpot-frontend:8080
- ## Redis is used for the websockets notifications.
- PENPOT_REDIS_URI: redis://penpot-redis/0
+ ## Valkey (or previowsly Redis) is used for the websockets notifications.
+ PENPOT_REDIS_URI: redis://penpot-valkey/0
penpot-postgres:
image: "postgres:15"
@@ -233,12 +233,12 @@ services:
- POSTGRES_USER=penpot
- POSTGRES_PASSWORD=penpot
- penpot-redis:
- image: redis:7.2
+ penpot-valkey:
+ image: valkey/valkey:8.1
restart: always
healthcheck:
- test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
+ test: ["CMD-SHELL", "valkey-cli ping | grep PONG"]
interval: 1s
timeout: 3s
retries: 5
diff --git a/docs/plugins/getting-started.md b/docs/plugins/getting-started.md
index b2d2e5e9f5..9765e737b0 100644
--- a/docs/plugins/getting-started.md
+++ b/docs/plugins/getting-started.md
@@ -140,7 +140,8 @@ The manifest.json file contains the basic infor
"user:read",
"comment:read",
"comment:write",
- "allow:downloads"
+ "allow:downloads",
+ "allow:localstorage"
]
}
```
@@ -173,6 +174,9 @@ Typical use cases: adding new comments to pages; deleting existing comments; rep
- allow:downloads: Allows downloading of the project file. Grants access to endpoints and operations that enable the downloading of the entire project file.
Typical use cases: downloading the full project file for backup or sharing.
+- allow:localstorage: Allows the access to the local storage proxy to store information. This info is only available for the plugin installation but be aware that a user can see this information in the browser.
+Typical use cases: storing authentication tokens for a plugin login
+
_Note: Write permissions automatically includes its corresponding read permission (e.g., content:write includes content:read) because reading is required to perform write or modification actions._
### What are plugin.ts and plugin.js files?
diff --git a/docs/technical-guide/configuration.md b/docs/technical-guide/configuration.md
index e4f075e094..b6e3d10071 100644
--- a/docs/technical-guide/configuration.md
+++ b/docs/technical-guide/configuration.md
@@ -353,9 +353,9 @@ If you are not using SMTP configuration and want to log the emails in the consol
PENPOT_FLAGS: [...] enable-log-emails
```
-## Redis
+## Valkey
-The Redis configuration is very simple, just provide a valid redis URI. Redis is used
+The Valkey configuration is very simple, just provide a valid redis URI. Valkey is used
mainly for websocket notifications coordination.
```bash
diff --git a/docs/technical-guide/getting-started/kubernetes.md b/docs/technical-guide/getting-started/kubernetes.md
index d2e9f969d9..142f498947 100644
--- a/docs/technical-guide/getting-started/kubernetes.md
+++ b/docs/technical-guide/getting-started/kubernetes.md
@@ -72,7 +72,7 @@ argument to helm install. For example,
```bash
helm install my-release \
--set global.postgresqlEnabled=true \
- --set global.redisEnabled=true \
+ --set global.valkeyEnabled=true \
--set persistence.assets.enabled=true \
penpot/penpot
```
diff --git a/exporter/src/app/handlers/export_shapes.cljs b/exporter/src/app/handlers/export_shapes.cljs
index 348a68e4a8..9327d29801 100644
--- a/exporter/src/app/handlers/export_shapes.cljs
+++ b/exporter/src/app/handlers/export_shapes.cljs
@@ -47,7 +47,7 @@
(s/def ::params
(s/keys :req-un [::exports ::profile-id]
- :opt-un [::wait ::name]))
+ :opt-un [::wait ::name ::skip-children]))
(defn handler
[{:keys [:request/auth-token] :as exchange} {:keys [exports] :as params}]
@@ -60,7 +60,7 @@
(handle-multiple-export exchange (assoc params :exports exports)))))
(defn- handle-single-export
- [exchange {:keys [export wait profile-id name] :as params}]
+ [exchange {:keys [export wait profile-id name skip-children] :as params}]
(let [topic (str profile-id)
resource (rsc/create (:type export) (or name (:name export)))
@@ -90,7 +90,7 @@
:resource-id (:id resource)
:status "error"
:cause (ex-message cause)})))
-
+ export (assoc export :skip-children skip-children)
proc (-> (rd/render export on-progress)
(p/then (constantly resource))
(p/catch on-error))]
@@ -99,7 +99,7 @@
(assoc exchange :response/body (dissoc resource :path)))))
(defn- handle-multiple-export
- [exchange {:keys [exports wait profile-id name] :as params}]
+ [exchange {:keys [exports wait profile-id name skip-children] :as params}]
(let [resource (rsc/create :zip (or name (-> exports first :name)))
total (count exports)
topic (str profile-id)
@@ -141,7 +141,8 @@
proc (-> (p/do
(p/loop [exports (seq exports)]
- (when-let [export (first exports)]
+ (when-let [export (-> (first exports)
+ (assoc :skip-children skip-children))]
(p/do
(rd/render export append)
(p/recur (rest exports)))))
diff --git a/exporter/src/app/renderer/bitmap.cljs b/exporter/src/app/renderer/bitmap.cljs
index e206bfe9ba..54335be501 100644
--- a/exporter/src/app/renderer/bitmap.cljs
+++ b/exporter/src/app/renderer/bitmap.cljs
@@ -17,7 +17,7 @@
[promesa.core :as p]))
(defn render
- [{:keys [file-id page-id share-id token scale type objects] :as params} on-object]
+ [{:keys [file-id page-id share-id token scale type objects skip-children] :as params} on-object]
(letfn [(prepare-options [uri]
#js {:screen #js {:width bw/default-viewport-width
:height bw/default-viewport-height}
@@ -56,7 +56,8 @@
:page-id page-id
:share-id share-id
:object-id (mapv :id objects)
- :route "objects"}
+ :route "objects"
+ :skip-children skip-children}
uri (-> (cf/get :public-uri)
(assoc :path "/render.html")
(assoc :query (u/map->query-string params)))]
diff --git a/frontend/resources/plugins-runtime/index.js b/frontend/resources/plugins-runtime/index.js
index 07b7a342ca..18b374e80d 100644
--- a/frontend/resources/plugins-runtime/index.js
+++ b/frontend/resources/plugins-runtime/index.js
@@ -3,7 +3,7 @@ var qn = (t) => {
};
var Kn = (t, e, r) => e.has(t) || qn("Cannot " + r);
var at = (t, e, r) => (Kn(t, e, "read from private field"), r ? r.call(t) : e.get(t)), tn = (t, e, r) => e.has(t) ? qn("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, r), fr = (t, e, r, n) => (Kn(t, e, "write to private field"), n ? n.call(t, r) : e.set(t, r), r);
-const x = globalThis, {
+const S = globalThis, {
Array: na,
ArrayBuffer: To,
Date: oa,
@@ -45,12 +45,12 @@ const x = globalThis, {
getOwnPropertyNames: Nt,
getPrototypeOf: G,
is: Zr,
- isFrozen: uu,
- isSealed: du,
- isExtensible: fu,
+ isFrozen: du,
+ isSealed: fu,
+ isExtensible: pu,
keys: Co,
prototype: zr,
- seal: pu,
+ seal: hu,
preventExtensions: da,
setPrototypeOf: wr,
values: Ro,
@@ -74,7 +74,7 @@ const x = globalThis, {
return n;
}, {
apply: ue,
- construct: Sr,
+ construct: xr,
get: ya,
getOwnPropertyDescriptor: _a,
has: Oo,
@@ -82,7 +82,7 @@ const x = globalThis, {
ownKeys: qe,
preventExtensions: ba,
set: Mo
-} = la, { isArray: pt, prototype: ve } = na, { prototype: xr } = To, { prototype: jt } = $e, { prototype: Br } = RegExp, { prototype: cr } = Dt, { prototype: Ge } = _e, { prototype: Gr } = ze, { prototype: Lo } = Ut, { prototype: Vr } = Function, { prototype: Fo } = ca, { prototype: Do } = G(
+} = la, { isArray: pt, prototype: ve } = na, { prototype: Sr } = To, { prototype: jt } = $e, { prototype: Br } = RegExp, { prototype: cr } = Dt, { prototype: Ge } = _e, { prototype: Gr } = ze, { prototype: Lo } = Ut, { prototype: Vr } = Function, { prototype: Fo } = ca, { prototype: Do } = G(
// eslint-disable-next-line no-empty-function, func-names
function* () {
}
@@ -95,9 +95,9 @@ const x = globalThis, {
), jo = (
/** @type {any} */
P(ve.flatMap)
-), Er = P(ve.pop), ne = P(ve.push), wa = P(ve.slice), Zo = P(ve.some), zo = P(ve.sort), Sa = P(ve[De]), xa = P(xr.slice), Ea = P(
+), Er = P(ve.pop), ne = P(ve.push), wa = P(ve.slice), Zo = P(ve.some), zo = P(ve.sort), xa = P(ve[De]), Sa = P(Sr.slice), Ea = P(
// @ts-expect-error we know it is there on all conforming platforms
- ee(xr, "byteLength").get
+ ee(Sr, "byteLength").get
), ka = P(Uo.set), pe = P(jt.set), Ke = P(jt.get), Wr = P(jt.has), Pa = P(jt.delete), Aa = P(jt.entries), Ta = P(jt[De]), In = P(cr.add);
P(cr.delete);
const Yn = P(cr.forEach), Cn = P(cr.has), Ia = P(cr[De]), Rn = P(Br.test), $n = P(Br.exec), Ca = P(Br[$o]), Bo = P(Ge.endsWith), Go = P(Ge.includes), Ra = P(Ge.indexOf);
@@ -180,8 +180,8 @@ const { freeze: ut } = Object, { apply: ja } = Reflect, Ln = (t) => (e, ...r) =>
ut(Xo);
const {
getEnvironmentOption: ce,
- getEnvironmentOptionsList: hu,
- environmentOptionsListHas: mu
+ getEnvironmentOptionsList: mu,
+ environmentOptionsListHas: gu
} = Xo(globalThis, !0), Ar = (t) => (t = `${t}`, t.length >= 1 && Go("aeiouAEIOU", t[0]) ? `an ${t}` : `a ${t}`);
y(Ar);
const Qo = (t, e = void 0) => {
@@ -404,7 +404,7 @@ const eo = new ze(), as = (t, e = t.name) => {
});
}
y(t);
-}, Ce = (t = re`Assert failed`, e = x.Error, {
+}, Ce = (t = re`Assert failed`, e = S.Error, {
errorName: r = void 0,
cause: n = void 0,
errors: o = void 0,
@@ -448,7 +448,7 @@ const Xa = (t) => {
`);
return Ho(e, " ") || r === -1 ? e : Nn(e, r + 1);
}, Ir = {
- getStackString: x.getStackString || Xa,
+ getStackString: S.getStackString || Xa,
tagError: (t) => as(t),
resetErrorTagNum: () => {
yn = 0;
@@ -532,8 +532,8 @@ const Qa = (t) => ue(cs, t, []) !== void 0, ei = (t) => {
});
});
}, ri = () => {
- if (typeof x.harden == "function")
- return x.harden;
+ if (typeof S.harden == "function")
+ return S.harden;
const t = new Ut(), { harden: e } = {
/**
* @template T
@@ -752,7 +752,7 @@ function lt(t) {
cause: !1
};
}
-function Se(t) {
+function xe(t) {
return {
// Properties of the TypedArray Constructors
"[[Proto]]": "%TypedArray%",
@@ -760,7 +760,7 @@ function Se(t) {
prototype: t
};
}
-function xe(t) {
+function Se(t) {
return {
// Properties of the TypedArray Prototype Objects
"[[Proto]]": "%TypedArrayPrototype%",
@@ -1471,39 +1471,39 @@ const so = {
with: a
},
// The TypedArray Constructors
- BigInt64Array: Se("%BigInt64ArrayPrototype%"),
- BigUint64Array: Se("%BigUint64ArrayPrototype%"),
+ BigInt64Array: xe("%BigInt64ArrayPrototype%"),
+ BigUint64Array: xe("%BigUint64ArrayPrototype%"),
// https://github.com/tc39/proposal-float16array
- Float16Array: Se("%Float16ArrayPrototype%"),
- Float32Array: Se("%Float32ArrayPrototype%"),
- Float64Array: Se("%Float64ArrayPrototype%"),
- Int16Array: Se("%Int16ArrayPrototype%"),
- Int32Array: Se("%Int32ArrayPrototype%"),
- Int8Array: Se("%Int8ArrayPrototype%"),
- Uint16Array: Se("%Uint16ArrayPrototype%"),
- Uint32Array: Se("%Uint32ArrayPrototype%"),
- Uint8ClampedArray: Se("%Uint8ClampedArrayPrototype%"),
+ Float16Array: xe("%Float16ArrayPrototype%"),
+ Float32Array: xe("%Float32ArrayPrototype%"),
+ Float64Array: xe("%Float64ArrayPrototype%"),
+ Int16Array: xe("%Int16ArrayPrototype%"),
+ Int32Array: xe("%Int32ArrayPrototype%"),
+ Int8Array: xe("%Int8ArrayPrototype%"),
+ Uint16Array: xe("%Uint16ArrayPrototype%"),
+ Uint32Array: xe("%Uint32ArrayPrototype%"),
+ Uint8ClampedArray: xe("%Uint8ClampedArrayPrototype%"),
Uint8Array: {
- ...Se("%Uint8ArrayPrototype%"),
+ ...xe("%Uint8ArrayPrototype%"),
// https://github.com/tc39/proposal-arraybuffer-base64
fromBase64: a,
// https://github.com/tc39/proposal-arraybuffer-base64
fromHex: a
},
- "%BigInt64ArrayPrototype%": xe("BigInt64Array"),
- "%BigUint64ArrayPrototype%": xe("BigUint64Array"),
+ "%BigInt64ArrayPrototype%": Se("BigInt64Array"),
+ "%BigUint64ArrayPrototype%": Se("BigUint64Array"),
// https://github.com/tc39/proposal-float16array
- "%Float16ArrayPrototype%": xe("Float16Array"),
- "%Float32ArrayPrototype%": xe("Float32Array"),
- "%Float64ArrayPrototype%": xe("Float64Array"),
- "%Int16ArrayPrototype%": xe("Int16Array"),
- "%Int32ArrayPrototype%": xe("Int32Array"),
- "%Int8ArrayPrototype%": xe("Int8Array"),
- "%Uint16ArrayPrototype%": xe("Uint16Array"),
- "%Uint32ArrayPrototype%": xe("Uint32Array"),
- "%Uint8ClampedArrayPrototype%": xe("Uint8ClampedArray"),
+ "%Float16ArrayPrototype%": Se("Float16Array"),
+ "%Float32ArrayPrototype%": Se("Float32Array"),
+ "%Float64ArrayPrototype%": Se("Float64Array"),
+ "%Int16ArrayPrototype%": Se("Int16Array"),
+ "%Int32ArrayPrototype%": Se("Int32Array"),
+ "%Int8ArrayPrototype%": Se("Int8Array"),
+ "%Uint16ArrayPrototype%": Se("Uint16Array"),
+ "%Uint32ArrayPrototype%": Se("Uint32Array"),
+ "%Uint8ClampedArrayPrototype%": Se("Uint8ClampedArray"),
"%Uint8ArrayPrototype%": {
- ...xe("Uint8Array"),
+ ...Se("Uint8Array"),
// https://github.com/tc39/proposal-arraybuffer-base64
setFromBase64: a,
// https://github.com/tc39/proposal-arraybuffer-base64
@@ -2031,7 +2031,7 @@ const ms = (t) => {
finalIntrinsics: s,
isPseudoNative: i
};
- return y(c), n(us), n(hs(x, ds)), c;
+ return y(c), n(us), n(hs(S, ds)), c;
}, ii = (t, e) => {
const { addIntrinsics: r, finalIntrinsics: n } = ms(e);
return r(hs(t, fs)), n();
@@ -2123,7 +2123,7 @@ function ci(t, e, r) {
const m = p["[[Proto]]"];
i(f, h, m), typeof h == "function" && e(h);
for (const A of qe(h)) {
- const S = s(f, A), w = `${f}.${S}`, R = u(h, p, S);
+ const x = s(f, A), w = `${f}.${x}`, R = u(h, p, x);
(!R || !l(w, h, A, R)) && ls(h, A, R === !1, w, r);
}
}
@@ -2190,7 +2190,7 @@ function ui(t = "safe") {
}, o = ({ powers: c = "none" } = {}) => {
let l;
return c === "original" ? l = function(...d) {
- return new.target === void 0 ? ue(e, void 0, d) : Sr(e, d, new.target);
+ return new.target === void 0 ? ue(e, void 0, d) : xr(e, d, new.target);
} : l = function(...d) {
if (new.target === void 0)
throw _(
@@ -2200,7 +2200,7 @@ function ui(t = "safe") {
throw _(
"secure mode Calling new %SharedDate%() with no arguments throws"
);
- return Sr(e, d, new.target);
+ return xr(e, d, new.target);
}, B(l, {
length: { value: 7 },
prototype: {
@@ -2274,7 +2274,7 @@ function fi(t = "safe") {
throw _(`unrecognized regExpTaming ${t}`);
const e = Xe.prototype, r = (s = {}) => {
const i = function(...l) {
- return new.target === void 0 ? Xe(...l) : Sr(Xe, l, new.target);
+ return new.target === void 0 ? Xe(...l) : xr(Xe, l, new.target);
};
if (B(i, {
length: { value: 2 },
@@ -2479,7 +2479,7 @@ function mi(t, e, { warn: r }, n = []) {
const o = new Dt(n);
function s(d, f, h, p) {
if ("value" in p && p.configurable) {
- const { value: m } = p, A = Cn(o, h), { get: S, set: w } = ee(
+ const { value: m } = p, A = Cn(o, h), { get: x, set: w } = ee(
{
get [h]() {
return m;
@@ -2501,13 +2501,13 @@ function mi(t, e, { warn: r }, n = []) {
},
h
);
- D(S, "originalValue", {
+ D(x, "originalValue", {
value: m,
writable: !1,
enumerable: !1,
configurable: !1
}), D(f, h, {
- get: S,
+ get: x,
set: w,
enumerable: p.enumerable,
configurable: p.configurable
@@ -2527,13 +2527,13 @@ function mi(t, e, { warn: r }, n = []) {
const m = ee(f, p);
if (!m || m.get || m.set)
continue;
- const A = `${d}.${_e(p)}`, S = h[p];
- if (S === !0)
+ const A = `${d}.${_e(p)}`, x = h[p];
+ if (x === !0)
i(A, f, p);
- else if (S === "*")
+ else if (x === "*")
c(A, m.value);
- else if (ke(S))
- l(A, m.value, S);
+ else if (ke(x))
+ l(A, m.value, x);
else
throw _(`Unexpected override enablement plan ${A}`);
}
@@ -2619,7 +2619,7 @@ ${o}
configurable: !1
}
}), G(Ee) === Ee.prototype || ao`Function prototype is the same accross compartments`, G(e) === Ee.prototype || ao`Function constructor prototype is the same accross compartments`, e;
-}, Si = (t) => {
+}, xi = (t) => {
D(
t,
fa,
@@ -2701,11 +2701,11 @@ ${o}
configurable: !0
});
}
-}, { Fail: xi, quote: bs } = Y, ws = new Ur(
+}, { Fail: Si, quote: bs } = Y, ws = new Ur(
Mn,
y({
get(t, e) {
- xi`Please report unexpected scope handler trap: ${bs(_e(e))}`;
+ Si`Please report unexpected scope handler trap: ${bs(_e(e))}`;
}
})
), Ei = {
@@ -2715,7 +2715,7 @@ ${o}
throw Wt(`${_e(e)} is not defined`);
},
has(t, e) {
- return e in x;
+ return e in S;
},
// note: this is likely a bug of safari
// https://bugs.webkit.org/show_bug.cgi?id=195534
@@ -2736,18 +2736,18 @@ ${o}
ownKeys(t) {
return [];
}
-}, Ss = y(
+}, xs = y(
H(
ws,
Be(Ei)
)
), ki = new Ur(
Mn,
- Ss
-), xs = (t) => {
+ xs
+), Ss = (t) => {
const e = {
// inherit scopeTerminator behavior
- ...Ss,
+ ...xs,
// Redirect set properties to the globalObject.
set(o, s, i) {
return Mo(t, s, i);
@@ -2767,7 +2767,7 @@ ${o}
r
);
};
-y(xs);
+y(Ss);
const { Fail: Pi } = Y, Ai = () => {
const t = H(null), e = y({
eval: {
@@ -2978,7 +2978,7 @@ const Ni = (t) => {
globalTransforms: r = [],
sloppyGlobalsMode: n = !1
}) => {
- const o = n ? xs(t) : ki, s = Ai(), { evalScope: i } = s, c = y({
+ const o = n ? Ss(t) : ki, s = Ai(), { evalScope: i } = s, c = y({
evalScope: i,
moduleLexicals: e,
globalObject: t,
@@ -3028,7 +3028,7 @@ function Li(t = "safe") {
throw _(`unrecognized domainTaming ${t}`);
if (t === "unsafe")
return;
- const e = x.process || void 0;
+ const e = S.process || void 0;
if (typeof e == "object") {
const r = ee(e, "domain");
if (r !== void 0 && r.get !== void 0)
@@ -3044,7 +3044,7 @@ function Li(t = "safe") {
}
}
const Fi = () => {
- const t = {}, e = x.ModuleSource;
+ const t = {}, e = S.ModuleSource;
if (e !== void 0) {
let n = function() {
};
@@ -3142,38 +3142,38 @@ y(dt);
const zn = (t, e) => {
if (!t)
return;
- const { getStackString: r, tagError: n, takeMessageLogArgs: o, takeNoteLogArgsArray: s } = e, i = (S, w) => de(S, (T) => Kr(T) ? (ne(w, T), `(${n(T)})`) : T), c = (S, w, R, T, j) => {
+ const { getStackString: r, tagError: n, takeMessageLogArgs: o, takeNoteLogArgsArray: s } = e, i = (x, w) => de(x, (T) => Kr(T) ? (ne(w, T), `(${n(T)})`) : T), c = (x, w, R, T, j) => {
const I = n(w), L = R === dt.MESSAGE ? `${I}:` : `${I} ${R}`, Z = i(T, j);
- t[S](L, ...Z);
- }, l = (S, w, R = void 0) => {
+ t[x](L, ...Z);
+ }, l = (x, w, R = void 0) => {
if (w.length === 0)
return;
if (w.length === 1 && R === void 0) {
- f(S, w[0]);
+ f(x, w[0]);
return;
}
let T;
w.length === 1 ? T = "Nested error" : T = `Nested ${w.length} errors`, R !== void 0 && (T = `${T} under ${R}`), t.group(T);
try {
for (const j of w)
- f(S, j);
+ f(x, j);
} finally {
t.groupEnd();
}
- }, u = new Ut(), d = (S) => (w, R) => {
+ }, u = new Ut(), d = (x) => (w, R) => {
const T = [];
- c(S, w, dt.NOTE, R, T), l(S, T, n(w));
- }, f = (S, w) => {
+ c(x, w, dt.NOTE, R, T), l(x, T, n(w));
+ }, f = (x, w) => {
if (lr(u, w))
return;
const R = n(w);
qr(u, w);
const T = [], j = o(w), I = s(
w,
- d(S)
+ d(x)
);
- j === void 0 ? t[S](`${R}:`, w.message) : c(
- S,
+ j === void 0 ? t[x](`${R}:`, w.message) : c(
+ x,
w,
dt.MESSAGE,
j,
@@ -3182,24 +3182,24 @@ const zn = (t, e) => {
let L = r(w);
typeof L == "string" && L.length >= 1 && !Bo(L, `
`) && (L += `
-`), t[S](L), w.cause && c(S, w, dt.CAUSE, [w.cause], T), w.errors && c(S, w, dt.ERRORS, w.errors, T);
+`), t[x](L), w.cause && c(x, w, dt.CAUSE, [w.cause], T), w.errors && c(x, w, dt.ERRORS, w.errors, T);
for (const Z of I)
- c(S, w, dt.NOTE, Z, T);
- l(S, T, R);
- }, h = de(jn, ([S, w]) => {
+ c(x, w, dt.NOTE, Z, T);
+ l(x, T, R);
+ }, h = de(jn, ([x, w]) => {
const R = (...T) => {
const j = [], I = i(T, j);
- t[S] && t[S](...I), l(S, j);
+ t[x] && t[x](...I), l(x, j);
};
- return D(R, "name", { value: S }), [S, y(R)];
+ return D(R, "name", { value: x }), [x, y(R)];
}), p = et(
Zn,
- ([S, w]) => S in t
- ), m = de(p, ([S, w]) => {
+ ([x, w]) => x in t
+ ), m = de(p, ([x, w]) => {
const R = (...T) => {
- t[S](...T);
+ t[x](...T);
};
- return D(R, "name", { value: S }), [S, y(R)];
+ return D(R, "name", { value: x }), [x, y(R)];
}), A = bt([...h, ...m]);
return (
/** @type {VirtualConsole} */
@@ -3293,13 +3293,13 @@ const fo = (t) => {
const s = (
/** @type {VirtualConsole} */
// eslint-disable-next-line no-nested-ternary
- typeof x.console < "u" ? x.console : typeof x.print == "function" ? (
+ typeof S.console < "u" ? S.console : typeof S.print == "function" ? (
// Make a good-enough console for eshost (including only functions that
// log at a specific level with no special argument interpretation).
// https://console.spec.whatwg.org/#logging
((u) => y({ debug: u, log: u, info: u, warn: u, error: u }))(
// eslint-disable-next-line no-undef
- po(x.print)
+ po(S.print)
)
) : void 0
);
@@ -3311,7 +3311,7 @@ const fo = (t) => {
const i = (
/** @type {VirtualConsole} */
t === "unsafe" ? s : zn(s, o)
- ), c = x.process || void 0;
+ ), c = S.process || void 0;
if (e !== "none" && typeof c == "object" && typeof c.on == "function") {
let u;
if (e === "platform" || e === "exit") {
@@ -3328,7 +3328,7 @@ const fo = (t) => {
});
d && (c.on("unhandledRejection", d.unhandledRejectionHandler), c.on("rejectionHandled", d.rejectionHandledHandler), c.on("exit", d.processTerminationHandler));
}
- const l = x.window || void 0;
+ const l = S.window || void 0;
if (e !== "none" && typeof l == "object" && typeof l.addEventListener == "function" && l.addEventListener("error", (u) => {
u.preventDefault(), i.error("SES_UNCAUGHT_EXCEPTION:", u.error), (e === "exit" || e === "abort") && (l.location.href = "about:blank");
}), r !== "none" && typeof l == "object" && typeof l.addEventListener == "function") {
@@ -3444,8 +3444,8 @@ const fo = (t) => {
if (lr(f, p))
return p;
const m = {
- prepareStackTrace(A, S) {
- return he(l, A, { callSites: S }), p(A, Gi(S));
+ prepareStackTrace(A, x) {
+ return he(l, A, { callSites: x }), p(A, Gi(x));
}
};
return qr(f, m.prepareStackTrace), m.prepareStackTrace;
@@ -3486,7 +3486,7 @@ function nc(t = "safe", e = "concise") {
const r = le.prototype, { captureStackTrace: n } = le, o = typeof n == "function" ? "v8" : "unknown", s = (l = {}) => {
const u = function(...f) {
let h;
- return new.target === void 0 ? h = ue(le, this, f) : h = Sr(le, f, new.target), o === "v8" && ue(n, le, [h, u]), h;
+ return new.target === void 0 ? h = ue(le, this, f) : h = xr(le, f, new.target), o === "v8" && ue(n, le, [h, u]), h;
};
return B(u, {
length: { value: 1 },
@@ -3850,7 +3850,7 @@ function* lc(t, e, r, n, o, s, i) {
);
return pe(f, n, w), w;
}
- const S = Bt(
+ const x = Bt(
t,
e,
r,
@@ -3860,7 +3860,7 @@ function* lc(t, e, r, n, o, s, i) {
s,
i
);
- return pe(f, n, S), S;
+ return pe(f, n, x), x;
} else
throw Ce(
re`module descriptor must be a string or object for specifier ${U(
@@ -3967,7 +3967,7 @@ const It = (t, e, r, n, o, s, i) => {
o
)}`
});
-}, { quote: xt } = Y, hc = () => {
+}, { quote: St } = Y, hc = () => {
let t = !1;
const e = H(null, {
// Make this appear like an ESM module namespace object.
@@ -3987,7 +3987,7 @@ const It = (t, e, r, n, o, s, i) => {
get(r, n, o) {
if (!t)
throw _(
- `Cannot get property ${xt(
+ `Cannot get property ${St(
n
)} of module exports namespace, the module has not yet begun to execute`
);
@@ -3995,13 +3995,13 @@ const It = (t, e, r, n, o, s, i) => {
},
set(r, n, o) {
throw _(
- `Cannot set property ${xt(n)} of module exports namespace`
+ `Cannot set property ${St(n)} of module exports namespace`
);
},
has(r, n) {
if (!t)
throw _(
- `Cannot check property ${xt(
+ `Cannot check property ${St(
n
)}, the module has not yet begun to execute`
);
@@ -4009,7 +4009,7 @@ const It = (t, e, r, n, o, s, i) => {
},
deleteProperty(r, n) {
throw _(
- `Cannot delete property ${xt(n)}s of module exports namespace`
+ `Cannot delete property ${St(n)}s of module exports namespace`
);
},
ownKeys(r) {
@@ -4022,7 +4022,7 @@ const It = (t, e, r, n, o, s, i) => {
getOwnPropertyDescriptor(r, n) {
if (!t)
throw _(
- `Cannot get own property descriptor ${xt(
+ `Cannot get own property descriptor ${St(
n
)}, the module has not yet begun to execute`
);
@@ -4050,7 +4050,7 @@ const It = (t, e, r, n, o, s, i) => {
},
defineProperty(r, n, o) {
throw _(
- `Cannot define property ${xt(n)} of module exports namespace`
+ `Cannot define property ${St(n)} of module exports namespace`
);
},
apply(r, n, o) {
@@ -4131,15 +4131,15 @@ const It = (t, e, r, n, o, s, i) => {
const p = [];
D(c, f, {
get: () => h,
- set: (S) => {
- h = S;
+ set: (x) => {
+ h = x;
for (const w of p)
- w(S);
+ w(x);
},
enumerable: !0,
configurable: !1
- }), u[f] = (S) => {
- ne(p, S), S(h);
+ }), u[f] = (x) => {
+ ne(p, x), x(h);
};
}), u["*"] = (f) => {
f(c);
@@ -4178,7 +4178,7 @@ const It = (t, e, r, n, o, s, i) => {
__reexportMap__: h = {},
__needsImportMeta__: p = !1,
__syncModuleFunctor__: m
- } = i, A = z(t, o), { __shimTransforms__: S, importMetaHook: w } = A, { exportsProxy: R, exportsTarget: T, activate: j } = Bn(
+ } = i, A = z(t, o), { __shimTransforms__: x, importMetaHook: w } = A, { exportsProxy: R, exportsTarget: T, activate: j } = Bn(
o,
A,
e,
@@ -4231,7 +4231,7 @@ const It = (t, e, r, n, o, s, i) => {
`binding ${mr(we)} not yet initialized`
);
return ie;
- }, St = y((Ie) => {
+ }, xt = y((Ie) => {
ie = Ie, ge = !1;
for (const en of te)
en(Ie);
@@ -4245,14 +4245,14 @@ const It = (t, e, r, n, o, s, i) => {
ae = {
get: Ae,
notify: (Ie) => {
- Ie !== St && (ne(te, Ie), ge || Ie(ie));
+ Ie !== xt && (ne(te, Ie), ge || Ie(ie));
}
}, be[W] = ae, q && D(L, W, {
get: Ae,
set: Te,
enumerable: !0,
configurable: !1
- }), se[W] = St;
+ }), se[W] = xt;
}
I[we] = {
get: ae.get,
@@ -4274,13 +4274,13 @@ const It = (t, e, r, n, o, s, i) => {
ie.execute();
const { notifiers: ge } = ie;
for (const [te, Ae] of ae) {
- const St = ge[te];
- if (!St)
+ const xt = ge[te];
+ if (!xt)
throw ir(
`The requested module '${q}' does not provide an export named '${te}'`
);
for (const Te of Ae)
- St(Te);
+ xt(Te);
}
if (Hr(l, q))
for (const [te, Ae] of me(
@@ -4312,7 +4312,7 @@ const It = (t, e, r, n, o, s, i) => {
let wt;
m !== void 0 ? wt = m : wt = Fs(A, u, {
globalObject: o.globalThis,
- transforms: S,
+ transforms: x,
__moduleShimLexicals__: L
});
let Pe = !1, st;
@@ -4352,7 +4352,7 @@ const It = (t, e, r, n, o, s, i) => {
o
)}`
);
- return xc(t, e, i);
+ return Sc(t, e, i);
};
function _c(t) {
return typeof t.__syncModuleProgram__ == "string";
@@ -4374,7 +4374,7 @@ function wc(t, e) {
r
)}, for module ${X(e)}`;
}
-function Sc(t, e) {
+function xc(t, e) {
ke(t) || ft`Invalid module source: must be of type object, got ${X(
t
)}, for module ${X(e)}`;
@@ -4387,11 +4387,11 @@ function Sc(t, e) {
o
)}, for module ${X(e)}`;
}
-const xc = (t, e, r) => {
+const Sc = (t, e, r) => {
const { compartment: n, moduleSpecifier: o, resolvedImports: s, moduleSource: i } = r, { instances: c } = z(t, n);
if (Wr(c, o))
return Ke(c, o);
- Sc(i, o);
+ xc(i, o);
const l = new $e();
let u;
if (_c(i))
@@ -4545,7 +4545,7 @@ const Ec = (...t) => {
modules: r
};
}
-}, Sn = (t, e, r, n = void 0) => {
+}, xn = (t, e, r, n = void 0) => {
function o(...s) {
if (new.target === void 0)
throw _(
@@ -4562,9 +4562,9 @@ const Ec = (...t) => {
importNowHook: p,
moduleMapHook: m,
importMetaHook: A,
- __noNamespaceBox__: S = !1
+ __noNamespaceBox__: x = !1
} = Ec(...s), w = [...c, ...l], R = { __proto__: null, ...u }, T = { __proto__: null, ...d }, j = new $e(), I = new $e(), L = new $e(), Z = {};
- Si(Z), _s(Z);
+ xi(Z), _s(Z);
const { safeEvaluate: se } = Un({
globalObject: Z,
globalTransforms: w,
@@ -4596,7 +4596,7 @@ const Ec = (...t) => {
deferredExports: L,
instances: I,
parentCompartment: n,
- noNamespaceBox: S
+ noNamespaceBox: x
});
}
return o.prototype = Vn, o;
@@ -4608,10 +4608,10 @@ function kc() {
return arguments;
}
const Pc = () => {
- const t = Ee.prototype.constructor, e = ee(kc(), "callee"), r = e && e.get, n = Na(new _e()), o = G(n), s = Br[$o] && Ca(/./), i = s && G(s), c = Sa([]), l = G(c), u = G(sa), d = Ta(new $e()), f = G(d), h = Ia(new Dt()), p = G(h), m = G(l);
+ const t = Ee.prototype.constructor, e = ee(kc(), "callee"), r = e && e.get, n = Na(new _e()), o = G(n), s = Br[$o] && Ca(/./), i = s && G(s), c = xa([]), l = G(c), u = G(sa), d = Ta(new $e()), f = G(d), h = Ia(new Dt()), p = G(h), m = G(l);
function* A() {
}
- const S = dn(A), w = S.prototype;
+ const x = dn(A), w = x.prototype;
async function* R() {
}
const T = dn(
@@ -4628,7 +4628,7 @@ const Pc = () => {
"%AsyncGeneratorPrototype%": I,
"%AsyncIteratorPrototype%": L,
"%Generator%": w,
- "%InertGeneratorFunction%": S,
+ "%InertGeneratorFunction%": x,
"%IteratorPrototype%": m,
"%MapIteratorPrototype%": f,
"%RegExpStringIteratorPrototype%": i,
@@ -4638,22 +4638,22 @@ const Pc = () => {
"%TypedArray%": u,
"%InertCompartment%": Gn
};
- return x.Iterator && (J["%IteratorHelperPrototype%"] = G(
+ return S.Iterator && (J["%IteratorHelperPrototype%"] = G(
// eslint-disable-next-line @endo/no-polymorphic-call
- x.Iterator.from([]).take(0)
+ S.Iterator.from([]).take(0)
), J["%WrapForValidIteratorPrototype%"] = G(
// eslint-disable-next-line @endo/no-polymorphic-call
- x.Iterator.from({
+ S.Iterator.from({
next() {
return { value: void 0 };
}
})
- )), x.AsyncIterator && (J["%AsyncIteratorHelperPrototype%"] = G(
+ )), S.AsyncIterator && (J["%AsyncIteratorHelperPrototype%"] = G(
// eslint-disable-next-line @endo/no-polymorphic-call
- x.AsyncIterator.from([]).take(0)
+ S.AsyncIterator.from([]).take(0)
), J["%WrapForValidAsyncIteratorPrototype%"] = G(
// eslint-disable-next-line @endo/no-polymorphic-call
- x.AsyncIterator.from({ next() {
+ S.AsyncIterator.from({ next() {
} })
)), J;
}, Us = (t, e) => {
@@ -4734,10 +4734,10 @@ const Ac = () => {
}
});
}, Rc = () => {
- if (typeof xr.transfer == "function")
+ if (typeof Sr.transfer == "function")
return {};
- const t = x.structuredClone;
- return typeof t != "function" ? {} : (D(xr, "transfer", {
+ const t = S.structuredClone;
+ return typeof t != "function" ? {} : (D(Sr, "transfer", {
// @ts-expect-error
value: {
/**
@@ -4753,7 +4753,7 @@ const Ac = () => {
const o = new To(r), s = new mn(this), i = new mn(o);
return ka(i, s), t(this, { transfer: [this] }), o;
} else {
- const o = xa(this, 0, r);
+ const o = Sa(this, 0, r);
return t(this, { transfer: [this] }), o;
}
}
@@ -4790,13 +4790,13 @@ const Ac = () => {
return gr(vo);
if (t !== "platform" && t !== "console")
throw new _(`Invalid lockdown reporting option: ${t}`);
- if (t === "console" || x.window === x || x.importScripts !== void 0)
+ if (t === "console" || S.window === S || S.importScripts !== void 0)
return console;
- if (x.console !== void 0) {
- const e = x.console, r = Wo(e.error, e);
+ if (S.console !== void 0) {
+ const e = S.console, r = Wo(e.error, e);
return gr(r);
}
- return x.print !== void 0 ? gr(x.print) : gr(vo);
+ return S.print !== void 0 ? gr(S.print) : gr(vo);
}, bo = (t, e, r) => {
const { warn: n, error: o, groupCollapsed: s, groupEnd: i } = e;
let c = !1;
@@ -4823,7 +4823,7 @@ const $c = ri(), Nc = () => {
` eval("SES_changed = true");
return SES_changed;
`
- )(Ko, !1), t || delete x.SES_changed;
+ )(Ko, !1), t || delete S.SES_changed;
} catch {
t = !0;
}
@@ -4871,7 +4871,7 @@ const $c = ri(), Nc = () => {
__hardenTaming__: m = ce("LOCKDOWN_HARDEN_TAMING", "safe"),
dateTaming: A = "safe",
// deprecated
- mathTaming: S = "safe",
+ mathTaming: x = "safe",
// deprecated
...w
} = t;
@@ -4883,20 +4883,20 @@ const $c = ri(), Nc = () => {
Y.fail(
wo`Already locked down at ${yr} (SES_ALREADY_LOCKED_DOWN)`,
_
- ), yr = _("Prior lockdown (SES_ALREADY_LOCKED_DOWN)"), yr.stack, Nc(), x.Function.prototype.constructor !== x.Function && // @ts-ignore harden is absent on globalThis type def.
- typeof x.harden == "function" && // @ts-ignore lockdown is absent on globalThis type def.
- typeof x.lockdown == "function" && x.Date.prototype.constructor !== x.Date && typeof x.Date.now == "function" && // @ts-ignore does not recognize that Date constructor is a special
+ ), yr = _("Prior lockdown (SES_ALREADY_LOCKED_DOWN)"), yr.stack, Nc(), S.Function.prototype.constructor !== S.Function && // @ts-ignore harden is absent on globalThis type def.
+ typeof S.harden == "function" && // @ts-ignore lockdown is absent on globalThis type def.
+ typeof S.lockdown == "function" && S.Date.prototype.constructor !== S.Date && typeof S.Date.now == "function" && // @ts-ignore does not recognize that Date constructor is a special
// Function.
// eslint-disable-next-line @endo/no-polymorphic-call
- Zr(x.Date.prototype.constructor.now(), NaN))
+ Zr(S.Date.prototype.constructor.now(), NaN))
throw _(
"Already locked down but not by this SES instance (SES_MULTIPLE_INSTANCES)"
);
Li(d);
const I = Ns(), { addIntrinsics: L, completePrototypes: Z, finalIntrinsics: se } = ms(T), J = Us($c, m);
- L({ harden: J }), L(li()), L(ui(A)), L(nc(e, u)), L(di(S)), L(fi(s)), L(Ac()), L(Rc()), L(Fi()), L(Pc()), Z();
+ L({ harden: J }), L(li()), L(ui(A)), L(nc(e, u)), L(di(x)), L(fi(s)), L(Ac()), L(Rc()), L(Fi()), L(Pc()), Z();
const be = se(), Me = { __proto__: null };
- typeof x.Buffer == "function" && (Me.Buffer = x.Buffer);
+ typeof S.Buffer == "function" && (Me.Buffer = S.Buffer);
let dr;
e === "safe" && (dr = be["%InitialGetStackString%"]);
const zt = Zi(
@@ -4905,13 +4905,13 @@ const $c = ri(), Nc = () => {
o,
dr
);
- if (x.console = /** @type {Console} */
+ if (S.console = /** @type {Console} */
zt.console, typeof /** @type {any} */
zt.console._times == "object" && (Me.SafeMap = G(
// eslint-disable-next-line no-underscore-dangle
/** @type {any} */
zt.console._times
- )), (e === "unsafe" || e === "unsafe-debug") && x.assert === Y && (x.assert = Xr(void 0, !0)), vi(be, i), Ic(be), bo(
+ )), (e === "unsafe" || e === "unsafe-debug") && S.assert === Y && (S.assert = Xr(void 0, !0)), vi(be, i), Ic(be), bo(
"SES Removing unpermitted intrinsics",
T,
(Pe) => ci(
@@ -4919,21 +4919,21 @@ const $c = ri(), Nc = () => {
I,
Pe
)
- ), _s(x), vs(x, {
+ ), _s(S), vs(S, {
intrinsics: be,
newGlobalPropertyNames: ro,
- makeCompartmentConstructor: Sn,
+ makeCompartmentConstructor: xn,
markVirtualizedNativeFunction: I
}), f === "noEval")
wn(
- x,
+ S,
Fa,
I
);
else if (f === "safeEval") {
- const { safeEvaluate: Pe } = Un({ globalObject: x });
+ const { safeEvaluate: Pe } = Un({ globalObject: S });
wn(
- x,
+ S,
Pe,
I
);
@@ -4960,43 +4960,43 @@ const $c = ri(), Nc = () => {
hostIntrinsics: Me,
globals: {
// Harden evaluators
- Function: x.Function,
- eval: x.eval,
+ Function: S.Function,
+ eval: S.eval,
// @ts-ignore Compartment does exist on globalThis
- Compartment: x.Compartment,
+ Compartment: S.Compartment,
// Harden Symbol
- Symbol: x.Symbol
+ Symbol: S.Symbol
}
};
for (const st of Nt(ro))
- Pe.globals[st] = x[st];
+ Pe.globals[st] = S[st];
return J(Pe), J;
};
};
-x.lockdown = (t) => {
+S.lockdown = (t) => {
const e = Zs(t);
- x.harden = e();
+ S.harden = e();
};
-x.repairIntrinsics = (t) => {
+S.repairIntrinsics = (t) => {
const e = Zs(t);
- x.hardenIntrinsics = () => {
- x.harden = e();
+ S.hardenIntrinsics = () => {
+ S.harden = e();
};
};
const Oc = Ns(), Mc = js("none");
-x.Compartment = Sn(
- Sn,
+S.Compartment = xn(
+ xn,
// Any reporting that would need to be done should have already been done
// during `lockdown()`.
// See https://github.com/endojs/endo/pull/2624#discussion_r1840979770
- ii(x, Mc),
+ ii(S, Mc),
Oc
);
-x.assert = Y;
+S.assert = Y;
const Lc = Ms(Ir), Fc = ha(
"MAKE_CAUSAL_CONSOLE_FROM_LOGGER_KEY_FOR_SES_AVA"
);
-x[Fc] = Lc;
+S[Fc] = Lc;
const Dc = (t, e = t, r) => {
let n = { x: 0, y: 0 }, o = { x: 0, y: 0 }, s = { x: 0, y: 0 };
const i = (u) => {
@@ -5027,16 +5027,19 @@ function jc(t, e, r, n, o) {
), s.setAttribute("title", t), s.setAttribute("iframe-src", e), o && s.setAttribute("allow-downloads", "true"), document.body.appendChild(s), s;
}
function zs(t, e = 335, r = 590) {
- const s = e > window.innerWidth ? window.innerWidth - 290 : e, i = parseInt(
- t.style.getPropertyValue("--modal-block-start") || "40",
- 10
- ), c = window.innerHeight - i;
- return e = Math.min(e, s), r = Math.min(r, c), e = Math.max(e, 200), r = Math.max(r, 200), t.wrapper.style.width = `${e}px`, t.wrapper.style.minWidth = `${e}px`, t.wrapper.style.height = `${r}px`, t.wrapper.style.minHeight = `${r}px`, { width: e, height: r };
+ var d;
+ let s = (d = t.shadowRoot) == null ? void 0 : d.querySelector(".wrapper"), i = 0, c = 0;
+ if (s) {
+ let f = s.getBoundingClientRect();
+ i = f.x, c = f.y;
+ }
+ const l = window.innerWidth - i - 40, u = window.innerHeight - c - 40;
+ return e = Math.min(e, l), r = Math.min(r, u), e = Math.max(e, 200), r = Math.max(r, 200), t.wrapper.style.width = `${e}px`, t.wrapper.style.minWidth = `${e}px`, t.wrapper.style.height = `${r}px`, t.wrapper.style.minHeight = `${r}px`, { width: e, height: r };
}
const Zc = `
-`;
+`, zc = 3;
var We, Rt;
-class zc extends HTMLElement {
+class Bc extends HTMLElement {
constructor() {
super();
tn(this, We);
@@ -5054,7 +5057,7 @@ class zc extends HTMLElement {
(r = at(this, Rt)) == null || r.call(this);
}
calculateZIndex() {
- const r = document.querySelectorAll("plugin-modal"), n = Array.from(r).filter((s) => s !== this).map((s) => Number(s.style.zIndex)), o = Math.max(...n, 0);
+ const r = document.querySelectorAll("plugin-modal"), n = Array.from(r).filter((s) => s !== this).map((s) => Number(s.style.zIndex)), o = Math.max(...n, zc);
this.style.zIndex = (o + 1).toString();
}
connectedCallback() {
@@ -5108,7 +5111,7 @@ class zc extends HTMLElement {
}
}
We = new WeakMap(), Rt = new WeakMap();
-customElements.define("plugin-modal", zc);
+customElements.define("plugin-modal", Bc);
var F;
(function(t) {
t.assertEqual = (o) => o;
@@ -5145,14 +5148,14 @@ var F;
}
t.joinValues = n, t.jsonStringifyReplacer = (o, s) => typeof s == "bigint" ? s.toString() : s;
})(F || (F = {}));
-var xn;
+var Sn;
(function(t) {
t.mergeShapes = (e, r) => ({
...e,
...r
// second overwrites first
});
-})(xn || (xn = {}));
+})(Sn || (Sn = {}));
const b = F.arrayToEnum([
"string",
"nan",
@@ -5212,7 +5215,7 @@ const b = F.arrayToEnum([
"invalid_intersection_types",
"not_multiple_of",
"not_finite"
-]), Bc = (t) => JSON.stringify(t, null, 2).replace(/"([^"]+)":/g, "$1:");
+]), Gc = (t) => JSON.stringify(t, null, 2).replace(/"([^"]+)":/g, "$1:");
class ye extends Error {
get errors() {
return this.issues;
@@ -5330,7 +5333,7 @@ const Mt = (t, e) => {
return { message: r };
};
let Bs = Mt;
-function Gc(t) {
+function Vc(t) {
Bs = t;
}
function $r() {
@@ -5356,7 +5359,7 @@ const Nr = (t) => {
path: s,
message: c
};
-}, Vc = [];
+}, Hc = [];
function v(t, e) {
const r = $r(), n = Nr({
issueData: e,
@@ -5440,7 +5443,7 @@ class je {
return this._cachedPath.length || (this._key instanceof Array ? this._cachedPath.push(...this._path, ...this._key) : this._cachedPath.push(...this._path, this._key)), this._cachedPath;
}
}
-const So = (t, e) => {
+const xo = (t, e) => {
if (yt(e))
return { success: !0, data: e.value };
if (!t.common.issues.length)
@@ -5527,7 +5530,7 @@ class O {
data: e,
parsedType: He(e)
}, s = this._parseSync({ data: e, path: o.path, parent: o });
- return So(o, s);
+ return xo(o, s);
}
"~validate"(e) {
var r, n;
@@ -5581,7 +5584,7 @@ class O {
data: e,
parsedType: He(e)
}, o = this._parse({ data: e, path: n.path, parent: n }), s = await (qt(o) ? o : Promise.resolve(o));
- return So(n, s);
+ return xo(n, s);
}
refine(e, r) {
const n = (o) => typeof r == "string" || typeof r > "u" ? { message: r } : typeof r == "function" ? r(o) : r;
@@ -5687,14 +5690,14 @@ class O {
return this.safeParse(null).success;
}
}
-const Hc = /^c[^\s-]{8,}$/i, Wc = /^[0-9a-z]+$/, qc = /^[0-9A-HJKMNP-TV-Z]{26}$/i, Kc = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i, Yc = /^[a-z0-9_-]{21}$/i, Jc = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/, Xc = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/, Qc = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i, el = "^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$";
+const Wc = /^c[^\s-]{8,}$/i, qc = /^[0-9a-z]+$/, Kc = /^[0-9A-HJKMNP-TV-Z]{26}$/i, Yc = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i, Jc = /^[a-z0-9_-]{21}$/i, Xc = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/, Qc = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/, el = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i, tl = "^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$";
let hn;
-const tl = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/, rl = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/, nl = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/, ol = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/, sl = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/, al = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/, Vs = "((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))", il = new RegExp(`^${Vs}$`);
+const rl = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/, nl = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/, ol = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/, sl = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/, al = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/, il = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/, Vs = "((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))", cl = new RegExp(`^${Vs}$`);
function Hs(t) {
let e = "([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d";
return t.precision ? e = `${e}\\.\\d{${t.precision}}` : t.precision == null && (e = `${e}(\\.\\d+)?`), e;
}
-function cl(t) {
+function ll(t) {
return new RegExp(`^${Hs(t)}$`);
}
function Ws(t) {
@@ -5702,11 +5705,11 @@ function Ws(t) {
const r = [];
return r.push(t.local ? "Z?" : "Z"), t.offset && r.push("([+-]\\d{2}:?\\d{2})"), e = `${e}(${r.join("|")})`, new RegExp(`^${e}$`);
}
-function ll(t, e) {
- return !!((e === "v4" || !e) && tl.test(t) || (e === "v6" || !e) && nl.test(t));
-}
function ul(t, e) {
- if (!Jc.test(t))
+ return !!((e === "v4" || !e) && rl.test(t) || (e === "v6" || !e) && ol.test(t));
+}
+function dl(t, e) {
+ if (!Xc.test(t))
return !1;
try {
const [r] = t.split("."), n = r.replace(/-/g, "+").replace(/_/g, "/").padEnd(r.length + (4 - r.length % 4) % 4, "="), o = JSON.parse(atob(n));
@@ -5715,8 +5718,8 @@ function ul(t, e) {
return !1;
}
}
-function dl(t, e) {
- return !!((e === "v4" || !e) && rl.test(t) || (e === "v6" || !e) && ol.test(t));
+function fl(t, e) {
+ return !!((e === "v4" || !e) && nl.test(t) || (e === "v6" || !e) && sl.test(t));
}
class Re extends O {
_parse(e) {
@@ -5767,43 +5770,43 @@ class Re extends O {
message: s.message
}), n.dirty());
} else if (s.kind === "email")
- Qc.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
+ el.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
validation: "email",
code: g.invalid_string,
message: s.message
}), n.dirty());
else if (s.kind === "emoji")
- hn || (hn = new RegExp(el, "u")), hn.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
+ hn || (hn = new RegExp(tl, "u")), hn.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
validation: "emoji",
code: g.invalid_string,
message: s.message
}), n.dirty());
else if (s.kind === "uuid")
- Kc.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
+ Yc.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
validation: "uuid",
code: g.invalid_string,
message: s.message
}), n.dirty());
else if (s.kind === "nanoid")
- Yc.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
+ Jc.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
validation: "nanoid",
code: g.invalid_string,
message: s.message
}), n.dirty());
else if (s.kind === "cuid")
- Hc.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
+ Wc.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
validation: "cuid",
code: g.invalid_string,
message: s.message
}), n.dirty());
else if (s.kind === "cuid2")
- Wc.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
+ qc.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
validation: "cuid2",
code: g.invalid_string,
message: s.message
}), n.dirty());
else if (s.kind === "ulid")
- qc.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
+ Kc.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
validation: "ulid",
code: g.invalid_string,
message: s.message
@@ -5838,35 +5841,35 @@ class Re extends O {
code: g.invalid_string,
validation: "datetime",
message: s.message
- }), n.dirty()) : s.kind === "date" ? il.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
+ }), n.dirty()) : s.kind === "date" ? cl.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
code: g.invalid_string,
validation: "date",
message: s.message
- }), n.dirty()) : s.kind === "time" ? cl(s).test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
+ }), n.dirty()) : s.kind === "time" ? ll(s).test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
code: g.invalid_string,
validation: "time",
message: s.message
- }), n.dirty()) : s.kind === "duration" ? Xc.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
+ }), n.dirty()) : s.kind === "duration" ? Qc.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
validation: "duration",
code: g.invalid_string,
message: s.message
- }), n.dirty()) : s.kind === "ip" ? ll(e.data, s.version) || (o = this._getOrReturnCtx(e, o), v(o, {
+ }), n.dirty()) : s.kind === "ip" ? ul(e.data, s.version) || (o = this._getOrReturnCtx(e, o), v(o, {
validation: "ip",
code: g.invalid_string,
message: s.message
- }), n.dirty()) : s.kind === "jwt" ? ul(e.data, s.alg) || (o = this._getOrReturnCtx(e, o), v(o, {
+ }), n.dirty()) : s.kind === "jwt" ? dl(e.data, s.alg) || (o = this._getOrReturnCtx(e, o), v(o, {
validation: "jwt",
code: g.invalid_string,
message: s.message
- }), n.dirty()) : s.kind === "cidr" ? dl(e.data, s.version) || (o = this._getOrReturnCtx(e, o), v(o, {
+ }), n.dirty()) : s.kind === "cidr" ? fl(e.data, s.version) || (o = this._getOrReturnCtx(e, o), v(o, {
validation: "cidr",
code: g.invalid_string,
message: s.message
- }), n.dirty()) : s.kind === "base64" ? sl.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
+ }), n.dirty()) : s.kind === "base64" ? al.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
validation: "base64",
code: g.invalid_string,
message: s.message
- }), n.dirty()) : s.kind === "base64url" ? al.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
+ }), n.dirty()) : s.kind === "base64url" ? il.test(e.data) || (o = this._getOrReturnCtx(e, o), v(o, {
validation: "base64url",
code: g.invalid_string,
message: s.message
@@ -6105,7 +6108,7 @@ Re.create = (t) => {
...N(t)
});
};
-function fl(t, e) {
+function pl(t, e) {
const r = (t.toString().split(".")[1] || "").length, n = (e.toString().split(".")[1] || "").length, o = r > n ? r : n, s = parseInt(t.toFixed(o).replace(".", "")), i = parseInt(e.toFixed(o).replace(".", ""));
return s % i / Math.pow(10, o);
}
@@ -6144,7 +6147,7 @@ class tt extends O {
inclusive: s.inclusive,
exact: !1,
message: s.message
- }), o.dirty()) : s.kind === "multipleOf" ? fl(e.data, s.value) !== 0 && (n = this._getOrReturnCtx(e, n), v(n, {
+ }), o.dirty()) : s.kind === "multipleOf" ? pl(e.data, s.value) !== 0 && (n = this._getOrReturnCtx(e, n), v(n, {
code: g.not_multiple_of,
multipleOf: s.value,
message: s.message
@@ -7853,7 +7856,7 @@ Dr.create = (t) => new Dr({
typeName: C.ZodNaN,
...N(t)
});
-const pl = Symbol("zod_brand");
+const hl = Symbol("zod_brand");
class Hn extends O {
_parse(e) {
const { ctx: r } = this._processInputParams(e), n = r.data;
@@ -7930,16 +7933,16 @@ function Ks(t, e = {}, r) {
}
}) : Lt.create();
}
-const hl = {
+const ml = {
object: V.lazycreate
};
var C;
(function(t) {
t.ZodString = "ZodString", t.ZodNumber = "ZodNumber", t.ZodNaN = "ZodNaN", t.ZodBigInt = "ZodBigInt", t.ZodBoolean = "ZodBoolean", t.ZodDate = "ZodDate", t.ZodSymbol = "ZodSymbol", t.ZodUndefined = "ZodUndefined", t.ZodNull = "ZodNull", t.ZodAny = "ZodAny", t.ZodUnknown = "ZodUnknown", t.ZodNever = "ZodNever", t.ZodVoid = "ZodVoid", t.ZodArray = "ZodArray", t.ZodObject = "ZodObject", t.ZodUnion = "ZodUnion", t.ZodDiscriminatedUnion = "ZodDiscriminatedUnion", t.ZodIntersection = "ZodIntersection", t.ZodTuple = "ZodTuple", t.ZodRecord = "ZodRecord", t.ZodMap = "ZodMap", t.ZodSet = "ZodSet", t.ZodFunction = "ZodFunction", t.ZodLazy = "ZodLazy", t.ZodLiteral = "ZodLiteral", t.ZodEnum = "ZodEnum", t.ZodEffects = "ZodEffects", t.ZodNativeEnum = "ZodNativeEnum", t.ZodOptional = "ZodOptional", t.ZodNullable = "ZodNullable", t.ZodDefault = "ZodDefault", t.ZodCatch = "ZodCatch", t.ZodPromise = "ZodPromise", t.ZodBranded = "ZodBranded", t.ZodPipeline = "ZodPipeline", t.ZodReadonly = "ZodReadonly";
})(C || (C = {}));
-const ml = (t, e = {
+const gl = (t, e = {
message: `Input not instance of ${t.name}`
-}) => Ks((r) => r instanceof t, e), Ys = Re.create, Js = tt.create, gl = Dr.create, yl = rt.create, Xs = Kt.create, _l = _t.create, vl = Mr.create, bl = Yt.create, wl = Jt.create, Sl = Lt.create, xl = mt.create, El = Ye.create, kl = Lr.create, Pl = Ne.create, Al = V.create, Tl = V.strictCreate, Il = Xt.create, Cl = Qr.create, Rl = Qt.create, $l = Ze.create, Nl = er.create, Ol = Fr.create, Ml = vt.create, Ll = Ct.create, Fl = tr.create, Dl = rr.create, Ul = nt.create, jl = nr.create, Zl = Ft.create, xo = Oe.create, zl = Ue.create, Bl = ot.create, Gl = Oe.createWithPreprocess, Vl = ur.create, Hl = () => Ys().optional(), Wl = () => Js().optional(), ql = () => Xs().optional(), Kl = {
+}) => Ks((r) => r instanceof t, e), Ys = Re.create, Js = tt.create, yl = Dr.create, _l = rt.create, Xs = Kt.create, vl = _t.create, bl = Mr.create, wl = Yt.create, xl = Jt.create, Sl = Lt.create, El = mt.create, kl = Ye.create, Pl = Lr.create, Al = Ne.create, Tl = V.create, Il = V.strictCreate, Cl = Xt.create, Rl = Qr.create, $l = Qt.create, Nl = Ze.create, Ol = er.create, Ml = Fr.create, Ll = vt.create, Fl = Ct.create, Dl = tr.create, Ul = rr.create, jl = nt.create, Zl = nr.create, zl = Ft.create, So = Oe.create, Bl = Ue.create, Gl = ot.create, Vl = Oe.createWithPreprocess, Hl = ur.create, Wl = () => Ys().optional(), ql = () => Js().optional(), Kl = () => Xs().optional(), Yl = {
string: (t) => Re.create({ ...t, coerce: !0 }),
number: (t) => tt.create({ ...t, coerce: !0 }),
boolean: (t) => Kt.create({
@@ -7948,14 +7951,14 @@ const ml = (t, e = {
}),
bigint: (t) => rt.create({ ...t, coerce: !0 }),
date: (t) => _t.create({ ...t, coerce: !0 })
-}, Yl = $;
+}, Jl = $;
var K = /* @__PURE__ */ Object.freeze({
__proto__: null,
defaultErrorMap: Mt,
- setErrorMap: Gc,
+ setErrorMap: Vc,
getErrorMap: $r,
makeIssue: Nr,
- EMPTY_PATH: Vc,
+ EMPTY_PATH: Hc,
addIssueToContext: v,
ParseStatus: oe,
INVALID: $,
@@ -7969,7 +7972,7 @@ var K = /* @__PURE__ */ Object.freeze({
return F;
},
get objectUtil() {
- return xn;
+ return Sn;
},
ZodParsedType: b,
getParsedType: He,
@@ -8009,63 +8012,63 @@ var K = /* @__PURE__ */ Object.freeze({
ZodDefault: or,
ZodCatch: sr,
ZodNaN: Dr,
- BRAND: pl,
+ BRAND: hl,
ZodBranded: Hn,
ZodPipeline: ur,
ZodReadonly: ar,
custom: Ks,
Schema: O,
ZodSchema: O,
- late: hl,
+ late: ml,
get ZodFirstPartyTypeKind() {
return C;
},
- coerce: Kl,
+ coerce: Yl,
any: Sl,
- array: Pl,
- bigint: yl,
+ array: Al,
+ bigint: _l,
boolean: Xs,
- date: _l,
- discriminatedUnion: Cl,
- effect: xo,
- enum: Ul,
- function: Ll,
- instanceof: ml,
- intersection: Rl,
- lazy: Fl,
- literal: Dl,
- map: Ol,
- nan: gl,
- nativeEnum: jl,
- never: El,
- null: wl,
- nullable: Bl,
+ date: vl,
+ discriminatedUnion: Rl,
+ effect: So,
+ enum: jl,
+ function: Fl,
+ instanceof: gl,
+ intersection: $l,
+ lazy: Dl,
+ literal: Ul,
+ map: Ml,
+ nan: yl,
+ nativeEnum: Zl,
+ never: kl,
+ null: xl,
+ nullable: Gl,
number: Js,
- object: Al,
- oboolean: ql,
- onumber: Wl,
- optional: zl,
- ostring: Hl,
- pipeline: Vl,
- preprocess: Gl,
- promise: Zl,
- record: Nl,
- set: Ml,
- strictObject: Tl,
+ object: Tl,
+ oboolean: Kl,
+ onumber: ql,
+ optional: Bl,
+ ostring: Wl,
+ pipeline: Hl,
+ preprocess: Vl,
+ promise: zl,
+ record: Ol,
+ set: Ll,
+ strictObject: Il,
string: Ys,
- symbol: vl,
- transformer: xo,
- tuple: $l,
- undefined: bl,
- union: Il,
- unknown: xl,
- void: kl,
- NEVER: Yl,
+ symbol: bl,
+ transformer: So,
+ tuple: Nl,
+ undefined: wl,
+ union: Cl,
+ unknown: El,
+ void: Pl,
+ NEVER: Jl,
ZodIssueCode: g,
- quotelessJson: Bc,
+ quotelessJson: Gc,
ZodError: ye
});
-const Jl = K.object({
+const Xl = K.object({
pluginId: K.string(),
name: K.string(),
host: K.string().url(),
@@ -8081,16 +8084,17 @@ const Jl = K.object({
"user:read",
"comment:read",
"comment:write",
- "allow:downloads"
+ "allow:downloads",
+ "allow:localstorage"
])
)
});
function Qs(t, e) {
return new URL(e, t).toString();
}
-function Xl(t) {
+function Ql(t) {
return fetch(t).then((e) => e.json()).then((e) => {
- if (!Jl.safeParse(e).success)
+ if (!Xl.safeParse(e).success)
throw new Error("Invalid plugin manifest");
return e;
}).catch((e) => {
@@ -8107,14 +8111,14 @@ function Eo(t) {
const ea = K.object({
width: K.number().positive(),
height: K.number().positive()
-}), Ql = K.function().args(
+}), eu = K.function().args(
K.string(),
K.string(),
K.enum(["dark", "light"]),
ea.optional(),
K.boolean().optional()
).implement((t, e, r, n, o) => jc(t, e, r, n, o));
-async function eu(t, e, r, n) {
+async function tu(t, e, r, n) {
let o = await Eo(e), s = !1, i = !1, c = null, l = [];
const u = /* @__PURE__ */ new Set(), d = !!e.permissions.find(
(I) => I === "allow:downloads"
@@ -8130,7 +8134,7 @@ async function eu(t, e, r, n) {
}), l = [], p = [];
}, A = () => {
m(), u.forEach(clearTimeout), u.clear(), c && (c.removeEventListener("close", A), c.remove(), c = null), i = !0, r();
- }, S = async () => {
+ }, x = async () => {
if (!s) {
s = !0;
return;
@@ -8138,9 +8142,9 @@ async function eu(t, e, r, n) {
m(), o = await Eo(e), n(o);
}, w = (I, L, Z) => {
const se = t.theme, J = Qs(e.host, L);
- (c == null ? void 0 : c.getAttribute("iframe-src")) !== J && (c = Ql(I, J, se, Z, d), c.setTheme(se), c.addEventListener("close", A, {
+ (c == null ? void 0 : c.getAttribute("iframe-src")) !== J && (c = eu(I, J, se, Z, d), c.setTheme(se), c.addEventListener("close", A, {
once: !0
- }), c.addEventListener("load", S));
+ }), c.addEventListener("load", x));
}, R = (I) => {
l.push(I);
}, T = (I, L, Z) => {
@@ -8182,7 +8186,7 @@ async function eu(t, e, r, n) {
}
};
}
-const tu = [
+const ru = [
"finish",
"pagechange",
"filechange",
@@ -8191,7 +8195,7 @@ const tu = [
"shapechange",
"contentsave"
];
-function ru(t) {
+function nu(t) {
const e = (n) => {
if (!t.manifest.permissions.includes(n))
throw new Error(`Permission ${n} is not granted`);
@@ -8258,7 +8262,7 @@ function ru(t) {
t.close();
},
on(n, o, s) {
- return K.enum(tu).parse(n), K.function().parse(o), e("content:read"), t.registerListener(n, o, s);
+ return K.enum(ru).parse(n), K.function().parse(o), e("content:read"), t.registerListener(n, o, s);
},
off(n) {
t.destroyListener(n);
@@ -8306,6 +8310,9 @@ function ru(t) {
get theme() {
return t.context.theme;
},
+ get localStorage() {
+ return e("allow:localstorage"), t.context.localStorage;
+ },
createBoard() {
return e("content:write"), t.context.createBoard();
},
@@ -8348,6 +8355,9 @@ function ru(t) {
generateStyle(n, o) {
return e("content:read"), t.context.generateStyle(n, o);
},
+ generateFontFaces(n) {
+ return e("content:read"), t.context.generateFontFaces(n);
+ },
openViewer() {
e("content:read"), t.context.openViewer();
},
@@ -8386,9 +8396,9 @@ const k = {
return t == null ? t : harden(t);
}
};
-function nu(t) {
+function ou(t) {
k.hardenIntrinsics();
- const e = ru(t), r = {
+ const e = nu(t), r = {
get(c, l, u) {
const d = Reflect.get(c, l, u);
return typeof d == "function" ? function(...f) {
@@ -8492,14 +8502,14 @@ function nu(t) {
compartment: i
};
}
-async function ou(t, e, r) {
+async function su(t, e, r) {
const n = async () => {
try {
s.evaluate();
} catch (i) {
console.error(i), o.close();
}
- }, o = await eu(
+ }, o = await tu(
t,
e,
function() {
@@ -8508,7 +8518,7 @@ async function ou(t, e, r) {
function() {
n();
}
- ), s = nu(o);
+ ), s = ou(o);
return n(), {
plugin: o,
manifest: e,
@@ -8516,7 +8526,7 @@ async function ou(t, e, r) {
};
}
let gt = [], An = null;
-function su(t) {
+function au(t) {
An = t;
}
const Po = () => {
@@ -8532,13 +8542,13 @@ window.addEventListener("message", (t) => {
console.error(e);
}
});
-const au = async function(t, e) {
+const iu = async function(t, e) {
try {
const r = An && An(t.pluginId);
if (!r)
return;
Po();
- const n = await ou(
+ const n = await su(
k.harden(r),
t,
() => {
@@ -8550,11 +8560,11 @@ const au = async function(t, e) {
Po(), console.error(r);
}
}, ta = async function(t, e) {
- au(t, e);
-}, iu = async function(t) {
- const e = await Xl(t);
+ iu(t, e);
+}, cu = async function(t) {
+ const e = await Ql(t);
ta(e);
-}, cu = function(t) {
+}, lu = function(t) {
const e = gt.find((r) => r.manifest.pluginId === t);
e && e.plugin.close();
};
@@ -8570,7 +8580,7 @@ repairIntrinsics({
const Ao = globalThis;
Ao.initPluginsRuntime = (t) => {
try {
- console.log("%c[PLUGINS] Initialize runtime", "color: #008d7c"), su(t), Ao.ɵcontext = t("TEST"), globalThis.ɵloadPlugin = ta, globalThis.ɵloadPluginByUrl = iu, globalThis.ɵunloadPlugin = cu;
+ console.log("%c[PLUGINS] Initialize runtime", "color: #008d7c"), au(t), Ao.ɵcontext = t("TEST"), globalThis.ɵloadPlugin = ta, globalThis.ɵloadPluginByUrl = cu, globalThis.ɵunloadPlugin = lu;
} catch (e) {
console.error(e);
}
diff --git a/frontend/scripts/_helpers.js b/frontend/scripts/_helpers.js
index 7602b9c149..ffa74c1889 100644
--- a/frontend/scripts/_helpers.js
+++ b/frontend/scripts/_helpers.js
@@ -274,6 +274,7 @@ async function readTranslations() {
"fa",
"fr",
"he",
+ "sr",
"nb_NO",
"pl",
"pt_BR",
diff --git a/frontend/src/app/main/render.cljs b/frontend/src/app/main/render.cljs
index b916688d07..f634741270 100644
--- a/frontend/src/app/main/render.cljs
+++ b/frontend/src/app/main/render.cljs
@@ -444,14 +444,16 @@
(mf/defc object-svg
{::mf/wrap [mf/memo]}
- [{:keys [objects object-id embed]
+ [{:keys [objects object-id embed skip-children]
:or {embed false}
:as props}]
(let [object (get objects object-id)
object (cond-> object
(:hide-fill-on-export object)
- (assoc :fills []))
+ (assoc :fills [])
+ skip-children
+ (assoc :shapes []))
{:keys [width height] :as bounds} (gsb/get-object-bounds objects object {:ignore-margin? false})
vbox (format-viewbox bounds)
diff --git a/frontend/src/app/main/ui/auth/register.cljs b/frontend/src/app/main/ui/auth/register.cljs
index 8e290054f7..3cedef6c88 100644
--- a/frontend/src/app/main/ui/auth/register.cljs
+++ b/frontend/src/app/main/ui/auth/register.cljs
@@ -35,6 +35,7 @@
:content (tr "onboarding-v2.newsletter.updates")}])]
[:div {:class (stl/css :fields-row :input-visible :newsletter-option-wrapper)}
[:& fm/input {:name :accept-newsletter-updates
+ :class (stl/css :checkbox-newsletter-updates)
:type "checkbox"
:default-checked false
:label updates-label}]]))
@@ -53,6 +54,7 @@
[:div {:class (stl/css :fields-row :input-visible :accept-terms-and-privacy-wrapper)}
[:& fm/input {:name :accept-terms-and-privacy
+ :show-error false
:class (stl/css :checkbox-terms-and-privacy)
:type "checkbox"
:default-checked false
diff --git a/frontend/src/app/main/ui/auth/register.scss b/frontend/src/app/main/ui/auth/register.scss
index 0309cd44ac..f4fd493a1b 100644
--- a/frontend/src/app/main/ui/auth/register.scss
+++ b/frontend/src/app/main/ui/auth/register.scss
@@ -14,9 +14,11 @@
}
}
-.checkbox-terms-and-privacy {
+.checkbox-terms-and-privacy,
+.checkbox-newsletter-updates {
align-items: flex-start;
}
+
.register-form {
gap: $s-24;
}
diff --git a/frontend/src/app/main/ui/components/code_block.scss b/frontend/src/app/main/ui/components/code_block.scss
index 7b44c702ae..5f28cd4624 100644
--- a/frontend/src/app/main/ui/components/code_block.scss
+++ b/frontend/src/app/main/ui/components/code_block.scss
@@ -4,9 +4,11 @@
//
// Copyright (c) KALEIDOS INC
+@use "../ds/typography.scss" as t;
@import "refactor/common-refactor.scss";
.code-display {
+ @include t.use-typography("code-font");
user-select: text;
border-radius: $br-8;
margin-top: $s-8;
diff --git a/frontend/src/app/main/ui/dashboard/import.cljs b/frontend/src/app/main/ui/dashboard/import.cljs
index afe962f7d2..30f94ffb9f 100644
--- a/frontend/src/app/main/ui/dashboard/import.cljs
+++ b/frontend/src/app/main/ui/dashboard/import.cljs
@@ -170,6 +170,9 @@
(rx/filter some?)
(rx/subs!
(fn [message]
+ (when (some? (:error message))
+ (st/emit! (ptk/data-event ::ev/event {::ev/name "import-files-error"
+ :error (:error message)})))
(swap! state update-with-analyze-result message))))))
(defn- import-files
@@ -467,6 +470,7 @@
(when (and (= :analyze status) errors?)
[:& context-notification
{:level :warning
+ :class (stl/css :context-notification-error)
:content (tr "dashboard.import.import-warning")}])
(when (= :import-success status)
@@ -480,12 +484,12 @@
:class (stl/css :context-notification-error)
:content (tr "dashboard.import.import-error.disclaimer")}])
- (if (= :import-error status)
+ (if (or (= :import-error status) (and (= :analyze status) errors?))
[:div {:class (stl/css :import-error-disclaimer)}
[:div (tr "dashboard.import.import-error.message1")]
[:ul {:class (stl/css :import-error-list)}
(for [entry entries]
- (when (= :import-error (:status entry))
+ (when (contains? #{:import-error :analyze-error} (:status entry))
[:li {:class (stl/css :import-error-list-enry)} (:name entry)]))]
[:div (tr "dashboard.import.import-error.message2")]]
diff --git a/frontend/src/app/main/ui/ds/buttons/button.cljs b/frontend/src/app/main/ui/ds/buttons/button.cljs
index 37adcd41da..376d063fc7 100644
--- a/frontend/src/app/main/ui/ds/buttons/button.cljs
+++ b/frontend/src/app/main/ui/ds/buttons/button.cljs
@@ -36,4 +36,4 @@
(on-ref node)))})]
[:> "button" props
(when icon [:> icon* {:icon-id icon :size "m"}])
- [:span {:class (stl/css :label-wrapper)} children]]))
\ No newline at end of file
+ [:span {:class (stl/css :label-wrapper)} children]]))
diff --git a/frontend/src/app/main/ui/ds/buttons/icon_button.cljs b/frontend/src/app/main/ui/ds/buttons/icon_button.cljs
index 33ee369523..1d2995ea8e 100644
--- a/frontend/src/app/main/ui/ds/buttons/icon_button.cljs
+++ b/frontend/src/app/main/ui/ds/buttons/icon_button.cljs
@@ -6,11 +6,11 @@
(ns app.main.ui.ds.buttons.icon-button
(:require-macros
- [app.common.data.macros :as dm]
[app.main.style :as stl])
(:require
+ [app.common.data :as d]
[app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list]]
- [app.main.ui.ds.tooltip.tooltip :refer [tooltip*]]
+ [app.main.ui.ds.tooltip :refer [tooltip*]]
[rumext.v2 :as mf]))
(def ^:private schema:icon-button
@@ -24,18 +24,30 @@
[:maybe [:enum "primary" "secondary" "ghost" "destructive" "action"]]]])
(mf/defc icon-button*
- {::mf/schema schema:icon-button}
+ {::mf/schema schema:icon-button
+ ::mf/memo true}
[{:keys [class icon icon-class variant aria-label children] :rest props}]
- (let [variant (or variant "primary")
- tooltip-id (mf/use-id)
- class (dm/str class " " (stl/css-case :icon-button true
- :icon-button-primary (= variant "primary")
- :icon-button-secondary (= variant "secondary")
- :icon-button-ghost (= variant "ghost")
- :icon-button-action (= variant "action")
- :icon-button-destructive (= variant "destructive")))
- props (mf/spread-props props {:class class
- :aria-labelledby tooltip-id})]
- [:> tooltip* {:tooltip-content aria-label
+ (let [variant
+ (d/nilv variant "primary")
+
+ tooltip-id
+ (mf/use-id)
+
+ button-class
+ (stl/css-case :icon-button true
+ :icon-button-primary (identical? variant "primary")
+ :icon-button-secondary (identical? variant "secondary")
+ :icon-button-ghost (identical? variant "ghost")
+ :icon-button-action (identical? variant "action")
+ :icon-button-destructive (identical? variant "destructive"))
+
+ props
+ (mf/spread-props props
+ {:class [class button-class]
+ :aria-labelledby tooltip-id})]
+
+ [:> tooltip* {:content aria-label
:id tooltip-id}
- [:> "button" props [:> icon* {:icon-id icon :aria-hidden true :class icon-class}] children]]))
\ No newline at end of file
+ [:> :button props
+ [:> icon* {:icon-id icon :aria-hidden true :class icon-class}]
+ children]]))
diff --git a/frontend/src/app/main/ui/ds/tooltip.cljs b/frontend/src/app/main/ui/ds/tooltip.cljs
new file mode 100644
index 0000000000..2cd68ec5d6
--- /dev/null
+++ b/frontend/src/app/main/ui/ds/tooltip.cljs
@@ -0,0 +1,12 @@
+;; This Source Code Form is subject to the terms of the Mozilla Public
+;; License, v. 2.0. If a copy of the MPL was not distributed with this
+;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+;;
+;; Copyright (c) KALEIDOS INC
+
+(ns app.main.ui.ds.tooltip
+ (:require
+ [app.common.data.macros :as dm]
+ [app.main.ui.ds.tooltip.tooltip :as impl]))
+
+(dm/export impl/tooltip*)
diff --git a/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs b/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs
index c69c2609e5..92d3b7901e 100644
--- a/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs
+++ b/frontend/src/app/main/ui/ds/tooltip/tooltip.cljs
@@ -15,21 +15,49 @@
[app.util.timers :as ts]
[rumext.v2 :as mf]))
-(defn- calculate-tooltip-rect [tooltip trigger-rect placement offset]
+(def ^:private ^:const arrow-height 12)
+(def ^:private ^:const half-arrow-height (/ arrow-height 2))
+(def ^:private ^:const overlay-offset 32)
+
+(defn- clear-schedule
+ [ref]
+ (when-let [schedule (mf/ref-val ref)]
+ (ts/dispose! schedule)
+ (mf/set-ref-val! ref nil)))
+
+(defn- add-schedule
+ [ref delay f]
+ (mf/set-ref-val! ref (ts/schedule delay f)))
+
+(defn- show-popover
+ [node]
+ (when (.-isConnected ^js node)
+ (.showPopover ^js node)))
+
+(defn- hide-popover
+ [node]
+ (dom/unset-css-property! node "block-size")
+ (dom/unset-css-property! node "display")
+ (.hidePopover ^js node))
+
+(defn- calculate-placement-bounding-rect
+ "Given a placement, calcultates the bounding rect for it taking in
+ account provided tooltip bounding rect and the origin bounding
+ rect."
+ [placement tooltip-brect origin-brect offset]
(let [{trigger-top :top
trigger-left :left
trigger-right :right
trigger-bottom :bottom
trigger-width :width
- trigger-height :height} trigger-rect
+ trigger-height :height}
+ origin-brect
{tooltip-width :width
- tooltip-height :height} (dom/get-bounding-rect tooltip)
+ tooltip-height :height}
+ tooltip-brect
- offset (d/nilv offset 2)
- arrow-height 12
- half-arrow-height (/ arrow-height 2)
- overlay-offset 32]
+ offset (d/nilv offset 2)]
(case placement
"bottom"
@@ -95,7 +123,10 @@
:width tooltip-width
:height tooltip-height})))
-(defn- get-fallback-order [placement]
+(defn- get-fallback-order
+ "Get a vector of placement followed with ordered fallback pacements
+ for the specified placement"
+ [placement]
(case placement
"top" ["top" "right" "bottom" "left" "top-right" "bottom-right" "bottom-left" "top-left"]
"bottom" ["bottom" "left" "top" "right" "bottom-right" "bottom-left" "top-left" "top-right"]
@@ -106,65 +137,93 @@
"bottom-left" ["bottom-left" "left" "top" "right" "bottom" "top-left" "top-right" "bottom-right"]
"top-left" ["top-left" "top" "right" "bottom" "left" "bottom-left" "top-right" "bottom-right"]))
+(defn- find-matching-placement
+ "Algorithm for find a correct placement and placement-brect for the
+ provided placement, if the current placement does not matches, it
+ uses the predefined fallbacks. Returns an array of matched placement
+ and its bounding rect."
+ [placement tooltip-brect origin-brect window-size offset]
+ (loop [placements (seq (get-fallback-order placement))]
+ (when-let [placement (first placements)]
+ (let [placement-brect (calculate-placement-bounding-rect placement tooltip-brect origin-brect offset)]
+ (if (dom/is-bounding-rect-outside? placement-brect window-size)
+ (recur (rest placements))
+ #js [placement placement-brect])))))
+
+(defn- update-tooltip-position
+ "Update the tooltip position having in account the current window
+ size, placement. It calculates the appropriate placement and updates
+ the dom with the result."
+ [tooltip placement origin-brect offset]
+ (show-popover tooltip)
+ (let [tooltip-brect (dom/get-bounding-rect tooltip)
+ window-size (dom/get-window-size)]
+ (when-let [[placement placement-rect] (find-matching-placement placement tooltip-brect origin-brect window-size offset)]
+
+ (let [height (if (or (= placement "right") (= placement "left"))
+ (- (:height placement-rect) arrow-height)
+ (:height placement-rect))]
+ (dom/set-css-property! tooltip "display" "grid")
+ (dom/set-css-property! tooltip "block-size" (dm/str height "px"))
+ (dom/set-css-property! tooltip "inset-block-start" (dm/str (:top placement-rect) "px"))
+ (dom/set-css-property! tooltip "inset-inline-start" (dm/str (:left placement-rect) "px")))
+ placement)))
+
(def ^:private schema:tooltip
[:map
[:class {:optional true} :string]
[:id {:optional true} :string]
[:offset {:optional true} :int]
[:delay {:optional true} :int]
+ [:content [:or fn? :string [:fn mf/element?]]]
[:placement {:optional true}
[:maybe [:enum "top" "bottom" "left" "right" "top-right" "bottom-right" "bottom-left" "top-left"]]]])
(mf/defc tooltip*
{::mf/schema schema:tooltip}
- [{:keys [class id children tooltip-content placement offset delay] :rest props}]
- (let [id (or id (mf/use-id))
- placement* (mf/use-state #(d/nilv placement "top"))
- placement (deref placement*)
- delay (d/nilv delay 300)
+ [{:keys [class id children content placement offset delay] :rest props}]
+ (let [internal-id
+ (mf/use-id)
- schedule-ref (mf/use-ref nil)
+ id
+ (d/nilv id internal-id)
- position-tooltip
- (fn [^js tooltip trigger-rect]
- (let [all-placements (get-fallback-order placement)]
- (when (.-isConnected tooltip)
- (.showPopover ^js tooltip))
- (loop [[current-placement & remaining-placements] all-placements]
- (when current-placement
- (reset! placement* current-placement)
- (let [tooltip-rect (calculate-tooltip-rect tooltip trigger-rect current-placement offset)]
- (if (dom/is-bounding-rect-outside? tooltip-rect)
- (recur remaining-placements)
- (do (dom/set-css-property! tooltip "display" "grid")
- (dom/set-css-property! tooltip "inset-block-start" (dm/str (:top tooltip-rect) "px"))
- (dom/set-css-property! tooltip "inset-inline-start" (dm/str (:left tooltip-rect) "px")))))))))
+ placement*
+ (mf/use-state #(d/nilv placement "top"))
+
+ placement
+ (deref placement*)
+
+ delay
+ (d/nilv delay 300)
+
+ schedule-ref
+ (mf/use-ref nil)
on-show
(mf/use-fn
- (mf/deps id placement)
+ (mf/deps id placement offset)
(fn [event]
- (when-let [schedule (mf/ref-val schedule-ref)]
- (ts/dispose! schedule)
- (mf/set-ref-val! schedule-ref nil))
+ (clear-schedule schedule-ref)
(when-let [tooltip (dom/get-element id)]
- (let [trigger-rect (->> (dom/get-target event)
- (dom/get-bounding-rect))]
- (mf/set-ref-val!
- schedule-ref
- (ts/schedule
- delay
- #(position-tooltip tooltip trigger-rect)))))))
+ (let [origin-brect
+ (->> (dom/get-target event)
+ (dom/get-bounding-rect))
+
+ update-position
+ (fn []
+ (let [placement (update-tooltip-position tooltip placement origin-brect offset)]
+ (reset! placement* placement)))]
+
+ (add-schedule schedule-ref delay update-position)))))
on-hide
(mf/use-fn
(mf/deps id)
- (fn [] (when-let [tooltip (dom/get-element id)]
- (when-let [schedule (mf/ref-val schedule-ref)]
- (ts/dispose! schedule)
- (mf/set-ref-val! schedule-ref nil))
- (dom/unset-css-property! tooltip "display")
- (.hidePopover ^js tooltip))))
+ (fn []
+ (when-let [tooltip (dom/get-element id)]
+ (clear-schedule schedule-ref)
+ (hide-popover tooltip))))
handle-key-down
(mf/use-fn
@@ -173,33 +232,38 @@
(when (kbd/esc? event)
(on-hide))))
- class (d/append-class class (stl/css-case
- :tooltip true
- :tooltip-top (= placement "top")
- :tooltip-bottom (= placement "bottom")
- :tooltip-left (= placement "left")
- :tooltip-right (= placement "right")
- :tooltip-top-right (= placement "top-right")
- :tooltip-bottom-right (= placement "bottom-right")
- :tooltip-bottom-left (= placement "bottom-left")
- :tooltip-top-left (= placement "top-left")))
+ tooltip-class
+ (stl/css-case
+ :tooltip true
+ :tooltip-top (identical? placement "top")
+ :tooltip-bottom (identical? placement "bottom")
+ :tooltip-left (identical? placement "left")
+ :tooltip-right (identical? placement "right")
+ :tooltip-top-right (identical? placement "top-right")
+ :tooltip-bottom-right (identical? placement "bottom-right")
+ :tooltip-bottom-left (identical? placement "bottom-left")
+ :tooltip-top-left (identical? placement "top-left"))
+
+ props
+ (mf/spread-props props
+ {:on-mouse-enter on-show
+ :on-mouse-leave on-hide
+ :on-focus on-show
+ :on-blur on-hide
+ :on-key-down handle-key-down
+ :class (stl/css :tooltip-trigger)
+ :aria-describedby id})
+ content
+ (if (fn? content)
+ (content)
+ content)]
- props (mf/spread-props props {:on-mouse-enter on-show
- :on-mouse-leave on-hide
- :on-focus on-show
- :on-blur on-hide
- :on-key-down handle-key-down
- :class (stl/css :tooltip-trigger)
- :aria-describedby id})]
[:> :div props
children
- [:div {:class class
+ [:div {:class [class tooltip-class]
:id id
:popover "auto"
:role "tooltip"}
- [:div {:class (stl/css :tooltip-content)}
- (if (fn? tooltip-content)
- (tooltip-content)
- tooltip-content)]
+ [:div {:class (stl/css :tooltip-content)} content]
[:div {:class (stl/css :tooltip-arrow)
- :id "tooltip-arrow"}]]]))
\ No newline at end of file
+ :id "tooltip-arrow"}]]]))
diff --git a/frontend/src/app/main/ui/ds/tooltip/tooltip.mdx b/frontend/src/app/main/ui/ds/tooltip/tooltip.mdx
index 1dfb2945f0..dfae36dba7 100644
--- a/frontend/src/app/main/ui/ds/tooltip/tooltip.mdx
+++ b/frontend/src/app/main/ui/ds/tooltip/tooltip.mdx
@@ -32,7 +32,7 @@ If `placement` is not provided, the tooltip will default to "top".
[:> tlp/tooltip* {:id "test-tooltip"
:placement "bottom"
- :tooltip-content "Tooltip content"}
+ :content "Tooltip content"}
[:div "Trigger component"]])
```
@@ -44,8 +44,7 @@ Tooltip content can include HTML elements:
[:> tlp/tooltip* {:id "test-tooltip"
:placement "bottom"
- :tooltip-content (mf/html
- [:span "Tooltip content"])}
+ :content (mf/html [:span "Tooltip content"])}
[:div "Trigger component"]])
```
diff --git a/frontend/src/app/main/ui/ds/tooltip/tooltip.scss b/frontend/src/app/main/ui/ds/tooltip/tooltip.scss
index cb2ce09c2b..ae97c8b17b 100644
--- a/frontend/src/app/main/ui/ds/tooltip/tooltip.scss
+++ b/frontend/src/app/main/ui/ds/tooltip/tooltip.scss
@@ -16,6 +16,7 @@ $arrow-side: 12px;
background-color: transparent;
overflow: hidden;
inline-size: fit-content;
+ block-size: fit-content;
}
.tooltip-arrow {
@@ -145,6 +146,7 @@ $arrow-side: 12px;
border: $b-1 solid var(--color-accent-primary-muted);
padding: var(--sp-s) var(--sp-m);
grid-area: content;
+ block-size: fit-content;
}
.tooltip-trigger {
diff --git a/frontend/src/app/main/ui/ds/tooltip/tooltip.stories.jsx b/frontend/src/app/main/ui/ds/tooltip/tooltip.stories.jsx
index 985ad19895..0f2398edc0 100644
--- a/frontend/src/app/main/ui/ds/tooltip/tooltip.stories.jsx
+++ b/frontend/src/app/main/ui/ds/tooltip/tooltip.stories.jsx
@@ -37,10 +37,10 @@ export default {
},
args: {
children: (
-
+
),
id: "popover-example",
- tooltipContent: "This is the tooltip content",
+ content: "This is the tooltip content",
delay: 300,
},
render: ({ children, ...args }) => (
@@ -74,18 +74,18 @@ export const Corners = {
>
-
+