Compare commits

..

12 Commits

Author SHA1 Message Date
Dominik Jain
7cf88359fa 📚 Add section on 'Development' to README 2026-02-18 20:22:34 +01:00
Dominik Jain
ea4c6c3998 📚 Update information on repository structure 2026-02-18 20:17:05 +01:00
Dominik Jain
f8dd02169c 📚 Remove unnecessary details on what the boostrap script does 2026-02-18 11:14:21 +01:00
Dominik Jain
ebdae2cf65 📚 Revise instructions on prerequisites
* Do not state that pnpm must be available after Node.js installation
  (it is installed by corepack)
* Do not state that caddy is required; it is required only when
  rebuilding the API documentation for the server, which is not
  a task relevant to regular users.
* Do not strongly suggest that MCP users should be using the devenv.
* Windows: Add pointer to use Git Bash
2026-02-18 11:11:25 +01:00
Dominik Jain
79d3469f36 📚 Add instructions on cloning and the branch to use 2026-02-18 10:56:21 +01:00
Dominik Jain
6a49b5df8c ♻️ Move high-level instructions to the end
In this way, they can reasonably reference the more low-level concepts
2026-02-17 13:16:21 +01:00
Dominik Jain
141847585e 🚧 Temporary workaround for fills/strokes being read-only
Add instructions to make the limintations.
Once #8357 is resolved, this can be reverted.
2026-02-17 12:51:48 +01:00
Dominik Jain
7a52550889 Make clear that ExecuteCodeTool serialises automatically
LLMs sometimes decide to apply serialisation themselves, which is unnecessary,
and which this seeks to prevent.
2026-02-15 22:20:38 +01:00
Dominik Jain
08fc6fe917 Improve description of token values 2026-02-12 17:45:50 +01:00
Dominik Jain
926d573d3e 🚧 Temporary workaround for Token resolvedValue not working
Instruct LLM to not use this property.
To be reverted once #8341 is fixed.
2026-02-12 17:24:44 +01:00
Dominik Jain
bac04f8a73 🚧 Temporary workaround for sizing options not working
Add instructions explaining that FlexLayout sizing options do not work.
Relates to https://github.com/penpot/penpot-mcp/issues/39
2026-02-12 12:37:24 +01:00
Dominik Jain
b4e815e787 📎 Fix spelling errors 2026-02-12 12:36:51 +01:00
235 changed files with 13825 additions and 20598 deletions

View File

@@ -80,7 +80,7 @@ jobs:
- name: "Build package for ${{ inputs.plugin_name }}-plugin"
working-directory: plugins
shell: bash
run: pnpm --filter ${{ inputs.plugin_name }}-plugin build
run: npx nx build ${{ inputs.plugin_name }}-plugin
- name: Select Worker name
run: |

View File

@@ -78,7 +78,7 @@ jobs:
- name: Build styles
working-directory: plugins
shell: bash
run: pnpm run build:styles-example
run: npx nx run example-styles:build
- name: Select Worker name
run: |

View File

@@ -2,6 +2,12 @@
## 2.14.0 (Unreleased)
### :boom: Breaking changes & Deprecations
### :rocket: Epics and highlights
### :heart: Community contributions (Thank you!)
### :sparkles: New features & Enhancements
- Access to design tokens in Penpot Plugins [Taiga #8990](https://tree.taiga.io/project/penpot/us/8990)
@@ -29,18 +35,11 @@
- Fix viewer can update library [Taiga #13186](https://tree.taiga.io/project/penpot/issue/13186)
- Fix remove fill affects different element than selected [Taiga #13128](https://tree.taiga.io/project/penpot/issue/13128)
## 2.13.3
### :bug: Bugs fixed
- Revert yetti (http server) update, because that caused a regression on multipart uploads
## 2.13.2
### :bug: Bugs fixed
- Fix modifying shapes by apply negative tokens to border radius [Taiga #13317](https://tree.taiga.io/project/penpot/issue/13317)
- Fix arbitrary file read security issue on create-font-variant rpc method (https://github.com/penpot/penpot/security/advisories/GHSA-xp3f-g8rq-9px2)
- Fix security issue (Path Traversal Vulnerability) on fonts related RPC method
## 2.13.1

View File

@@ -28,8 +28,8 @@
com.google.guava/guava {:mvn/version "33.4.8-jre"}
funcool/yetti
{:git/tag "v11.8"
:git/sha "1d1b33f"
{:git/tag "v11.9"
:git/sha "5fad7a9"
:git/url "https://github.com/funcool/yetti.git"
:exclusions [org.slf4j/slf4j-api]}

View File

@@ -12,7 +12,6 @@ penpot - error list
<a class="{% if version = 3 %}strong{% endif %}" href="?version=3">[BACKEND ERRORS]</a>
<a class="{% if version = 4 %}strong{% endif %}" href="?version=4">[FRONTEND ERRORS]</a>
<a class="{% if version = 5 %}strong{% endif %}" href="?version=5">[RLIMIT REPORTS]</a>
</div>
</nav>
<main class="horizontal-list">

View File

@@ -1,40 +0,0 @@
{% extends "app/templates/base.tmpl" %}
{% block title %}
Report: {{hint|abbreviate:150}} - {{id}} - Penpot Rate Limit Report
{% endblock %}
{% block content %}
<nav>
<div>[<a href="/dbg/error?version={{version}}">⮜</a>]</div>
<div>[<a href="#head">head</a>]</div>
<div>[<a href="#context">context</a>]</div>
<div>[<a href="#result">result</a>]</div>
</nav>
<main>
<div class="table">
<div class="table-row multiline">
<div id="head" class="table-key">HEAD:</div>
<div class="table-val">
<h1><span class="not-important">Hint:</span> <br/> {{hint}}</h1>
<h2><span class="not-important">Reported at:</span> <br/> {{created-at}}</h2>
<h2><span class="not-important">Report ID:</span> <br/> {{id}}</h2>
</div>
</div>
<div class="table-row multiline">
<div id="context" class="table-key">CONTEXT: </div>
<div class="table-val">
<pre>{{context}}</pre>
</div>
</div>
<div class="table-row multiline">
<div id="result" class="table-key">RESULT: </div>
<div class="table-val">
<pre>{{result}}</pre>
</div>
</div>
</div>
</main>
{% endblock %}

View File

@@ -3,9 +3,9 @@
{:default
[[:default :window "200000/h"]]
;; #{:main/get-teams}
;; #{:command/get-teams}
;; [[:burst :bucket "5/5/5s"]]
;; #{:main/get-profile}
;; #{:command/get-profile}
;; [[:burst :bucket "60/60/1m"]]
}

View File

@@ -240,13 +240,6 @@
(tmpl/render (-> content
(assoc :id id)
(assoc :version 4)
(assoc :created-at (ct/format-inst created-at :rfc1123))))))
(render-template-v5 [{:keys [content id created-at]}]
(-> (io/resource "app/templates/error-report.v5.tmpl")
(tmpl/render (-> content
(assoc :id id)
(assoc :version 5)
(assoc :created-at (ct/format-inst created-at :rfc1123))))))]
(if-let [report (get-report request)]
@@ -254,8 +247,7 @@
1 (render-template-v1 report)
2 (render-template-v2 report)
3 (render-template-v3 report)
4 (render-template-v4 report)
5 (render-template-v5 report))]
4 (render-template-v4 report))]
{::yres/status 200
::yres/body result
::yres/headers {"content-type" "text/html; charset=utf-8"

View File

@@ -213,14 +213,14 @@
(assoc "access-control-allow-origin" origin)
(assoc "access-control-allow-methods" "GET,POST,DELETE,OPTIONS,PUT,HEAD,PATCH")
(assoc "access-control-allow-credentials" "true")
(assoc "access-control-expose-headers" "content-type, set-cookie")
(assoc "access-control-allow-headers" "x-frontend-version, x-client, x-requested-width, content-type, accept, cookie")))
(assoc "access-control-expose-headers" "x-requested-with, content-type, cookie")
(assoc "access-control-allow-headers" "x-frontend-version, content-type, accept, x-requested-width")))
(defn wrap-cors
[handler]
(fn [request]
(let [response (if (= (yreq/method request) :options)
{::yres/status 204}
{::yres/status 200}
(handler request))
origin (yreq/get-header request "origin")]
(update response ::yres/headers with-cors-headers origin))))

View File

@@ -151,22 +151,20 @@
uuid/zero)
props (-> (or (::replace-props resultm)
(merge params (::props resultm)))
(-> params
(merge (::props resultm))
(dissoc :profile-id)
(dissoc :type)))
(clean-props))
context (merge (::context resultm)
(prepare-context-from-request request))
ip-addr (inet/parse-request request)
module (get cfg ::rpc/module)]
ip-addr (inet/parse-request request)]
{::type (or (::type resultm)
(::rpc/type cfg))
::name (or (::name resultm)
(let [sname (::sv/name mdata)]
(if (not= module "main")
(str module "-" sname)
sname)))
(::sv/name mdata))
::profile-id profile-id
::ip-addr ip-addr
::props props

View File

@@ -15,7 +15,6 @@
[app.config :as cf]
[app.db :as db]
[app.loggers.audit :as audit]
[app.rpc.rlimit :as-alias rlimit]
[clojure.spec.alpha :as s]
[integrant.core :as ig]
[promesa.exec :as px]
@@ -42,7 +41,7 @@
(or (instance? java.util.concurrent.CompletionException cause)
(instance? java.util.concurrent.ExecutionException cause)))
(defn- log-record->report
(defn record->report
[{:keys [::l/context ::l/message ::l/props ::l/logger ::l/level ::l/cause] :as record}]
(assert (l/valid-record? record) "expectd valid log record")
(let [data (if (concurrent-exception? cause)
@@ -87,16 +86,16 @@
[{:keys [::db/pool]} {:keys [::l/id] :as record}]
(try
(let [uri (cf/get :public-uri)
report (-> record log-record->report d/without-nils)]
report (-> record record->report d/without-nils)]
(l/dbg :hint "registering error on database"
:id (str id)
:id id
:src "logging"
:uri (str uri "/dbg/error/" id))
(persist-on-database! pool id 3 report))
(catch Throwable cause
(l/warn :hint "unexpected exception on database error logger" :cause cause))))
(defn- audit-event->report
(defn- event->report
[{:keys [::audit/context ::audit/props ::audit/ip-addr] :as record}]
(let [context
(reduce-kv (fn [context k v]
@@ -126,51 +125,15 @@
[{:keys [::db/pool]} {:keys [::audit/id] :as event}]
(try
(let [uri (cf/get :public-uri)
report (-> event audit-event->report d/without-nils)]
report (-> event event->report d/without-nils)]
(l/dbg :hint "registering error on database"
:id (str id)
:id id
:src "audit-log"
:uri (str uri "/dbg/error/" id))
(persist-on-database! pool id 4 report))
(catch Throwable cause
(l/warn :hint "unexpected exception on database error logger" :cause cause))))
(defn- rlimit-event->report
[event]
(let [context
(-> {}
(assoc :rlimit/uid (::rlimit/uid event))
(assoc :rlimit/method (::rlimit/method event))
(assoc :backend/tenant (cf/get :tenant))
(assoc :backend/host (cf/get :host))
(assoc :backend/public-uri (str (cf/get :public-uri)))
(assoc :backend/version (:full cf/version)))
result
(->> (::rlimit/results event)
(mapv (fn [result]
(-> (into (sorted-map) result)
(dissoc ::rlimit/method)))))]
{:hint (str "Rate Limit Rejection: " (::rlimit/method event) " for " (::rlimit/uid event))
:context (-> (into (sorted-map) context)
(pp/pprint-str :length 50))
:result (pp/pprint-str result :length 50)}))
(defn- handle-rlimit-event
"Convert the log record into a report object and persist it on the database"
[{:keys [::db/pool]} {:keys [::rlimit/id] :as event}]
(try
(let [uri (cf/get :public-uri)
report (-> event rlimit-event->report d/without-nils)]
(l/dbg :hint "registering rate limit rejection"
:id (str id)
:src "rlimit"
:uri (str uri "/dbg/error/" id))
(persist-on-database! pool id 5 report))
(catch Throwable cause
(l/warn :hint "unexpected exception on database error logger" :cause cause))))
(defmethod ig/assert-key ::reporter
[_ params]
(assert (db/pool? (::db/pool params)) "expect valid database pool"))
@@ -191,9 +154,6 @@
(::audit/id item)
(handle-audit-event cfg item)
(::rlimit/id item)
(handle-rlimit-event cfg item)
:else
(l/warn :hint "received unexpected item" :item item))

View File

@@ -9,12 +9,10 @@
(:require
[app.common.exceptions :as ex]
[app.common.logging :as l]
[app.common.pprint :as pp]
[app.common.uri :as u]
[app.config :as cf]
[app.http.client :as http]
[app.loggers.audit :as audit]
[app.rpc.rlimit :as-alias rlimit]
[app.util.json :as json]
[integrant.core :as ig]
[promesa.exec :as px]
@@ -24,28 +22,21 @@
(defn- send-mattermost-notification!
[cfg {:keys [id] :as report}]
(let [type (get report :type)
text (str "#" type " | " (get report :hint) "\n"
(when id
(str (u/join (cf/get :public-uri) "/dbg/error/" id) " "))
(let [url (u/join (cf/get :public-uri) "/dbg/error/" id)
text (str "Exception: " url " "
(when-let [pid (:profile-id report)]
(if (uuid? pid)
(str "(pid: #uuid-" pid ")")
(str "(pid: #ip-" pid ")")))
(str "(pid: #uuid-" pid ")"))
"\n"
"- host: #" (:host report) "\n"
"- tenant: #" (:tenant report) "\n"
"- origin: #" (:origin report) "\n"
(when-let [href (get report :href)]
(str "- href: `" href "`\n"))
(when-let [version (get report :frontend-version)]
(str "- frontend-version: `" version "`\n"))
(when-let [version (get report :backend-version)]
(str "- backend-version: `" version "`\n"))
"- href: `" (:href report) "`\n"
"- frontend-version: `" (:frontend-version report) "`\n"
"- backend-version: `" (:backend-version report) "`\n"
"\n"
(when-let [info (:info report)]
(str "```\n" info "```"))
(when-let [trace (:trace report)]
(str "```\n"
"Trace:\n"
@@ -63,15 +54,13 @@
(l/warn :hint "error on sending data"
:response (pr-str resp)))))
(defn- log-record->report
[{:keys [::l/context ::l/id ::l/cause ::l/message] :as record}]
(defn- record->report
[{:keys [::l/context ::l/id ::l/cause] :as record}]
(assert (l/valid-record? record) "expectd valid log record")
(let [public-uri (cf/get :public-uri)]
{:id id
:type "exception"
:origin "logging"
:hint (or (some-> cause ex-message) @message)
:tenant (cf/get :tenant)
:host (cf/get :host)
:backend-version (:full cf/version)
@@ -85,9 +74,7 @@
(defn- audit-event->report
[{:keys [::audit/context ::audit/props ::audit/id] :as event}]
{:id id
:type "exception"
:origin "audit-log"
:hint (get props :hint)
:tenant (cf/get :tenant)
:host (cf/get :host)
:backend-version (:full cf/version)
@@ -95,35 +82,18 @@
:profile-id (:audit/profile-id event)
:href (get props :href)})
(defn- rlimit-event->report
[event]
{:id (::rlimit/id event)
:type "notification"
:origin "rlimit"
:hint (str "rlimit reject of "
(::rlimit/method event)
" for "
(::rlimit/uid event))
:tenant (cf/get :tenant)
:host (cf/get :host)
:backend-version (:full cf/version)
:profile-id (::rlimit/profile-id event)
:info (with-out-str
(println "Rejected by:")
(println "------------")
(println "Method: " (::rlimit/method event))
(println "Limit Name: " (::rlimit/name event))
(println "Limit Strategy:" (::rlimit/strategy event))
(println)
(println "Results & Config:")
(println "-----------------")
(doseq [result (::rlimit/results event)]
(pp/pprint (into (sorted-map) result))))})
(defn- handle-event
[cfg event event->report]
(defn- handle-log-record
[cfg record]
(try
(let [report (event->report event)]
(let [report (record->report record)]
(send-mattermost-notification! cfg report))
(catch Throwable cause
(l/warn :hint "unhandled error" :cause cause))))
(defn- handle-audit-event
[cfg record]
(try
(let [report (audit-event->report record)]
(send-mattermost-notification! cfg report))
(catch Throwable cause
(l/warn :hint "unhandled error" :cause cause))))
@@ -146,13 +116,10 @@
(when @enabled
(cond
(::l/id item)
(handle-event cfg item log-record->report)
(handle-log-record cfg item)
(::audit/id item)
(handle-event cfg item audit-event->report)
(::rlimit/id item)
(handle-event cfg item rlimit-event->report)
(handle-audit-event cfg item)
:else
(l/warn :hint "received unexpected item" :item item)))

View File

@@ -317,13 +317,7 @@
::climit/enabled (contains? cf/flags :rpc-climit)}
:app.rpc/rlimit
{::wrk/executor (ig/ref ::wrk/netty-executor)
:app.loggers.mattermost/reporter
(ig/ref :app.loggers.mattermost/reporter)
:app.loggers.database/reporter
(ig/ref :app.loggers.database/reporter)}
{::wrk/executor (ig/ref ::wrk/netty-executor)}
:app.rpc/methods
{::http.client/client (ig/ref ::http.client/client)

View File

@@ -90,7 +90,7 @@
[methods]
(let [methods (update-vals methods peek)]
(fn [{:keys [params path-params method] :as request}]
(let [handler-name (:method-name path-params)
(let [handler-name (:type path-params)
etag (yreq/get-header request "if-none-match")
key-id (get request ::http/auth-key-id)
@@ -227,8 +227,8 @@
(wrap-authentication cfg $ mdata)))
(defn- process-method
[cfg wrap-fn [f mdata]]
(l/trc :hint "add method" :module (::module cfg) :type (::type cfg) :name (::sv/name mdata))
[cfg module wrap-fn [f mdata]]
(l/trc :hint "add method" :module module :name (::sv/name mdata))
(let [f (wrap-fn cfg f mdata)
k (keyword (::sv/name mdata))]
[k [mdata (partial f cfg)]]))
@@ -239,7 +239,7 @@
(defn- resolve-methods
[cfg]
(let [cfg (assoc cfg ::module "main" ::type "command" ::metrics-id :rpc-main-timing)]
(let [cfg (assoc cfg ::type "command" ::metrics-id :rpc-command-timing)]
(->> (sv/scan-ns
'app.rpc.commands.access-token
'app.rpc.commands.audit
@@ -266,7 +266,7 @@
'app.rpc.commands.verify-token
'app.rpc.commands.viewer
'app.rpc.commands.webhooks)
(map (partial process-method cfg wrap))
(map (partial process-method cfg "rpc" wrap))
(into {}))))
(def ^:private schema:methods-params
@@ -298,13 +298,13 @@
(defn- resolve-management-methods
[cfg]
(let [cfg (assoc cfg ::module "management" ::type "command" ::metrics-id :rpc-management-timing)
(let [cfg (assoc cfg ::type "management" ::metrics-id :rpc-management-timing)
mods (cond->> (list 'app.rpc.management.exporter)
(contains? cf/flags :nitrate)
(cons 'app.rpc.management.nitrate))]
(->> (apply sv/scan-ns mods)
(map (partial process-method cfg wrap-management))
(map (partial process-method cfg "management" wrap-management))
(into {}))))
(def ^:private schema:management-methods-params
@@ -359,7 +359,7 @@
(let [public-uri (cf/get :public-uri)]
["/api"
["/management"
["/methods/:method-name"
["/methods/:type"
{:middleware [[mw/shared-key-auth shared-keys]
[session/authz cfg]]
:handler (make-rpc-handler management-methods)}]
@@ -370,7 +370,7 @@
:description "MANAGEMENT API")]
["/main"
["/methods/:method-name"
["/methods/:type"
{:middleware [[mw/cors]
[sec/client-header-check]
[session/authz cfg]
@@ -388,7 +388,7 @@
["/openapi" {:handler (redirect (u/join public-uri "/api/main/doc/openapi"))}]
["/openapi.join" {:handler (redirect (u/join public-uri "/api/main/doc/openapi.json"))}]
["/rpc/command/:method-name"
["/rpc/command/:type"
{:middleware [[mw/cors]
[sec/client-header-check]
[session/authz cfg]

View File

@@ -52,8 +52,6 @@
[app.common.uuid :as uuid]
[app.config :as cf]
[app.http :as-alias http]
[app.loggers.database :as loggers.db]
[app.loggers.mattermost :as loggers.mm]
[app.redis :as rds]
[app.redis.script :as-alias rscript]
[app.rpc :as-alias rpc]
@@ -173,9 +171,9 @@
:hint (str/ffmt "looks like '%' does not have a valid format" opts))))
(defmethod process-limit :bucket
[rconn profile-id now {:keys [::key ::params ::method ::capacity ::interval ::rate] :as limit}]
[rconn profile-id now {:keys [::key ::params ::service ::capacity ::interval ::rate] :as limit}]
(let [script (-> bucket-rate-limit-script
(assoc ::rscript/keys [(str key "." method "." profile-id)])
(assoc ::rscript/keys [(str key "." service "." profile-id)])
(assoc ::rscript/vals (conj params (->seconds now))))
result (rds/eval rconn script)
allowed? (boolean (nth result 0))
@@ -183,7 +181,7 @@
reset (* (/ (inst-ms interval) rate)
(- capacity remaining))]
(l/trace :hint "limit processed"
:method method
:service service
:limit (name (::name limit))
:strategy (name (::strategy limit))
:opts (::opts limit)
@@ -195,17 +193,17 @@
(assoc ::lresult/remaining remaining))))
(defmethod process-limit :window
[rconn uid now {:keys [::permits ::unit ::key ::method] :as limit}]
[rconn profile-id now {:keys [::permits ::unit ::key ::service] :as limit}]
(let [ts (ct/truncate now unit)
ttl (ct/diff now (ct/plus ts {unit 1}))
script (-> window-rate-limit-script
(assoc ::rscript/keys [(str key "." method "." uid "." (ct/format-inst ts))])
(assoc ::rscript/keys [(str key "." service "." profile-id "." (ct/format-inst ts))])
(assoc ::rscript/vals [permits (->seconds ttl)]))
result (rds/eval rconn script)
allowed? (boolean (nth result 0))
remaining (nth result 1)]
(l/trace :hint "limit processed"
:method method
:service service
:name (name (::name limit))
:strategy (name (::strategy limit))
:opts (::opts limit)
@@ -213,13 +211,12 @@
:remaining remaining)
(-> limit
(assoc ::lresult/allowed allowed?)
(assoc ::lresult/timestamp ts)
(assoc ::lresult/remaining remaining)
(assoc ::lresult/reset (ct/plus ts {unit 1})))))
(defn- process-limits
[{:keys [::rds/conn] :as cfg} uid limits now]
(let [results (into [] (map (partial process-limit conn uid now)) limits)
[rconn profile-id limits now]
(let [results (into [] (map (partial process-limit rconn profile-id now)) limits)
remaining (->> results
(d/index-by ::name ::lresult/remaining)
(uri/map->query-string))
@@ -230,22 +227,11 @@
rejected (d/seek (complement ::lresult/allowed) results)]
(when rejected
(let [event {::id (uuid/next)
::uid uid
::method (-> rejected ::method name)
::name (-> rejected ::name name)
::strategy (-> rejected ::strategy name)
::results results}]
(l/warn :hint "rejected rate limit"
:method (-> rejected ::method name)
:name (-> rejected ::name name)
:strategy (-> rejected ::strategy name)
:uid (str uid)
:report-id (:id event))
(loggers.mm/emit cfg event)
(loggers.db/emit cfg event)))
(l/warn :hint "rejected rate limit"
:profile-id (str profile-id)
:limit-service (-> rejected ::service name)
:limit-name (-> rejected ::name name)
:limit-strategy (-> rejected ::strategy name)))
{::enabled true
::allowed (not (some? rejected))
@@ -258,7 +244,7 @@
[state skey sname]
(when-let [limits (or (get-in @state [::limits skey])
(get-in @state [::limits :default]))]
(into [] (map #(assoc % ::method sname)) limits)))
(into [] (map #(assoc % ::service sname)) limits)))
(defn- get-uid
[{:keys [::rpc/profile-id] :as params}]
@@ -268,10 +254,10 @@
uuid/zero)))
(defn- process-request'
[cfg limits params]
[{:keys [::rds/conn] :as cfg} limits params]
(try
(let [uid (get-uid params)
result (process-limits cfg uid limits (ct/now))]
result (process-limits conn uid limits (ct/now))]
(if (contains? cf/flags :soft-rpc-rlimit)
{::enabled false}
result))
@@ -289,8 +275,8 @@
(assert (or (nil? rlimit) (valid-rlimit-instance? rlimit)) "expected a valid rlimit instance")
(if rlimit
(let [skey (keyword (::rpc/module cfg) (->> mdata ::sv/spec name))
sname (str (::rpc/module cfg) "." (->> mdata ::sv/spec name))
(let [skey (keyword (::rpc/type cfg) (->> mdata ::sv/spec name))
sname (str (::rpc/type cfg) "." (->> mdata ::sv/spec name))
cfg (-> cfg
(assoc ::skey skey)
(assoc ::sname sname))]

View File

@@ -33,7 +33,6 @@
java.util.Optional
java.util.concurrent.atomic.AtomicLong
org.reactivestreams.Subscriber
software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider
software.amazon.awssdk.core.ResponseBytes
software.amazon.awssdk.core.async.AsyncRequestBody
software.amazon.awssdk.core.async.AsyncResponseTransformer
@@ -200,8 +199,7 @@
(defn- build-s3-client
[{:keys [::region ::endpoint ::wrk/netty-io-executor]}]
(let [creds-provider (DefaultCredentialsProvider/create)
aconfig (-> (ClientAsyncConfiguration/builder)
(let [aconfig (-> (ClientAsyncConfiguration/builder)
(.build))
sconfig (-> (S3Configuration/builder)
@@ -223,7 +221,6 @@
builder (.asyncConfiguration ^S3AsyncClientBuilder builder ^ClientAsyncConfiguration aconfig)
builder (.httpClient ^S3AsyncClientBuilder builder ^NettyNioAsyncHttpClient hclient)
builder (.region ^S3AsyncClientBuilder builder (lookup-region region))
builder (.credentialsProvider ^S3AsyncClientBuilder builder creds-provider)
builder (cond-> ^S3AsyncClientBuilder builder
(some? endpoint)
(.endpointOverride (URI. (str endpoint))))]
@@ -240,8 +237,7 @@
(defn- build-s3-presigner
[{:keys [::region ::endpoint]}]
(let [creds-provider (DefaultCredentialsProvider/create)
config (-> (S3Configuration/builder)
(let [config (-> (S3Configuration/builder)
(cond-> (some? endpoint) (.pathStyleAccessEnabled true))
(.build))]
@@ -249,7 +245,6 @@
(cond-> (some? endpoint) (.endpointOverride (URI. (str endpoint))))
(.region (lookup-region region))
(.serviceConfiguration ^S3Configuration config)
(.credentialsProvider creds-provider)
(.build))))
(defn- write-input-stream

View File

@@ -104,13 +104,13 @@
(assoc-in [::db/pool ::db/password] (:database-password config))
(assoc-in [:app.rpc/methods :app.setup/templates] templates)
(assoc-in [:app.rpc/methods :app.setup/templates] templates)
(update :app.rpc/rlimit assoc
:app.loggers.mattermost/reporter nil
:app.loggers.database/reporter nil)
(update :app.rpc/methods assoc
:app.setup/templates templates
:app.loggers.mattermost/reporter nil
:app.loggers.database/reporter nil)
(update :app.rpc/methods
(fn [state]
(-> state
(assoc :app.setup/templates templates)
(assoc :app.loggers.mattermost/reporter nil)
(assoc :app.loggers.database/reporter nil))))
(dissoc :app.srepl/server
:app.http/server
:app.http/route

View File

@@ -35,7 +35,7 @@
[::sm/text {:error/fn token-value-empty-fn}])
(def schema:token-value-font-family
[:vector ::sm/text])
[:vector :string])
(def schema:token-value-typography-map
[:map

View File

@@ -50,7 +50,6 @@ services:
- 4400:4400
- 4401:4401
- 4402:4402
- 4403:4403
# Plugins
- 4200:4200

View File

@@ -5,8 +5,7 @@ ENV LANG=en_US.UTF-8 \
LC_ALL=en_US.UTF-8 \
NODE_VERSION=v22.22.0 \
DEBIAN_FRONTEND=noninteractive \
PATH=/opt/node/bin:/opt/imagick/bin:$PATH \
PLAYWRIGHT_BROWSERS_PATH=/opt/penpot/browsers
PATH=/opt/node/bin:/opt/imagick/bin:$PATH
RUN set -ex; \
useradd -U -M -u 1001 -s /bin/false -d /opt/penpot penpot; \

View File

@@ -15,7 +15,6 @@ pnpm run build;
cp pnpm-lock.yaml target/;
cp package.json target/;
touch target/pnpm-workspace.yaml;
cat <<EOF | tee target/setup
#/usr/bin/env bash
@@ -23,7 +22,7 @@ set -e;
corepack enable;
corepack install;
pnpm install
pnpm exec playwright install chromium;
pnpx playwright install chromium;
EOF
chmod +x target/setup;

View File

@@ -100,14 +100,12 @@
(def browser-pool-factory
(letfn [(create []
(-> (p/let [opts #js {:args #js ["--allow-insecure-localhost" "--font-render-hinting=none"]}
browser (.launch pw/chromium opts)
id (swap! pool-browser-id inc)]
(l/info :origin "factory" :action "create" :browser-id id)
(unchecked-set browser "__id" id)
browser)
(p/catch (fn [cause]
(l/error :hint "Cannot launch the headless browser" :cause cause)))))
(p/let [opts #js {:args #js ["--allow-insecure-localhost" "--font-render-hinting=none"]}
browser (.launch pw/chromium opts)
id (swap! pool-browser-id inc)]
(l/info :origin "factory" :action "create" :browser-id id)
(unchecked-set browser "__id" id)
browser))
(destroy [obj]
(let [id (unchecked-get obj "__id")]

View File

@@ -47,13 +47,12 @@
(s/def ::params
(s/keys :req-un [::exports ::profile-id]
:opt-un [::wait ::name ::skip-children ::as-many]))
:opt-un [::wait ::name ::skip-children]))
(defn handler
[{:keys [:request/auth-token] :as exchange} {:keys [exports force-multiple] :as params}]
[{:keys [:request/auth-token] :as exchange} {:keys [exports] :as params}]
(let [exports (prepare-exports exports auth-token)]
(if (and (not force-multiple)
(= 1 (count exports))
(if (and (= 1 (count exports))
(= 1 (count (-> exports first :objects))))
(handle-single-export exchange (-> params
(assoc :export (first exports))

View File

@@ -8,6 +8,6 @@
"author": "Andrey Antukh",
"license": "MPL-2.0",
"dependencies": {
"@tokens-studio/tokenscript-interpreter": "^0.26.0"
"@tokens-studio/tokenscript-interpreter": "^0.23.1"
}
}

View File

@@ -1,12 +1,12 @@
// Auto-generated by @tokens-studio/tokenscript-schemas
// Version: @tokens-studio/tokenscript-schemas@v0.4.0
// Version: @tokens-studio/tokenscript-schemas@v0.1.2
// GitHub: https://github.com/tokens-studio/tokenscript-schemas
// Command: npx @tokens-studio/tokenscript-schemas bundle preset:css preset:cssColors --output ./schemas.js
// Generated: 2026-02-11T08:46:40.467Z
// Command: npx @tokens-studio/tokenscript-schemas bundle preset:css --output ./tokenscript-schemas.js
// Generated: 2026-01-07T09:21:11.478Z
import { Config } from "@tokens-studio/tokenscript-interpreter";
export const SCHEMAS = [
const SCHEMAS = [
{
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/hex-color/0/",
schema: {
@@ -31,127 +31,7 @@ export const SCHEMAS = [
}
}
],
"conversions": [
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/",
"target": "$self",
"description": "Converts sRGB (0-1) to Hex format",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// sRGB to Hex Conversion\n// Converts sRGB (0-1) to hexadecimal string format\n//\n// Examples:\n// sRGB(1, 0, 0) → #ff0000\n// sRGB(0, 1, 0.5) → #00ff80\n\nvariable hex: String = \"#\";\nvariable value: Number = 0;\n\n// Red channel\nvalue = round({input}.r * 255);\nif (value < 0) [ value = 0; ];\nif (value > 255) [ value = 255; ];\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Green channel\nvalue = round({input}.g * 255);\nif (value < 0) [ value = 0; ];\nif (value > 255) [ value = 255; ];\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Blue channel\nvalue = round({input}.b * 255);\nif (value < 0) [ value = 0; ];\nif (value > 255) [ value = 255; ];\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\nreturn hex;"
}
},
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/p3-color/0/",
"target": "$self",
"description": "Converts Display P3 to Hex format (clamps to sRGB gamut)",
"lossless": false,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// Display P3 to Hex Conversion\n// Converts P3 (0-1) to hexadecimal string format\n// Note: P3 colors may be out of sRGB gamut, values are clamped to 0-1\n//\n// Examples:\n// P3(1, 0, 0) → #ff0000\n// P3(0, 1, 0.5) → #00ff80\n\nvariable hex: String = \"#\";\nvariable value: Number = 0;\n\n// Red channel (clamp P3 to sRGB range)\nvalue = {input}.r;\nif (value < 0) [ value = 0; ];\nif (value > 1) [ value = 1; ];\nvalue = round(value * 255);\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Green channel\nvalue = {input}.g;\nif (value < 0) [ value = 0; ];\nif (value > 1) [ value = 1; ];\nvalue = round(value * 255);\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Blue channel\nvalue = {input}.b;\nif (value < 0) [ value = 0; ];\nif (value > 1) [ value = 1; ];\nvalue = round(value * 255);\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\nreturn hex;"
}
},
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/hsl-color/0/",
"target": "$self",
"description": "Converts HSL to Hex format",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// HSL to Hex Conversion\n// Converts HSL to hexadecimal string format\n// Reference: Standard HSL to RGB algorithm\n//\n// Input: Color.HSL with h (0-360), s (0-1), l (0-1)\n// Output: Hex string #rrggbb\n\n// Get input HSL values\nvariable h: Number = {input}.h;\nvariable s: Number = {input}.s;\nvariable l: Number = {input}.l;\n\n// Normalize hue to 0-1 range\nvariable hue: Number = h / 360;\n\n// RGB values (default to achromatic)\nvariable r: Number = l;\nvariable g: Number = l;\nvariable b: Number = l;\n\n// Only calculate if there's saturation\nif (s > 0) [\n variable q: Number = 0;\n if (l < 0.5) [\n q = l * (1 + s);\n ] else [\n q = l + s - l * s;\n ];\n\n variable p: Number = 2 * l - q;\n\n // Red (hue + 1/3)\n variable tr: Number = hue + 0.333333333333333;\n if (tr < 0) [ tr = tr + 1; ];\n if (tr > 1) [ tr = tr - 1; ];\n\n if (tr < 0.166666666666667) [\n r = p + (q - p) * 6 * tr;\n ] else [\n if (tr < 0.5) [\n r = q;\n ] else [\n if (tr < 0.666666666666667) [\n r = p + (q - p) * (0.666666666666667 - tr) * 6;\n ] else [\n r = p;\n ];\n ];\n ];\n\n // Green (hue)\n variable tg: Number = hue;\n if (tg < 0) [ tg = tg + 1; ];\n if (tg > 1) [ tg = tg - 1; ];\n\n if (tg < 0.166666666666667) [\n g = p + (q - p) * 6 * tg;\n ] else [\n if (tg < 0.5) [\n g = q;\n ] else [\n if (tg < 0.666666666666667) [\n g = p + (q - p) * (0.666666666666667 - tg) * 6;\n ] else [\n g = p;\n ];\n ];\n ];\n\n // Blue (hue - 1/3)\n variable tb: Number = hue - 0.333333333333333;\n if (tb < 0) [ tb = tb + 1; ];\n if (tb > 1) [ tb = tb - 1; ];\n\n if (tb < 0.166666666666667) [\n b = p + (q - p) * 6 * tb;\n ] else [\n if (tb < 0.5) [\n b = q;\n ] else [\n if (tb < 0.666666666666667) [\n b = p + (q - p) * (0.666666666666667 - tb) * 6;\n ] else [\n b = p;\n ];\n ];\n ];\n];\n\n// Convert RGB to hex\nvariable hex: String = \"#\";\nvariable value: Number = 0;\n\n// Red\nvalue = round(r * 255);\nif (value < 0) [ value = 0; ];\nif (value > 255) [ value = 255; ];\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Green\nvalue = round(g * 255);\nif (value < 0) [ value = 0; ];\nif (value > 255) [ value = 255; ];\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Blue\nvalue = round(b * 255);\nif (value < 0) [ value = 0; ];\nif (value > 255) [ value = 255; ];\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\nreturn hex;"
}
},
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/oklch-color/0/",
"target": "$self",
"description": "Converts OKLCH to Hex format (clamps to sRGB gamut)",
"lossless": false,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// OKLCH to Hex Conversion\n// Converts OKLCH perceptual color to hexadecimal string format\n// Path: OKLCH → OKLab → XYZ-D65 → Linear sRGB → sRGB → Hex\n//\n// Input: Color.OKLCH with l (0-1), c, h (0-360)\n// Output: Hex string #rrggbb\n\n// Get input OKLCH values\nvariable ok_l: Number = {input}.l;\nvariable ok_c: Number = {input}.c;\nvariable ok_h: Number = {input}.h;\n\n// === Step 1: OKLCH to OKLab (polar to cartesian) ===\nvariable pi: Number = pi();\nvariable deg_to_rad: Number = pi / 180;\nvariable h_rad: Number = ok_h * deg_to_rad;\n\nvariable lab_a: Number = ok_c * cos(h_rad);\nvariable lab_b: Number = ok_c * sin(h_rad);\n\n// === Step 2: OKLab to XYZ-D65 ===\n// Inverse Lab-to-LMS matrix\nvariable lms_l: Number = 1.0 * ok_l + 0.3963377773761749 * lab_a + 0.2158037573099136 * lab_b;\nvariable lms_m: Number = 1.0 * ok_l + -0.1055613458156586 * lab_a + -0.0638541728258133 * lab_b;\nvariable lms_s: Number = 1.0 * ok_l + -0.0894841775298119 * lab_a + -1.2914855480194092 * lab_b;\n\n// Cube the values (inverse of cube root)\nvariable lms_l_cubed: Number = lms_l * lms_l * lms_l;\nvariable lms_m_cubed: Number = lms_m * lms_m * lms_m;\nvariable lms_s_cubed: Number = lms_s * lms_s * lms_s;\n\n// Inverse LMS-to-XYZ matrix\nvariable xyz_x: Number = 1.2268798758459243 * lms_l_cubed + -0.5578149944602171 * lms_m_cubed + 0.2813910456659647 * lms_s_cubed;\nvariable xyz_y: Number = -0.0405757452148008 * lms_l_cubed + 1.1122868032803170 * lms_m_cubed + -0.0717110580655164 * lms_s_cubed;\nvariable xyz_z: Number = -0.0763729366746601 * lms_l_cubed + -0.4214933324022432 * lms_m_cubed + 1.5869240198367816 * lms_s_cubed;\n\n// === Step 3: XYZ-D65 to Linear sRGB ===\nvariable linear_r: Number = 3.2409699419045226 * xyz_x + -1.537383177570094 * xyz_y + -0.4986107602930034 * xyz_z;\nvariable linear_g: Number = -0.9692436362808796 * xyz_x + 1.8759675015077202 * xyz_y + 0.04155505740717559 * xyz_z;\nvariable linear_b: Number = 0.05563007969699366 * xyz_x + -0.20397695888897652 * xyz_y + 1.0569715142428786 * xyz_z;\n\n// === Step 4: Linear sRGB to sRGB (gamma correction) ===\nvariable threshold: Number = 0.0031308;\nvariable linear_scale: Number = 12.92;\nvariable gamma_offset: Number = 0.055;\nvariable gamma_scale: Number = 1.055;\nvariable gamma_exp: Number = 0.416666666666667;\n\nvariable srgb_r: Number = 0;\nif (linear_r <= threshold) [\n srgb_r = linear_r * linear_scale;\n] else [\n if (linear_r > 0) [\n srgb_r = gamma_scale * pow(linear_r, gamma_exp) - gamma_offset;\n ] else [\n srgb_r = 0;\n ];\n];\n\nvariable srgb_g: Number = 0;\nif (linear_g <= threshold) [\n srgb_g = linear_g * linear_scale;\n] else [\n if (linear_g > 0) [\n srgb_g = gamma_scale * pow(linear_g, gamma_exp) - gamma_offset;\n ] else [\n srgb_g = 0;\n ];\n];\n\nvariable srgb_b: Number = 0;\nif (linear_b <= threshold) [\n srgb_b = linear_b * linear_scale;\n] else [\n if (linear_b > 0) [\n srgb_b = gamma_scale * pow(linear_b, gamma_exp) - gamma_offset;\n ] else [\n srgb_b = 0;\n ];\n];\n\n// === Step 5: sRGB to Hex ===\nvariable hex: String = \"#\";\nvariable value: Number = 0;\n\n// Red (clamp to 0-1)\nvalue = srgb_r;\nif (value < 0) [ value = 0; ];\nif (value > 1) [ value = 1; ];\nvalue = round(value * 255);\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Green\nvalue = srgb_g;\nif (value < 0) [ value = 0; ];\nif (value > 1) [ value = 1; ];\nvalue = round(value * 255);\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\n// Blue\nvalue = srgb_b;\nif (value < 0) [ value = 0; ];\nif (value > 1) [ value = 1; ];\nvalue = round(value * 255);\nif (value < 16) [\n hex = hex.concat(\"0\").concat(value.to_string(16));\n] else [\n hex = hex.concat(value.to_string(16));\n];\n\nreturn hex;"
}
}
]
}
},
{
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/",
schema: {
"name": "SRGB",
"type": "color",
"description": "sRGB color space with normalized 0-1 range. The standard color space for web and displays.",
"schema": {
"type": "object",
"properties": {
"r": {
"type": "number",
"description": "Red channel (0-1)"
},
"g": {
"type": "number",
"description": "Green channel (0-1)"
},
"b": {
"type": "number",
"description": "Blue channel (0-1)"
}
},
"required": [
"r",
"g",
"b"
],
"order": [
"r",
"g",
"b"
],
"additionalProperties": false
},
"initializers": [
{
"title": "sRGB Color Initializer",
"keyword": "srgb",
"description": "Creates an sRGB color from normalized 0-1 values",
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// sRGB Color Initializer\n// Creates an sRGB color from normalized 0-1 values\n// Input: List of [r, g, b] or [r, g, b, alpha] values in 0-1 range\n\nvariable color_values: List = {input};\nvariable output: Color.SRGB;\n\noutput.r = color_values.get(0);\noutput.g = color_values.get(1);\noutput.b = color_values.get(2);\n\n// Set alpha if provided as 4th parameter\nif (color_values.length() > 3) [\n output.alpha = color_values.get(3);\n];\n\nreturn output;"
}
}
],
"conversions": [
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/rgb-color/0/",
"target": "$self",
"description": "Converts RGB (0-255) to sRGB (0-1) by normalizing",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// RGB to sRGB Conversion\n// Converts RGB (0-255) to sRGB (0-1) by normalizing\n// Input: Color.Rgb with r, g, b in 0-255 range\n// Output: Color.SRGB with r, g, b in 0-1 range\n// Lossless: Yes (simple division)\n\nvariable r_normalized: Number = {input}.r / 255;\nvariable g_normalized: Number = {input}.g / 255;\nvariable b_normalized: Number = {input}.b / 255;\n\nvariable output: Color.SRGB;\noutput.r = r_normalized;\noutput.g = g_normalized;\noutput.b = b_normalized;\n\nreturn output;"
}
},
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/hsl-color/0/",
"target": "$self",
"description": "Converts HSL to sRGB",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// HSL to sRGB Conversion\n// Reference: https://github.com/color-js/color.js/blob/main/src/spaces/hsl.js\n//\n// Algorithm:\n// 1. If saturation is 0, it's achromatic: R=G=B=L\n// 2. Otherwise use the HSL to RGB formula:\n// - Calculate intermediate values based on L\n// - Use hue to determine RGB components\n//\n// Input: Color.HSL with h (0-360), s (0-1), l (0-1)\n// Output: Color.SRGB with r, g, b in 0-1 range\n\n// Get input HSL values\nvariable h: Number = {input}.h;\nvariable s: Number = {input}.s;\nvariable l: Number = {input}.l;\n\n// Normalize hue to 0-1 range\nvariable hue: Number = h / 360;\n\n// Output values\nvariable r: Number = l;\nvariable g: Number = l;\nvariable b: Number = l;\n\n// Only calculate if there's saturation (not achromatic)\nif (s > 0) [\n // Calculate intermediate value\n variable q: Number = 0;\n if (l < 0.5) [\n q = l * (1 + s);\n ] else [\n q = l + s - l * s;\n ];\n \n variable p: Number = 2 * l - q;\n \n // Helper function logic inlined for R (hue + 1/3)\n variable tr: Number = hue + 0.333333333333333;\n if (tr < 0) [ tr = tr + 1; ];\n if (tr > 1) [ tr = tr - 1; ];\n \n if (tr < 0.166666666666667) [\n r = p + (q - p) * 6 * tr;\n ] else [\n if (tr < 0.5) [\n r = q;\n ] else [\n if (tr < 0.666666666666667) [\n r = p + (q - p) * (0.666666666666667 - tr) * 6;\n ] else [\n r = p;\n ];\n ];\n ];\n \n // Helper function logic inlined for G (hue)\n variable tg: Number = hue;\n if (tg < 0) [ tg = tg + 1; ];\n if (tg > 1) [ tg = tg - 1; ];\n \n if (tg < 0.166666666666667) [\n g = p + (q - p) * 6 * tg;\n ] else [\n if (tg < 0.5) [\n g = q;\n ] else [\n if (tg < 0.666666666666667) [\n g = p + (q - p) * (0.666666666666667 - tg) * 6;\n ] else [\n g = p;\n ];\n ];\n ];\n \n // Helper function logic inlined for B (hue - 1/3)\n variable tb: Number = hue - 0.333333333333333;\n if (tb < 0) [ tb = tb + 1; ];\n if (tb > 1) [ tb = tb - 1; ];\n \n if (tb < 0.166666666666667) [\n b = p + (q - p) * 6 * tb;\n ] else [\n if (tb < 0.5) [\n b = q;\n ] else [\n if (tb < 0.666666666666667) [\n b = p + (q - p) * (0.666666666666667 - tb) * 6;\n ] else [\n b = p;\n ];\n ];\n ];\n];\n\n// Create output\nvariable output: Color.SRGB;\noutput.r = r;\noutput.g = g;\noutput.b = b;\n\nreturn output;"
}
},
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-linear-color/0/",
"target": "$self",
"description": "Converts Linear sRGB to sRGB by applying gamma correction",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// Linear sRGB to sRGB Conversion\n// Applies gamma correction (transfer function)\n// Reference: IEC 61966-2-1:1999 (sRGB specification)\n//\n// Algorithm:\n// if linear ≤ 0.0031308: srgb = linear * 12.92\n// else: srgb = 1.055 * linear^(1/2.4) - 0.055\n//\n// Input: Color.LinearSRGB with r, g, b in linear 0-1 range\n// Output: Color.SRGB with r, g, b in gamma-corrected 0-1 range\n\n// Gamma correction constants (IEC 61966-2-1)\nvariable threshold: Number = 0.0031308;\nvariable linear_scale: Number = 12.92;\nvariable gamma_offset: Number = 0.055;\nvariable gamma_scale: Number = 1.055;\nvariable gamma_exponent: Number = 0.416666666666667;\n\n// Get input linear values\nvariable linear_r: Number = {input}.r;\nvariable linear_g: Number = {input}.g;\nvariable linear_b: Number = {input}.b;\n\n// Convert red channel\nvariable srgb_r: Number = 0;\nif (linear_r <= threshold) [\n srgb_r = linear_r * linear_scale;\n] else [\n srgb_r = gamma_scale * pow(linear_r, gamma_exponent) - gamma_offset;\n];\n\n// Convert green channel\nvariable srgb_g: Number = 0;\nif (linear_g <= threshold) [\n srgb_g = linear_g * linear_scale;\n] else [\n srgb_g = gamma_scale * pow(linear_g, gamma_exponent) - gamma_offset;\n];\n\n// Convert blue channel\nvariable srgb_b: Number = 0;\nif (linear_b <= threshold) [\n srgb_b = linear_b * linear_scale;\n] else [\n srgb_b = gamma_scale * pow(linear_b, gamma_exponent) - gamma_offset;\n];\n\n// Create output\nvariable output: Color.SRGB;\noutput.r = srgb_r;\noutput.g = srgb_g;\noutput.b = srgb_b;\n\nreturn output;"
}
}
]
"conversions": []
}
},
{
@@ -297,6 +177,85 @@ export const SCHEMAS = [
]
}
},
{
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-color/0/",
schema: {
"name": "SRGB",
"type": "color",
"description": "sRGB color space with normalized 0-1 range. The standard color space for web and displays.",
"schema": {
"type": "object",
"properties": {
"r": {
"type": "number",
"description": "Red channel (0-1)"
},
"g": {
"type": "number",
"description": "Green channel (0-1)"
},
"b": {
"type": "number",
"description": "Blue channel (0-1)"
}
},
"required": [
"r",
"g",
"b"
],
"order": [
"r",
"g",
"b"
],
"additionalProperties": false
},
"initializers": [
{
"title": "sRGB Color Initializer",
"keyword": "srgb",
"description": "Creates an sRGB color from normalized 0-1 values",
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// sRGB Color Initializer\n// Creates an sRGB color from normalized 0-1 values\n// Input: List of [r, g, b] or [r, g, b, alpha] values in 0-1 range\n\nvariable color_values: List = {input};\nvariable output: Color.SRGB;\n\noutput.r = color_values.get(0);\noutput.g = color_values.get(1);\noutput.b = color_values.get(2);\n\n// Set alpha if provided as 4th parameter\nif (color_values.length() > 3) [\n output.alpha = color_values.get(3);\n];\n\nreturn output;"
}
}
],
"conversions": [
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/rgb-color/0/",
"target": "$self",
"description": "Converts RGB (0-255) to sRGB (0-1) by normalizing",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// RGB to sRGB Conversion\n// Converts RGB (0-255) to sRGB (0-1) by normalizing\n// Input: Color.Rgb with r, g, b in 0-255 range\n// Output: Color.SRGB with r, g, b in 0-1 range\n// Lossless: Yes (simple division)\n\nvariable r_normalized: Number = {input}.r / 255;\nvariable g_normalized: Number = {input}.g / 255;\nvariable b_normalized: Number = {input}.b / 255;\n\nvariable output: Color.SRGB;\noutput.r = r_normalized;\noutput.g = g_normalized;\noutput.b = b_normalized;\n\nreturn output;"
}
},
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/hsl-color/0/",
"target": "$self",
"description": "Converts HSL to sRGB",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// HSL to sRGB Conversion\n// Reference: https://github.com/color-js/color.js/blob/main/src/spaces/hsl.js\n//\n// Algorithm:\n// 1. If saturation is 0, it's achromatic: R=G=B=L\n// 2. Otherwise use the HSL to RGB formula:\n// - Calculate intermediate values based on L\n// - Use hue to determine RGB components\n//\n// Input: Color.HSL with h (0-360), s (0-1), l (0-1)\n// Output: Color.SRGB with r, g, b in 0-1 range\n\n// Get input HSL values\nvariable h: Number = {input}.h;\nvariable s: Number = {input}.s;\nvariable l: Number = {input}.l;\n\n// Normalize hue to 0-1 range\nvariable hue: Number = h / 360;\n\n// Output values\nvariable r: Number = l;\nvariable g: Number = l;\nvariable b: Number = l;\n\n// Only calculate if there's saturation (not achromatic)\nif (s > 0) [\n // Calculate intermediate value\n variable q: Number = 0;\n if (l < 0.5) [\n q = l * (1 + s);\n ] else [\n q = l + s - l * s;\n ];\n \n variable p: Number = 2 * l - q;\n \n // Helper function logic inlined for R (hue + 1/3)\n variable tr: Number = hue + 0.333333333333333;\n if (tr < 0) [ tr = tr + 1; ];\n if (tr > 1) [ tr = tr - 1; ];\n \n if (tr < 0.166666666666667) [\n r = p + (q - p) * 6 * tr;\n ] else [\n if (tr < 0.5) [\n r = q;\n ] else [\n if (tr < 0.666666666666667) [\n r = p + (q - p) * (0.666666666666667 - tr) * 6;\n ] else [\n r = p;\n ];\n ];\n ];\n \n // Helper function logic inlined for G (hue)\n variable tg: Number = hue;\n if (tg < 0) [ tg = tg + 1; ];\n if (tg > 1) [ tg = tg - 1; ];\n \n if (tg < 0.166666666666667) [\n g = p + (q - p) * 6 * tg;\n ] else [\n if (tg < 0.5) [\n g = q;\n ] else [\n if (tg < 0.666666666666667) [\n g = p + (q - p) * (0.666666666666667 - tg) * 6;\n ] else [\n g = p;\n ];\n ];\n ];\n \n // Helper function logic inlined for B (hue - 1/3)\n variable tb: Number = hue - 0.333333333333333;\n if (tb < 0) [ tb = tb + 1; ];\n if (tb > 1) [ tb = tb - 1; ];\n \n if (tb < 0.166666666666667) [\n b = p + (q - p) * 6 * tb;\n ] else [\n if (tb < 0.5) [\n b = q;\n ] else [\n if (tb < 0.666666666666667) [\n b = p + (q - p) * (0.666666666666667 - tb) * 6;\n ] else [\n b = p;\n ];\n ];\n ];\n];\n\n// Create output\nvariable output: Color.SRGB;\noutput.r = r;\noutput.g = g;\noutput.b = b;\n\nreturn output;"
}
},
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-linear-color/0/",
"target": "$self",
"description": "Converts Linear sRGB to sRGB by applying gamma correction",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// Linear sRGB to sRGB Conversion\n// Applies gamma correction (transfer function)\n// Reference: IEC 61966-2-1:1999 (sRGB specification)\n//\n// Algorithm:\n// if linear ≤ 0.0031308: srgb = linear * 12.92\n// else: srgb = 1.055 * linear^(1/2.4) - 0.055\n//\n// Input: Color.LinearSRGB with r, g, b in linear 0-1 range\n// Output: Color.SRGB with r, g, b in gamma-corrected 0-1 range\n\n// Gamma correction constants (IEC 61966-2-1)\nvariable threshold: Number = 0.0031308;\nvariable linear_scale: Number = 12.92;\nvariable gamma_offset: Number = 0.055;\nvariable gamma_scale: Number = 1.055;\nvariable gamma_exponent: Number = 0.416666666666667;\n\n// Get input linear values\nvariable linear_r: Number = {input}.r;\nvariable linear_g: Number = {input}.g;\nvariable linear_b: Number = {input}.b;\n\n// Convert red channel\nvariable srgb_r: Number = 0;\nif (linear_r <= threshold) [\n srgb_r = linear_r * linear_scale;\n] else [\n srgb_r = gamma_scale * pow(linear_r, gamma_exponent) - gamma_offset;\n];\n\n// Convert green channel\nvariable srgb_g: Number = 0;\nif (linear_g <= threshold) [\n srgb_g = linear_g * linear_scale;\n] else [\n srgb_g = gamma_scale * pow(linear_g, gamma_exponent) - gamma_offset;\n];\n\n// Convert blue channel\nvariable srgb_b: Number = 0;\nif (linear_b <= threshold) [\n srgb_b = linear_b * linear_scale;\n] else [\n srgb_b = gamma_scale * pow(linear_b, gamma_exponent) - gamma_offset;\n];\n\n// Create output\nvariable output: Color.SRGB;\noutput.r = srgb_r;\noutput.g = srgb_g;\noutput.b = srgb_b;\n\nreturn output;"
}
}
]
}
},
{
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/srgb-linear-color/0/",
schema: {
@@ -770,65 +729,6 @@ export const SCHEMAS = [
]
}
},
{
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/p3-color/0/",
schema: {
"name": "P3",
"type": "color",
"description": "Display-P3 color space with sRGB transfer function. Wider gamut than sRGB, common on modern Apple displays.",
"schema": {
"type": "object",
"properties": {
"r": {
"type": "number",
"description": "Red channel (0-1, can exceed for out-of-gamut)"
},
"g": {
"type": "number",
"description": "Green channel (0-1, can exceed for out-of-gamut)"
},
"b": {
"type": "number",
"description": "Blue channel (0-1, can exceed for out-of-gamut)"
}
},
"required": [
"r",
"g",
"b"
],
"order": [
"r",
"g",
"b"
],
"additionalProperties": false
},
"initializers": [
{
"title": "Display-P3 Color Initializer",
"keyword": "p3",
"description": "Creates a Display-P3 color from 0-1 values",
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// Display-P3 Color Initializer\n// Creates a Display-P3 color from 0-1 values\n// Input: List of [r, g, b] or [r, g, b, alpha] values\n\nvariable color_values: List = {input};\nvariable output: Color.P3;\n\noutput.r = color_values.get(0);\noutput.g = color_values.get(1);\noutput.b = color_values.get(2);\n\n// Set alpha if provided as 4th parameter\nif (color_values.length() > 3) [\n output.alpha = color_values.get(3);\n];\n\nreturn output;"
}
}
],
"conversions": [
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/p3-linear-color/0/",
"target": "$self",
"description": "Converts Linear P3 to P3 by applying sRGB transfer function",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// Linear P3 to P3 Conversion\n// Applies sRGB transfer function (gamma encoding)\n// P3 uses the same transfer function as sRGB\n// Reference: CSS Color Level 4\n//\n// Algorithm (same as sRGB):\n// if linear ≤ 0.0031308: encoded = 12.92 × linear\n// else: encoded = 1.055 × linear^(1/2.4) - 0.055\n//\n// Input: Color.LinearP3 with linear r, g, b values\n// Output: Color.P3 with gamma-encoded r, g, b values\n\n// Transfer function constants (same as sRGB)\nvariable threshold: Number = 0.0031308;\nvariable linear_scale: Number = 12.92;\nvariable gamma_scale: Number = 1.055;\nvariable gamma_offset: Number = 0.055;\nvariable gamma_exponent: Number = 0.4166666666666667;\n\n// Get linear values\nvariable linear_r: Number = {input}.r;\nvariable linear_g: Number = {input}.g;\nvariable linear_b: Number = {input}.b;\n\n// Convert red channel\nvariable encoded_r: Number = 0;\nif (linear_r <= threshold) [\n encoded_r = linear_scale * linear_r;\n] else [\n encoded_r = gamma_scale * pow(linear_r, gamma_exponent) - gamma_offset;\n];\n\n// Convert green channel\nvariable encoded_g: Number = 0;\nif (linear_g <= threshold) [\n encoded_g = linear_scale * linear_g;\n] else [\n encoded_g = gamma_scale * pow(linear_g, gamma_exponent) - gamma_offset;\n];\n\n// Convert blue channel\nvariable encoded_b: Number = 0;\nif (linear_b <= threshold) [\n encoded_b = linear_scale * linear_b;\n] else [\n encoded_b = gamma_scale * pow(linear_b, gamma_exponent) - gamma_offset;\n];\n\n// Create output\nvariable output: Color.P3;\noutput.r = encoded_r;\noutput.g = encoded_g;\noutput.b = encoded_b;\n\nreturn output;"
}
}
]
}
},
{
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/css-color/0/",
schema: {
@@ -1286,6 +1186,65 @@ export const SCHEMAS = [
]
}
},
{
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/p3-color/0/",
schema: {
"name": "P3",
"type": "color",
"description": "Display-P3 color space with sRGB transfer function. Wider gamut than sRGB, common on modern Apple displays.",
"schema": {
"type": "object",
"properties": {
"r": {
"type": "number",
"description": "Red channel (0-1, can exceed for out-of-gamut)"
},
"g": {
"type": "number",
"description": "Green channel (0-1, can exceed for out-of-gamut)"
},
"b": {
"type": "number",
"description": "Blue channel (0-1, can exceed for out-of-gamut)"
}
},
"required": [
"r",
"g",
"b"
],
"order": [
"r",
"g",
"b"
],
"additionalProperties": false
},
"initializers": [
{
"title": "Display-P3 Color Initializer",
"keyword": "p3",
"description": "Creates a Display-P3 color from 0-1 values",
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// Display-P3 Color Initializer\n// Creates a Display-P3 color from 0-1 values\n// Input: List of [r, g, b] or [r, g, b, alpha] values\n\nvariable color_values: List = {input};\nvariable output: Color.P3;\n\noutput.r = color_values.get(0);\noutput.g = color_values.get(1);\noutput.b = color_values.get(2);\n\n// Set alpha if provided as 4th parameter\nif (color_values.length() > 3) [\n output.alpha = color_values.get(3);\n];\n\nreturn output;"
}
}
],
"conversions": [
{
"source": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/p3-linear-color/0/",
"target": "$self",
"description": "Converts Linear P3 to P3 by applying sRGB transfer function",
"lossless": true,
"script": {
"type": "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/core/tokenscript/0/",
"script": "// Linear P3 to P3 Conversion\n// Applies sRGB transfer function (gamma encoding)\n// P3 uses the same transfer function as sRGB\n// Reference: CSS Color Level 4\n//\n// Algorithm (same as sRGB):\n// if linear ≤ 0.0031308: encoded = 12.92 × linear\n// else: encoded = 1.055 × linear^(1/2.4) - 0.055\n//\n// Input: Color.LinearP3 with linear r, g, b values\n// Output: Color.P3 with gamma-encoded r, g, b values\n\n// Transfer function constants (same as sRGB)\nvariable threshold: Number = 0.0031308;\nvariable linear_scale: Number = 12.92;\nvariable gamma_scale: Number = 1.055;\nvariable gamma_offset: Number = 0.055;\nvariable gamma_exponent: Number = 0.4166666666666667;\n\n// Get linear values\nvariable linear_r: Number = {input}.r;\nvariable linear_g: Number = {input}.g;\nvariable linear_b: Number = {input}.b;\n\n// Convert red channel\nvariable encoded_r: Number = 0;\nif (linear_r <= threshold) [\n encoded_r = linear_scale * linear_r;\n] else [\n encoded_r = gamma_scale * pow(linear_r, gamma_exponent) - gamma_offset;\n];\n\n// Convert green channel\nvariable encoded_g: Number = 0;\nif (linear_g <= threshold) [\n encoded_g = linear_scale * linear_g;\n] else [\n encoded_g = gamma_scale * pow(linear_g, gamma_exponent) - gamma_offset;\n];\n\n// Convert blue channel\nvariable encoded_b: Number = 0;\nif (linear_b <= threshold) [\n encoded_b = linear_scale * linear_b;\n] else [\n encoded_b = gamma_scale * pow(linear_b, gamma_exponent) - gamma_offset;\n];\n\n// Create output\nvariable output: Color.P3;\noutput.r = encoded_r;\noutput.g = encoded_g;\noutput.b = encoded_b;\n\nreturn output;"
}
}
]
}
},
{
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/function/lighten/0/",
schema: {
@@ -1465,165 +1424,6 @@ export const SCHEMAS = [
]
}
},
{
uri: "https://schema.tokenscript.dev.gcp.tokens.studio/api/v1/constants/css-hex-colors/0/",
schema: {
"name": "CSS Hex Colors",
"type": "constants",
"description": "CSS named colors mapped to their hex values (CSS Color Level 4)",
"inline": true,
"values": {
"aliceblue": "#F0F8FF",
"antiquewhite": "#FAEBD7",
"aqua": "#00FFFF",
"aquamarine": "#7FFFD4",
"azure": "#F0FFFF",
"beige": "#F5F5DC",
"bisque": "#FFE4C4",
"black": "#000000",
"blanchedalmond": "#FFEBCD",
"blue": "#0000FF",
"blueviolet": "#8A2BE2",
"brown": "#A52A2A",
"burlywood": "#DEB887",
"cadetblue": "#5F9EA0",
"chartreuse": "#7FFF00",
"chocolate": "#D2691E",
"coral": "#FF7F50",
"cornflowerblue": "#6495ED",
"cornsilk": "#FFF8DC",
"crimson": "#DC143C",
"cyan": "#00FFFF",
"darkblue": "#00008B",
"darkcyan": "#008B8B",
"darkgoldenrod": "#B8860B",
"darkgray": "#A9A9A9",
"darkgreen": "#006400",
"darkgrey": "#A9A9A9",
"darkkhaki": "#BDB76B",
"darkmagenta": "#8B008B",
"darkolivegreen": "#556B2F",
"darkorange": "#FF8C00",
"darkorchid": "#9932CC",
"darkred": "#8B0000",
"darksalmon": "#E9967A",
"darkseagreen": "#8FBC8F",
"darkslateblue": "#483D8B",
"darkslategray": "#2F4F4F",
"darkslategrey": "#2F4F4F",
"darkturquoise": "#00CED1",
"darkviolet": "#9400D3",
"deeppink": "#FF1493",
"deepskyblue": "#00BFFF",
"dimgray": "#696969",
"dimgrey": "#696969",
"dodgerblue": "#1E90FF",
"firebrick": "#B22222",
"floralwhite": "#FFFAF0",
"forestgreen": "#228B22",
"fuchsia": "#FF00FF",
"gainsboro": "#DCDCDC",
"ghostwhite": "#F8F8FF",
"gold": "#FFD700",
"goldenrod": "#DAA520",
"gray": "#808080",
"green": "#008000",
"greenyellow": "#ADFF2F",
"grey": "#808080",
"honeydew": "#F0FFF0",
"hotpink": "#FF69B4",
"indianred": "#CD5C5C",
"indigo": "#4B0082",
"ivory": "#FFFFF0",
"khaki": "#F0E68C",
"lavender": "#E6E6FA",
"lavenderblush": "#FFF0F5",
"lawngreen": "#7CFC00",
"lemonchiffon": "#FFFACD",
"lightblue": "#ADD8E6",
"lightcoral": "#F08080",
"lightcyan": "#E0FFFF",
"lightgoldenrodyellow": "#FAFAD2",
"lightgray": "#D3D3D3",
"lightgreen": "#90EE90",
"lightgrey": "#D3D3D3",
"lightpink": "#FFB6C1",
"lightsalmon": "#FFA07A",
"lightseagreen": "#20B2AA",
"lightskyblue": "#87CEFA",
"lightslategray": "#778899",
"lightslategrey": "#778899",
"lightsteelblue": "#B0C4DE",
"lightyellow": "#FFFFE0",
"lime": "#00FF00",
"limegreen": "#32CD32",
"linen": "#FAF0E6",
"magenta": "#FF00FF",
"maroon": "#800000",
"mediumaquamarine": "#66CDAA",
"mediumblue": "#0000CD",
"mediumorchid": "#BA55D3",
"mediumpurple": "#9370DB",
"mediumseagreen": "#3CB371",
"mediumslateblue": "#7B68EE",
"mediumspringgreen": "#00FA9A",
"mediumturquoise": "#48D1CC",
"mediumvioletred": "#C71585",
"midnightblue": "#191970",
"mintcream": "#F5FFFA",
"mistyrose": "#FFE4E1",
"moccasin": "#FFE4B5",
"navajowhite": "#FFDEAD",
"navy": "#000080",
"oldlace": "#FDF5E6",
"olive": "#808000",
"olivedrab": "#6B8E23",
"orange": "#FFA500",
"orangered": "#FF4500",
"orchid": "#DA70D6",
"palegoldenrod": "#EEE8AA",
"palegreen": "#98FB98",
"paleturquoise": "#AFEEEE",
"palevioletred": "#DB7093",
"papayawhip": "#FFEFD5",
"peachpuff": "#FFDAB9",
"peru": "#CD853F",
"pink": "#FFC0CB",
"plum": "#DDA0DD",
"powderblue": "#B0E0E6",
"purple": "#800080",
"rebeccapurple": "#663399",
"red": "#FF0000",
"rosybrown": "#BC8F8F",
"royalblue": "#4169E1",
"saddlebrown": "#8B4513",
"salmon": "#FA8072",
"sandybrown": "#F4A460",
"seagreen": "#2E8B57",
"seashell": "#FFF5EE",
"sienna": "#A0522D",
"silver": "#C0C0C0",
"skyblue": "#87CEEB",
"slateblue": "#6A5ACD",
"slategray": "#708090",
"slategrey": "#708090",
"snow": "#FFFAFA",
"springgreen": "#00FF7F",
"steelblue": "#4682B4",
"tan": "#D2B48C",
"teal": "#008080",
"thistle": "#D8BFD8",
"tomato": "#FF6347",
"turquoise": "#40E0D0",
"violet": "#EE82EE",
"wheat": "#F5DEB3",
"white": "#FFFFFF",
"whitesmoke": "#F5F5F5",
"yellow": "#FFFF00",
"yellowgreen": "#9ACD32"
}
}
},
];
export function makeConfig() {

View File

@@ -22,8 +22,8 @@
"~:has-media-trimmed": false,
"~:comment-thread-seqn": 0,
"~:name": "flex_index_position",
"~:revn": 126,
"~:modified-at": "~m1770978609930",
"~:revn": 114,
"~:modified-at": "~m1769430362161",
"~:vern": 0,
"~:id": "~u31fe2e21-73e7-80f3-8007-73894fb58240",
"~:is-shared": false,
@@ -117,63 +117,31 @@
"~:name": "Page 1",
"~:objects": {
"~#penpot/objects-map/v2": {
"~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^I\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~u77c71dba-32ee-804c-8007-736561cf857f\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~u9299427e-8172-80bb-8007-90e71cbb9fea\",\"~u9299427e-8172-80bb-8007-90e71fba0f7d\",\"~u9299427e-8172-80bb-8007-90e72469bf8c\"]]]",
"~u9299427e-8172-80bb-8007-90e71fba0f82": "[\"~#shape\",[\"^ \",\"~:y\",210.0000271241638,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:name\",\"base-background\",\"~:width\",24,\"~:type\",\"~:rect\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linejoin\",\"round\",\"~:stroke-linecap\",\"round\",\"~:id\",\"base-background\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1140,\"~:y\",210.0000271241638]],[\"^?\",[\"^ \",\"~:x\",1164,\"~:y\",210.0000271241638]],[\"^?\",[\"^ \",\"~:x\",1164,\"~:y\",234.0000271241638]],[\"^?\",[\"^ \",\"~:x\",1140,\"~:y\",234.0000271241638]]],\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c5\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:hidden\",true,\"^=\",\"~u9299427e-8172-80bb-8007-90e71fba0f82\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f81\",\"~:svg-viewbox\",[\"^ \",\"~:y\",0,\"~:y1\",0,\"^6\",24,\"~:x\",0,\"~:x1\",0,\"~:y2\",24,\"~:x2\",24,\"~:height\",24],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f81\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-color\",\"#ffffff\",\"~:stroke-opacity\",1,\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2]],\"~:x\",1140,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1140,\"~:y\",210.0000271241638,\"^6\",24,\"^K\",24,\"^H\",1140,\"^G\",210.0000271241638,\"^J\",1164,\"^I\",234.0000271241638]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",24,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e7059421c2": "[\"~#shape\",[\"^ \",\"~:y\",198.00002998518676,\"~:hide-fill-on-export\",false,\"~:layout-item-absolute\",true,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"add-favorites\",\"~:layout-align-items\",\"~:center\",\"~:width\",48,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:touched\",[\"~#set\",[\"^2\",\"~:layout-item-z-index\"]],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",792,\"~:y\",198.00002998518676]],[\"^P\",[\"^ \",\"~:x\",840,\"~:y\",198.00002998518676]],[\"^P\",[\"^ \",\"~:x\",840,\"~:y\",246.00002426314086]],[\"^P\",[\"^ \",\"~:x\",792,\"~:y\",246.00002426314086]]],\"~:r2\",50,\"~:shape-ref\",\"~uc8b014fe-f285-8021-8007-8ea400bd9406\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",50,\"~:layout-justify-content\",\"^F\",\"~:r1\",50,\"~:id\",\"~u9299427e-8172-80bb-8007-90e7059421c2\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:layout-flex-dir\",\"~:row\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"color.bg.default\"],\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea447a0bc30\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:strokes\",[],\"~:x\",792,\"~:proportion\",1,\"~:r4\",50,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",792,\"~:y\",198.00002998518676,\"^G\",48,\"~:height\",47.9999942779541,\"~:x1\",792,\"~:y1\",198.00002998518676,\"~:x2\",840,\"~:y2\",246.00002426314086]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.3]],\"~:flip-x\",null,\"^1?\",47.9999942779541,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e7059421c4\"]]]",
"~u9299427e-8172-80bb-8007-90e71fba0f83": "[\"~#shape\",[\"^ \",\"~:y\",212.99997181105346,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"svg-path\",\"~:width\",20,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1142,\"~:y\",212.99997181105346]],[\"^;\",[\"^ \",\"~:x\",1162,\"~:y\",212.99997181105346]],[\"^;\",[\"^ \",\"~:x\",1162,\"~:y\",230.99997181105346]],[\"^;\",[\"^ \",\"~:x\",1142,\"~:y\",230.99997181105346]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c6\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71fba0f83\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f81\",\"~:applied-tokens\",[\"^ \"],\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea4f64a1c9b\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f81\",\"~:strokes\",[],\"~:x\",1142,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1142,\"~:y\",212.99997181105346,\"^7\",20,\"~:height\",18,\"~:x1\",1142,\"~:y1\",212.99997181105346,\"~:x2\",1162,\"~:y2\",230.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^N\",18,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71fba0f84\"]]]",
"~u9299427e-8172-80bb-8007-90e7059421c3": "[\"~#shape\",[\"^ \",\"~:y\",192.00001259178498,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"patinegro\",\"~:width\",264.80230943863717,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",579.9999793759137,\"~:y\",192.00001259178498]],[\"^9\",[\"^ \",\"~:x\",844.8022888145506,\"~:y\",192.00001259178498]],[\"^9\",[\"^ \",\"~:x\",844.8022888145506,\"~:y\",388.1131514739925]],[\"^9\",[\"^ \",\"~:x\",579.9999793759137,\"~:y\",388.1131514739925]]],\"~:r2\",0,\"~:proportion-lock\",true,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e7059421c3\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e7059421c1\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e7059421c1\",\"~:strokes\",[],\"~:x\",579.9999793759134,\"~:proportion\",1.3487940630797774,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",579.9999793759134,\"~:y\",192.00001259178498,\"^5\",264.80230943863717,\"~:height\",196.11313888220752,\"~:x1\",579.9999793759134,\"~:y1\",192.00001259178498,\"~:x2\",844.8022888145506,\"~:y2\",388.1131514739925]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#b73d3d\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^H\",196.11313888220752,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71fba0f80": "[\"~#shape\",[\"^ \",\"~:y\",192.00001259178498,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"patinegro\",\"~:width\",264.80230943863717,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",915.9999793759137,\"~:y\",192.00001259178498]],[\"^9\",[\"^ \",\"~:x\",1180.8022888145506,\"~:y\",192.00001259178498]],[\"^9\",[\"^ \",\"~:x\",1180.8022888145506,\"~:y\",388.1131514739925]],[\"^9\",[\"^ \",\"~:x\",915.9999793759137,\"~:y\",388.1131514739925]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c3\",\"~:proportion-lock\",true,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71fba0f80\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7e\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7e\",\"~:strokes\",[],\"~:x\",915.9999793759134,\"~:proportion\",1.3487940630797774,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",915.9999793759134,\"~:y\",192.00001259178498,\"^5\",264.80230943863717,\"~:height\",196.11313888220752,\"~:x1\",915.9999793759134,\"~:y1\",192.00001259178498,\"~:x2\",1180.8022888145506,\"~:y2\",388.1131514739925]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#b73d3d\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^I\",196.11313888220752,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e7059421c0": "[\"~#shape\",[\"^ \",\"~:y\",191.99998474121094,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"card-img / patinegro\",\"~:layout-align-items\",\"~:start\",\"~:variant-name\",\"patinegro\",\"~:width\",265,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",580,\"~:y\",191.99998474121094]],[\"^M\",[\"^ \",\"~:x\",845,\"~:y\",191.99998474121094]],[\"^M\",[\"^ \",\"~:x\",845,\"~:y\",369.99997875688996]],[\"^M\",[\"^ \",\"~:x\",580,\"~:y\",369.99997875688996]]],\"~:r2\",20,\"~:component-root\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:r3\",20,\"~:layout-justify-content\",\"^E\",\"~:r1\",20,\"~:id\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~u9299427e-8172-80bb-8007-90e7059a83e2\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",580,\"~:main-instance\",true,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",580,\"~:y\",191.99998474121094,\"^G\",265,\"~:height\",177.99999401567902,\"~:x1\",580,\"~:y1\",191.99998474121094,\"~:x2\",845,\"~:y2\",369.99997875688996]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^1=\",177.99999401567902,\"~:component-file\",\"~u31fe2e21-73e7-80f3-8007-73894fb58240\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e7059421c1\",\"~u9299427e-8172-80bb-8007-90e7059421c2\"]]]",
"~u9299427e-8172-80bb-8007-90e71fba0f81": "[\"~#shape\",[\"^ \",\"~:y\",209.99999660658568,\"~:rx\",0,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:hide-in-viewer\",true,\"~:name\",\"heart\",\"~:width\",24,\"~:type\",\"~:frame\",\"~:svg-attrs\",[\"^ \",\"^8\",\"24\",\"~:height\",\"24\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1140,\"~:y\",209.99999660658568]],[\"^>\",[\"^ \",\"~:x\",1164,\"~:y\",209.99999660658568]],[\"^>\",[\"^ \",\"~:x\",1164,\"~:y\",233.99999660658568]],[\"^>\",[\"^ \",\"~:x\",1140,\"~:y\",233.99999660658568]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71fba0f81\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7f\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7f\",\"~:strokes\",[],\"~:x\",1140,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1140,\"~:y\",209.99999660658568,\"^8\",24,\"^<\",24,\"~:x1\",1140,\"~:y1\",209.99999660658568,\"~:x2\",1164,\"~:y2\",233.99999660658568]],\"~:fills\",[],\"~:flip-x\",null,\"~:ry\",0,\"^<\",24,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71fba0f82\",\"~u9299427e-8172-80bb-8007-90e71fba0f83\"]]]",
"~u9299427e-8172-80bb-8007-90e7059421c1": "[\"~#shape\",[\"^ \",\"~:y\",191.99999475401955,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"img-city\",\"~:width\",265,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",580,\"~:y\",191.99999475401978]],[\"^;\",[\"^ \",\"~:x\",845,\"~:y\",191.99999475401978]],[\"^;\",[\"^ \",\"~:x\",845,\"~:y\",369.9899634401968]],[\"^;\",[\"^ \",\"~:x\",580,\"~:y\",369.9899634401968]]],\"~:r2\",0,\"~:layout-item-h-sizing\",\"~:fill\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:layout-item-v-sizing\",\"^>\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e7059421c1\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:strokes\",[],\"~:x\",580,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",580,\"~:y\",191.99999475401955,\"^7\",265,\"~:height\",177.989968686177,\"~:x1\",580,\"~:y1\",191.99999475401955,\"~:x2\",845,\"~:y2\",369.98996344019656]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^M\",177.989968686177,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e7059421c3\"]]]",
"~u77c71dba-32ee-804c-8007-736561cff457": "[\"~#shape\",[\"^ \",\"~:y\",222.00000357564704,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",222.00000357564704]],[\"^>\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",222.00000357564704]],[\"^>\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",302.00000357564704]],[\"^>\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",302.00000357564704]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff457\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:strokes\",[],\"~:x\",379.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",222.00000357564704,\"^9\",80,\"~:height\",80,\"~:x1\",379.0000081062317,\"~:y1\",222.00000357564704,\"~:x2\",459.0000081062317,\"~:y2\",302.00000357564704]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e7059421c6": "[\"~#shape\",[\"^ \",\"~:y\",212.99997181105346,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"svg-path\",\"~:width\",20,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",806,\"~:y\",212.99997181105346]],[\"^;\",[\"^ \",\"~:x\",826,\"~:y\",212.99997181105346]],[\"^;\",[\"^ \",\"~:x\",826,\"~:y\",230.99997181105346]],[\"^;\",[\"^ \",\"~:x\",806,\"~:y\",230.99997181105346]]],\"~:r2\",0,\"~:shape-ref\",\"~uc8b014fe-f285-8021-8007-8ea51856a422\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e7059421c6\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:applied-tokens\",[\"^ \"],\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea4f64a1c9b\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:strokes\",[],\"~:x\",806,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",806,\"~:y\",212.99997181105346,\"^7\",20,\"~:height\",18,\"~:x1\",806,\"~:y1\",212.99997181105346,\"~:x2\",826,\"~:y2\",230.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^N\",18,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e705944588\"]]]",
"~u94eaebe4-addd-80d1-8007-79d508aa2885": "[\"~#shape\",[\"^ \",\"~:y\",437.999988316858,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",437.999988316858]],[\"^>\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",437.999988316858]],[\"^>\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",517.999988316858]],[\"^>\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",517.999988316858]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2885\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:strokes\",[],\"~:x\",295.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",437.999988316858,\"^9\",80,\"~:height\",80,\"~:x1\",295.0000081062317,\"~:y1\",437.999988316858,\"~:x2\",375.0000081062317,\"~:y2\",517.999988316858]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71fba0f84": "[\"~#shape\",[\"^ \",\"~:y\",null,\"~:stroke-cap-start\",\"round\",\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:content\",[\"~#penpot/path-data\",\"~bAQAAAAAAAAAAAAAAAAAAAAAAAAAA4JBE/P9fQwMAAACuD5FE/IleQwBAkUT8yVxDAECRRPx/WkMDAAAAAECRRHx2V0M08ZBE/P9UQwCQkET8/1RDAwAAAK5XkET8/1RDADCQRPx/VUMAAJBE/P9WQwMAAAAA0I9E/H9VQ1Koj0T8/1RDAHCPRPz/VEMDAAAAzA6PRPz/VEMAwI5EfHZXQwDAjkT8f1pDAwAAAADAjkT8zFxDAPCORPyMXkMAII9E/P9fQwIAAAAAAAAAAAAAAAAAAAAAAAAAAACQRPz/ZkMCAAAAAAAAAAAAAAAAAAAAAAAAAADgkET8/19D\"],\"~:name\",\"svg-path\",\"~:width\",null,\"~:type\",\"~:path\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linecap\",\"round\",\"~:stroke-linejoin\",\"round\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1142,\"~:y\",212.99997181105346]],[\"^A\",[\"^ \",\"~:x\",1162,\"~:y\",212.99997181105346]],[\"^A\",[\"^ \",\"~:x\",1162,\"~:y\",230.99997181105346]],[\"^A\",[\"^ \",\"~:x\",1142,\"~:y\",230.99997181105346]]],\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e705944588\",\"~:proportion-lock\",false,\"~:stroke-cap-end\",\"round\",\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:constraints-v\",\"~:scale\",\"~:svg-transform\",[\"^ \",\"~:a\",1,\"~:b\",0,\"~:c\",0,\"~:d\",1,\"~:e\",0,\"~:f\",0],\"~:constraints-h\",\"^H\",\"~:id\",\"~u9299427e-8172-80bb-8007-90e71fba0f84\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f83\",\"~:svg-viewbox\",[\"^ \",\"~:y\",3,\"~:y1\",3,\"^9\",20,\"~:x\",2,\"~:x1\",2,\"~:y2\",21,\"~:x2\",22,\"~:height\",18],\"~:applied-tokens\",[\"^ \",\"~:stroke-color\",\"color.icon.default\"],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f83\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2,\"^T\",\"#ffffff\",\"~:stroke-opacity\",1]],\"~:x\",null,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1142,\"~:y\",212.99997181105346,\"^9\",20,\"^R\",18,\"^O\",1142,\"^N\",212.99997181105346,\"^Q\",1162,\"^P\",230.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^R\",null,\"~:flip-y\",null]]",
"~u94eaebe4-addd-80d1-8007-79d508aa2886": "[\"~#shape\",[\"^ \",\"~:y\",461.999988316858,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",302.0000081062317,\"~:y\",461.999988316858]],[\"^K\",[\"^ \",\"~:x\",368.0000081062317,\"~:y\",461.999988316858]],[\"^K\",[\"^ \",\"~:x\",368.0000081062317,\"~:y\",493.999988316858]],[\"^K\",[\"^ \",\"~:x\",302.0000081062317,\"~:y\",493.999988316858]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:strokes\",[],\"~:x\",302.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",302.0000081062317,\"~:y\",461.999988316858,\"^E\",66,\"~:height\",32,\"~:x1\",302.0000081062317,\"~:y1\",461.999988316858,\"~:x2\",368.0000081062317,\"~:y2\",493.999988316858]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508aa2887\"]]]",
"~u9299427e-8172-80bb-8007-90e7059421c4": "[\"~#shape\",[\"^ \",\"~:y\",209.99999660658568,\"~:rx\",0,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:hide-in-viewer\",true,\"~:name\",\"heart\",\"~:width\",24,\"~:type\",\"~:frame\",\"~:svg-attrs\",[\"^ \",\"^8\",\"24\",\"~:height\",\"24\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",804,\"~:y\",209.99999660658568]],[\"^>\",[\"^ \",\"~:x\",828,\"~:y\",209.99999660658568]],[\"^>\",[\"^ \",\"~:x\",828,\"~:y\",233.99999660658568]],[\"^>\",[\"^ \",\"~:x\",804,\"~:y\",233.99999660658568]]],\"~:r2\",0,\"~:shape-ref\",\"~uc8b014fe-f285-8021-8007-8ea400bd9407\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e7059421c2\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e7059421c2\",\"~:strokes\",[],\"~:x\",804,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",804,\"~:y\",209.99999660658568,\"^8\",24,\"^<\",24,\"~:x1\",804,\"~:y1\",209.99999660658568,\"~:x2\",828,\"~:y2\",233.99999660658568]],\"~:fills\",[],\"~:flip-x\",null,\"~:ry\",0,\"^<\",24,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e7059421c5\",\"~u9299427e-8172-80bb-8007-90e7059421c6\"]]]",
"~u94eaebe4-addd-80d1-8007-79d508aa2887": "[\"~#shape\",[\"^ \",\"~:y\",469.999988316858,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",314.0000081062317,\"~:y\",469.999988316858]],[\"^K\",[\"^ \",\"~:x\",356.0000081062317,\"~:y\",469.999988316858]],[\"^K\",[\"^ \",\"~:x\",356.0000081062317,\"~:y\",485.999988316858]],[\"^K\",[\"^ \",\"~:x\",314.0000081062317,\"~:y\",485.999988316858]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2887\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\",\"~:strokes\",[],\"~:x\",314.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",314.0000081062317,\"~:y\",469.999988316858,\"^D\",42,\"~:height\",16,\"~:x1\",314.0000081062317,\"~:y1\",469.999988316858,\"~:x2\",356.0000081062317,\"~:y2\",485.999988316858]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508aa2888\"]]]",
"~u9299427e-8172-80bb-8007-90e7059421c5": "[\"~#shape\",[\"^ \",\"~:y\",210.0000271241638,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:name\",\"base-background\",\"~:width\",24,\"~:type\",\"~:rect\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linejoin\",\"round\",\"~:stroke-linecap\",\"round\",\"~:id\",\"base-background\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",804,\"~:y\",210.0000271241638]],[\"^?\",[\"^ \",\"~:x\",828,\"~:y\",210.0000271241638]],[\"^?\",[\"^ \",\"~:x\",828,\"~:y\",234.0000271241638]],[\"^?\",[\"^ \",\"~:x\",804,\"~:y\",234.0000271241638]]],\"~:shape-ref\",\"~uc8b014fe-f285-8021-8007-8ea400bd9408\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:hidden\",true,\"^=\",\"~u9299427e-8172-80bb-8007-90e7059421c5\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:svg-viewbox\",[\"^ \",\"~:y\",0,\"~:y1\",0,\"^6\",24,\"~:x\",0,\"~:x1\",0,\"~:y2\",24,\"~:x2\",24,\"~:height\",24],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-color\",\"#ffffff\",\"~:stroke-opacity\",1,\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2]],\"~:x\",804,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",804,\"~:y\",210.0000271241638,\"^6\",24,\"^K\",24,\"^H\",804,\"^G\",210.0000271241638,\"^J\",828,\"^I\",234.0000271241638]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",24,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71cbb9fea": "[\"~#shape\",[\"^ \",\"~:y\",428.99998474121094,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"card-img / patinegro\",\"~:layout-align-items\",\"~:start\",\"~:width\",265,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",580,\"~:y\",428.99998474121094]],[\"^L\",[\"^ \",\"~:x\",845,\"~:y\",428.99998474121094]],[\"^L\",[\"^ \",\"~:x\",845,\"~:y\",606.99997875689]],[\"^L\",[\"^ \",\"~:x\",580,\"~:y\",606.99997875689]]],\"~:r2\",20,\"~:component-root\",true,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",20,\"~:layout-justify-content\",\"^E\",\"~:r1\",20,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71cbb9fea\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~u9299427e-8172-80bb-8007-90e7059a83e2\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",580,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",580,\"~:y\",428.99998474121094,\"^F\",265,\"~:height\",177.99999401567902,\"~:x1\",580,\"~:y1\",428.99998474121094,\"~:x2\",845,\"~:y2\",606.99997875689]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^1:\",177.99999401567902,\"~:component-file\",\"~u31fe2e21-73e7-80f3-8007-73894fb58240\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71cbc342d\",\"~u9299427e-8172-80bb-8007-90e71cbc342f\"]]]",
"~u94eaebe4-addd-80d1-8007-79d508aa2888": "[\"~#shape\",[\"^ \",\"~:y\",470.9999883168582,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",316.0000081062317,\"~:y\",470.9999883168582]],[\"^S\",[\"^ \",\"~:x\",354.0000081062317,\"~:y\",470.9999883168582]],[\"^S\",[\"^ \",\"~:x\",354.0000081062317,\"~:y\",485.99998831685775]],[\"^S\",[\"^ \",\"~:x\",316.0000081062317,\"~:y\",485.9999883168582]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2888\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2887\",\"~:position-data\",[[\"^ \",\"~:y\",485.3399963378906,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.94000244140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",316.0299987792969,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.079986572265625,\"^L\",\"Label\"]],\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2887\",\"~:strokes\",[],\"~:x\",316.0000081062317,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",316.0000081062317,\"~:y\",470.9999883168582,\"^Q\",38,\"^11\",15,\"~:x1\",316.0000081062317,\"~:y1\",470.9999883168582,\"~:x2\",354.0000081062317,\"~:y2\",485.9999883168582]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]",
"~u77c71dba-32ee-804c-8007-736561cff45a": "[\"~#shape\",[\"^ \",\"~:y\",255.00000357564727,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",400.0000081062317,\"~:y\",255.00000357564727]],[\"^S\",[\"^ \",\"~:x\",438.0000081062317,\"~:y\",255.00000357564727]],[\"^S\",[\"^ \",\"~:x\",438.0000081062317,\"~:y\",270.0000035756468]],[\"^S\",[\"^ \",\"~:x\",400.0000081062317,\"~:y\",270.00000357564727]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff45a\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cff459\",\"~:position-data\",[[\"^ \",\"~:y\",269.3399963378906,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.94000244140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",400.0299987792969,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.080001831054688,\"^L\",\"Label\"]],\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cff459\",\"~:strokes\",[],\"~:x\",400.0000081062317,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",400.0000081062317,\"~:y\",255.00000357564727,\"^Q\",38,\"^11\",15,\"~:x1\",400.0000081062317,\"~:y1\",255.00000357564727,\"~:x2\",438.0000081062317,\"~:y2\",270.00000357564727]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]",
"~u77c71dba-32ee-804c-8007-736561cff459": "[\"~#shape\",[\"^ \",\"~:y\",254.00000357564704,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",398.0000081062317,\"~:y\",254.00000357564704]],[\"^K\",[\"^ \",\"~:x\",440.0000081062317,\"~:y\",254.00000357564704]],[\"^K\",[\"^ \",\"~:x\",440.0000081062317,\"~:y\",270.00000357564704]],[\"^K\",[\"^ \",\"~:x\",398.0000081062317,\"~:y\",270.00000357564704]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff459\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cff458\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cff458\",\"~:strokes\",[],\"~:x\",398.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",398.0000081062317,\"~:y\",254.00000357564704,\"^D\",42,\"~:height\",16,\"~:x1\",398.0000081062317,\"~:y1\",254.00000357564704,\"~:x2\",440.0000081062317,\"~:y2\",270.00000357564704]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cff45a\"]]]",
"~u9299427e-8172-80bb-8007-90e705944588": "[\"~#shape\",[\"^ \",\"~:y\",null,\"~:stroke-cap-start\",\"round\",\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:content\",[\"~#penpot/path-data\",\"~bAQAAAAAAAAAAAAAAAAAAAAAAAAAAwE1E/P9fQwMAAABcH05E/IleQwCATkT8yVxDAIBORPx/WkMDAAAAAIBORHx2V0No4k1E/P9UQwAgTUT8/1RDAwAAAFyvTET8/1RDAGBMRPx/VUMAAExE/P9WQwMAAAAAoEtE/H9VQ6RQS0T8/1RDAOBKRPz/VEMDAAAAmB1KRPz/VEMAgElEfHZXQwCASUT8f1pDAwAAAACASUT8zFxDAOBJRPyMXkMAQEpE/P9fQwIAAAAAAAAAAAAAAAAAAAAAAAAAAABMRPz/ZkMCAAAAAAAAAAAAAAAAAAAAAAAAAADATUT8/19D\"],\"~:name\",\"svg-path\",\"~:width\",null,\"~:type\",\"~:path\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linecap\",\"round\",\"~:stroke-linejoin\",\"round\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",806,\"~:y\",212.99997181105346]],[\"^A\",[\"^ \",\"~:x\",826,\"~:y\",212.99997181105346]],[\"^A\",[\"^ \",\"~:x\",826,\"~:y\",230.99997181105346]],[\"^A\",[\"^ \",\"~:x\",806,\"~:y\",230.99997181105346]]],\"~:shape-ref\",\"~uc8b014fe-f285-8021-8007-8ea518570b0f\",\"~:proportion-lock\",false,\"~:stroke-cap-end\",\"round\",\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:constraints-v\",\"~:scale\",\"~:svg-transform\",[\"^ \",\"~:a\",1,\"~:b\",0,\"~:c\",0,\"~:d\",1,\"~:e\",0,\"~:f\",0],\"~:constraints-h\",\"^H\",\"~:id\",\"~u9299427e-8172-80bb-8007-90e705944588\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e7059421c6\",\"~:svg-viewbox\",[\"^ \",\"~:y\",3,\"~:y1\",3,\"^9\",20,\"~:x\",2,\"~:x1\",2,\"~:y2\",21,\"~:x2\",22,\"~:height\",18],\"~:applied-tokens\",[\"^ \",\"~:stroke-color\",\"color.icon.default\"],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e7059421c6\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2,\"^T\",\"#ffffff\",\"~:stroke-opacity\",1]],\"~:x\",null,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",806,\"~:y\",212.99997181105346,\"^9\",20,\"^R\",18,\"^O\",806,\"^N\",212.99997181105346,\"^Q\",826,\"^P\",230.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^R\",null,\"~:flip-y\",null]]",
"~u77c71dba-32ee-804c-8007-736561cff458": "[\"~#shape\",[\"^ \",\"~:y\",246.00000357564704,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",386.0000081062317,\"~:y\",246.00000357564704]],[\"^K\",[\"^ \",\"~:x\",452.0000081062317,\"~:y\",246.00000357564704]],[\"^K\",[\"^ \",\"~:x\",452.0000081062317,\"~:y\",278.00000357564704]],[\"^K\",[\"^ \",\"~:x\",386.0000081062317,\"~:y\",278.00000357564704]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff458\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:strokes\",[],\"~:x\",386.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",386.0000081062317,\"~:y\",246.00000357564704,\"^E\",66,\"~:height\",32,\"~:x1\",386.0000081062317,\"~:y1\",246.00000357564704,\"~:x2\",452.0000081062317,\"~:y2\",278.00000357564704]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cff459\"]]]",
"~u9299427e-8172-80bb-8007-90e72469bf8e": "[\"~#shape\",[\"^ \",\"~:y\",444.00002998518676,\"~:hide-fill-on-export\",false,\"~:layout-item-absolute\",true,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"add-favorites\",\"~:layout-align-items\",\"~:center\",\"~:width\",48,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1128,\"~:y\",444.00002998518676]],[\"^M\",[\"^ \",\"~:x\",1176,\"~:y\",444.00002998518676]],[\"^M\",[\"^ \",\"~:x\",1176,\"~:y\",492.00002426314086]],[\"^M\",[\"^ \",\"~:x\",1128,\"~:y\",492.00002426314086]]],\"~:r2\",50,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c2\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",50,\"~:layout-justify-content\",\"^F\",\"~:r1\",50,\"~:id\",\"~u9299427e-8172-80bb-8007-90e72469bf8e\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8c\",\"~:layout-flex-dir\",\"~:row\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"color.bg.default\"],\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea447a0bc30\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8c\",\"~:strokes\",[],\"~:x\",1128,\"~:proportion\",1,\"~:r4\",50,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1128,\"~:y\",444.00002998518676,\"^G\",48,\"~:height\",47.9999942779541,\"~:x1\",1128,\"~:y1\",444.00002998518676,\"~:x2\",1176,\"~:y2\",492.00002426314086]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.3]],\"~:flip-x\",null,\"^1<\",47.9999942779541,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e72469bf90\"]]]",
"~u9299427e-8172-80bb-8007-90e71cbc342e": "[\"~#shape\",[\"^ \",\"~:y\",429.000012591785,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"patinegro\",\"~:width\",264.80230943863717,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",579.9999793759137,\"~:y\",429.000012591785]],[\"^9\",[\"^ \",\"~:x\",844.8022888145506,\"~:y\",429.000012591785]],[\"^9\",[\"^ \",\"~:x\",844.8022888145506,\"~:y\",625.1131514739925]],[\"^9\",[\"^ \",\"~:x\",579.9999793759137,\"~:y\",625.1131514739925]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c3\",\"~:proportion-lock\",true,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71cbc342e\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71cbc342d\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71cbc342d\",\"~:strokes\",[],\"~:x\",579.9999793759134,\"~:proportion\",1.3487940630797774,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",579.9999793759134,\"~:y\",429.000012591785,\"^5\",264.80230943863717,\"~:height\",196.11313888220752,\"~:x1\",579.9999793759134,\"~:y1\",429.000012591785,\"~:x2\",844.8022888145506,\"~:y2\",625.1131514739925]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#b73d3d\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^I\",196.11313888220752,\"~:flip-y\",null]]",
"~u77c71dba-32ee-804c-8007-736561cf857f": "[\"~#shape\",[\"^ \",\"~:y\",221.99999439878093,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 1\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",221.99999439878093]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",221.99999439878093]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",301.999982234935]],[\"^J\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",301.999982234935]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cf857f\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",283.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",221.99999439878093,\"^D\",272,\"~:height\",79.99998783615405,\"~:x1\",283.0000081062317,\"~:y1\",221.99999439878093,\"~:x2\",555.0000081062317,\"~:y2\",301.999982234935]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.99998783615405,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cf8584\"]]]",
"~u9299427e-8172-80bb-8007-90e72469bf8f": "[\"~#shape\",[\"^ \",\"~:y\",438.000012591785,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"patinegro\",\"~:width\",264.80230943863717,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",915.9999793759137,\"~:y\",438.000012591785]],[\"^9\",[\"^ \",\"~:x\",1180.8022888145506,\"~:y\",438.000012591785]],[\"^9\",[\"^ \",\"~:x\",1180.8022888145506,\"~:y\",634.1131514739925]],[\"^9\",[\"^ \",\"~:x\",915.9999793759137,\"~:y\",634.1131514739925]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c3\",\"~:proportion-lock\",true,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e72469bf8f\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8d\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8d\",\"~:strokes\",[],\"~:x\",915.9999793759134,\"~:proportion\",1.3487940630797774,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",915.9999793759134,\"~:y\",438.000012591785,\"^5\",264.80230943863717,\"~:height\",196.11313888220752,\"~:x1\",915.9999793759134,\"~:y1\",438.000012591785,\"~:x2\",1180.8022888145506,\"~:y2\",634.1131514739925]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#b73d3d\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^I\",196.11313888220752,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71cbc342f": "[\"~#shape\",[\"^ \",\"~:y\",435.00002998518676,\"~:hide-fill-on-export\",false,\"~:layout-item-absolute\",true,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"add-favorites\",\"~:layout-align-items\",\"~:center\",\"~:width\",48,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:touched\",[\"~#set\",[\"~:layout-item-z-index\"]],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",792,\"~:y\",435.00002998518676]],[\"^P\",[\"^ \",\"~:x\",840,\"~:y\",435.00002998518676]],[\"^P\",[\"^ \",\"~:x\",840,\"~:y\",483.00002426314086]],[\"^P\",[\"^ \",\"~:x\",792,\"~:y\",483.00002426314086]]],\"~:r2\",50,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c2\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",50,\"~:layout-justify-content\",\"^F\",\"~:r1\",50,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71cbc342f\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71cbb9fea\",\"~:layout-flex-dir\",\"~:row\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"color.bg.default\"],\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea447a0bc30\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71cbb9fea\",\"~:strokes\",[],\"~:x\",792,\"~:proportion\",1,\"~:r4\",50,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",792,\"~:y\",435.00002998518676,\"^G\",48,\"~:height\",47.9999942779541,\"~:x1\",792,\"~:y1\",435.00002998518676,\"~:x2\",840,\"~:y2\",483.00002426314086]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.3]],\"~:flip-x\",null,\"^1?\",47.9999942779541,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"^N\",1,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71cbc3430\"]]]",
"~u94eaebe4-addd-80d1-8007-79d50980078e": "[\"~#shape\",[\"^ \",\"~:y\",546.0000478045426,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 4\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",546.0000478045426]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",546.0000478045426]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",626.0000356406968]],[\"^J\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",626.0000356406968]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column-reverse\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",283.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",546.0000478045426,\"^D\",272,\"~:height\",79.9999878361541,\"~:x1\",283.0000081062317,\"~:y1\",546.0000478045426,\"~:x2\",555.0000081062317,\"~:y2\",626.0000356406968]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.9999878361541,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d50980078f\"]]]",
"~u9299427e-8172-80bb-8007-90e72469bf8c": "[\"~#shape\",[\"^ \",\"~:y\",437.99998474121094,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"card-img / patinegro\",\"~:layout-align-items\",\"~:start\",\"~:width\",265,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",916,\"~:y\",437.99998474121094]],[\"^L\",[\"^ \",\"~:x\",1181,\"~:y\",437.99998474121094]],[\"^L\",[\"^ \",\"~:x\",1181,\"~:y\",615.99997875689]],[\"^L\",[\"^ \",\"~:x\",916,\"~:y\",615.99997875689]]],\"~:r2\",20,\"~:component-root\",true,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",20,\"~:layout-justify-content\",\"^E\",\"~:r1\",20,\"~:id\",\"~u9299427e-8172-80bb-8007-90e72469bf8c\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~u9299427e-8172-80bb-8007-90e7059a83e2\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",916,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",916,\"~:y\",437.99998474121094,\"^F\",265,\"~:height\",177.99999401567902,\"~:x1\",916,\"~:y1\",437.99998474121094,\"~:x2\",1181,\"~:y2\",615.99997875689]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^1:\",177.99999401567902,\"~:component-file\",\"~u31fe2e21-73e7-80f3-8007-73894fb58240\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e72469bf8d\",\"~u9299427e-8172-80bb-8007-90e72469bf8e\"]]]",
"~u94eaebe4-addd-80d1-8007-79d50980078f": "[\"~#shape\",[\"^ \",\"~:y\",545.9999806874634,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",545.9999806874634]],[\"^;\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",545.9999806874634]],[\"^;\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",625.9999806874634]],[\"^;\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",625.9999806874634]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~:strokes\",[],\"~:x\",295.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",545.9999806874634,\"^7\",80,\"~:height\",80,\"~:x1\",295.0000081062317,\"~:y1\",545.9999806874634,\"~:x2\",375.0000081062317,\"~:y2\",625.9999806874634]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d509800790\",\"~u94eaebe4-addd-80d1-8007-79d509800791\"]]]",
"~u9299427e-8172-80bb-8007-90e72469bf8d": "[\"~#shape\",[\"^ \",\"~:y\",437.99999475401955,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"img-city\",\"~:width\",265,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",916,\"~:y\",437.9999947540198]],[\"^;\",[\"^ \",\"~:x\",1181,\"~:y\",437.9999947540198]],[\"^;\",[\"^ \",\"~:x\",1181,\"~:y\",615.9899634401968]],[\"^;\",[\"^ \",\"~:x\",916,\"~:y\",615.9899634401968]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c1\",\"~:layout-item-h-sizing\",\"~:fill\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:layout-item-v-sizing\",\"^?\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e72469bf8d\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8c\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8c\",\"~:strokes\",[],\"~:x\",916,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",916,\"~:y\",437.99999475401955,\"^7\",265,\"~:height\",177.989968686177,\"~:x1\",916,\"~:y1\",437.99999475401955,\"~:x2\",1181,\"~:y2\",615.9899634401966]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^N\",177.989968686177,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e72469bf8f\"]]]",
"~u9299427e-8172-80bb-8007-90e71cbc342d": "[\"~#shape\",[\"^ \",\"~:y\",428.99999475401955,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"img-city\",\"~:width\",265,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",580,\"~:y\",428.9999947540198]],[\"^;\",[\"^ \",\"~:x\",845,\"~:y\",428.9999947540198]],[\"^;\",[\"^ \",\"~:x\",845,\"~:y\",606.9899634401968]],[\"^;\",[\"^ \",\"~:x\",580,\"~:y\",606.9899634401968]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c1\",\"~:layout-item-h-sizing\",\"~:fill\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:layout-item-v-sizing\",\"^?\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71cbc342d\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71cbb9fea\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71cbb9fea\",\"~:strokes\",[],\"~:x\",580,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",580,\"~:y\",428.99999475401955,\"^7\",265,\"~:height\",177.989968686177,\"~:x1\",580,\"~:y1\",428.99999475401955,\"~:x2\",845,\"~:y2\",606.9899634401966]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^N\",177.989968686177,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71cbc342e\"]]]",
"~u94eaebe4-addd-80d1-8007-79d508a9dc2f": "[\"~#shape\",[\"^ \",\"~:y\",437.9999943987809,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 3\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",437.9999943987809]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",437.9999943987809]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",517.999982234935]],[\"^J\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",517.999982234935]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",283.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",437.9999943987809,\"^D\",272,\"~:height\",79.9999878361541,\"~:x1\",283.0000081062317,\"~:y1\",437.9999943987809,\"~:x2\",555.0000081062317,\"~:y2\",517.999982234935]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.9999878361541,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\"]]]",
"~u94eaebe4-addd-80d1-8007-79d509800790": "[\"~#shape\",[\"^ \",\"~:y\",546.0000417226197,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",546.0000417226197]],[\"^>\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",546.0000417226197]],[\"^>\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",626.0000417226197]],[\"^>\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",626.0000417226197]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800790\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:strokes\",[],\"~:x\",295.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",546.0000417226197,\"^9\",80,\"~:height\",80,\"~:x1\",295.0000081062317,\"~:y1\",546.0000417226197,\"~:x2\",375.0000081062317,\"~:y2\",626.0000417226197]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e72469bf92": "[\"~#shape\",[\"^ \",\"~:y\",458.99997181105346,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"svg-path\",\"~:width\",20,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1142,\"~:y\",458.99997181105346]],[\"^;\",[\"^ \",\"~:x\",1162,\"~:y\",458.99997181105346]],[\"^;\",[\"^ \",\"~:x\",1162,\"~:y\",476.99997181105346]],[\"^;\",[\"^ \",\"~:x\",1142,\"~:y\",476.99997181105346]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c6\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e72469bf92\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e72469bf90\",\"~:applied-tokens\",[\"^ \"],\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea4f64a1c9b\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e72469bf90\",\"~:strokes\",[],\"~:x\",1142,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1142,\"~:y\",458.99997181105346,\"^7\",20,\"~:height\",18,\"~:x1\",1142,\"~:y1\",458.99997181105346,\"~:x2\",1162,\"~:y2\",476.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^N\",18,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e72469bf93\"]]]",
"~u9299427e-8172-80bb-8007-90e71cbc3432": "[\"~#shape\",[\"^ \",\"~:y\",449.99997181105346,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"svg-path\",\"~:width\",20,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",806,\"~:y\",449.99997181105346]],[\"^;\",[\"^ \",\"~:x\",826,\"~:y\",449.99997181105346]],[\"^;\",[\"^ \",\"~:x\",826,\"~:y\",467.99997181105346]],[\"^;\",[\"^ \",\"~:x\",806,\"~:y\",467.99997181105346]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c6\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71cbc3432\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71cbc3430\",\"~:applied-tokens\",[\"^ \"],\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea4f64a1c9b\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71cbc3430\",\"~:strokes\",[],\"~:x\",806,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",806,\"~:y\",449.99997181105346,\"^7\",20,\"~:height\",18,\"~:x1\",806,\"~:y1\",449.99997181105346,\"~:x2\",826,\"~:y2\",467.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^N\",18,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71cbc3433\"]]]",
"~u94eaebe4-addd-80d1-8007-79d508a9dc30": "[\"~#shape\",[\"^ \",\"~:y\",437.999988316858,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",437.999988316858]],[\"^;\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",437.999988316858]],[\"^;\",[\"^ \",\"~:x\",375.0000081062317,\"~:y\",517.999988316858]],[\"^;\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",517.999988316858]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~:strokes\",[],\"~:x\",295.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",295.0000081062317,\"~:y\",437.999988316858,\"^7\",80,\"~:height\",80,\"~:x1\",295.0000081062317,\"~:y1\",437.999988316858,\"~:x2\",375.0000081062317,\"~:y2\",517.999988316858]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508aa2885\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\"]]]",
"~u94eaebe4-addd-80d1-8007-79d509800791": "[\"~#shape\",[\"^ \",\"~:y\",570.0000417226197,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",302.0000081062317,\"~:y\",570.0000417226197]],[\"^K\",[\"^ \",\"~:x\",368.0000081062317,\"~:y\",570.0000417226197]],[\"^K\",[\"^ \",\"~:x\",368.0000081062317,\"~:y\",602.0000417226197]],[\"^K\",[\"^ \",\"~:x\",302.0000081062317,\"~:y\",602.0000417226197]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800791\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:strokes\",[],\"~:x\",302.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",302.0000081062317,\"~:y\",570.0000417226197,\"^E\",66,\"~:height\",32,\"~:x1\",302.0000081062317,\"~:y1\",570.0000417226197,\"~:x2\",368.0000081062317,\"~:y2\",602.0000417226197]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d509800792\"]]]",
"~u9299427e-8172-80bb-8007-90e72469bf93": "[\"~#shape\",[\"^ \",\"~:y\",null,\"~:stroke-cap-start\",\"round\",\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:content\",[\"~#penpot/path-data\",\"~bAQAAAAAAAAAAAAAAAAAAAAAAAAAA4JBE/v/qQwMAAACuD5FE/kTqQwBAkUT+ZOlDAECRRP4/6EMDAAAAAECRRD675kM08ZBE/n/lQwCQkET+f+VDAwAAAK5XkET+f+VDADCQRP6/5UMAAJBE/n/mQwMAAAAA0I9E/r/lQ1Koj0T+f+VDAHCPRP5/5UMDAAAAzA6PRP5/5UMAwI5EPrvmQwDAjkT+P+hDAwAAAADAjkR+ZulDAPCORH5G6kMAII9E/v/qQwIAAAAAAAAAAAAAAAAAAAAAAAAAAACQRP5/7kMCAAAAAAAAAAAAAAAAAAAAAAAAAADgkET+/+pD\"],\"~:name\",\"svg-path\",\"~:width\",null,\"~:type\",\"~:path\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linecap\",\"round\",\"~:stroke-linejoin\",\"round\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1142,\"~:y\",458.99997181105346]],[\"^A\",[\"^ \",\"~:x\",1162,\"~:y\",458.99997181105346]],[\"^A\",[\"^ \",\"~:x\",1162,\"~:y\",476.99997181105346]],[\"^A\",[\"^ \",\"~:x\",1142,\"~:y\",476.99997181105346]]],\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e705944588\",\"~:proportion-lock\",false,\"~:stroke-cap-end\",\"round\",\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:constraints-v\",\"~:scale\",\"~:svg-transform\",[\"^ \",\"~:a\",1,\"~:b\",0,\"~:c\",0,\"~:d\",1,\"~:e\",0,\"~:f\",0],\"~:constraints-h\",\"^H\",\"~:id\",\"~u9299427e-8172-80bb-8007-90e72469bf93\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e72469bf92\",\"~:svg-viewbox\",[\"^ \",\"~:y\",3,\"~:y1\",3,\"^9\",20,\"~:x\",2,\"~:x1\",2,\"~:y2\",21,\"~:x2\",22,\"~:height\",18],\"~:applied-tokens\",[\"^ \",\"~:stroke-color\",\"color.icon.default\"],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e72469bf92\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2,\"^T\",\"#ffffff\",\"~:stroke-opacity\",1]],\"~:x\",null,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1142,\"~:y\",458.99997181105346,\"^9\",20,\"^R\",18,\"^O\",1142,\"^N\",458.99997181105346,\"^Q\",1162,\"^P\",476.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^R\",null,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71cbc3433": "[\"~#shape\",[\"^ \",\"~:y\",null,\"~:stroke-cap-start\",\"round\",\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:content\",[\"~#penpot/path-data\",\"~bAQAAAAAAAAAAAAAAAAAAAAAAAAAAwE1E/n/mQwMAAABcH05E/sTlQwCATkT+5ORDAIBORP6/40MDAAAAAIBORD474kNo4k1E/v/gQwAgTUT+/+BDAwAAAFyvTET+/+BDAGBMRP4/4UMAAExE/v/hQwMAAAAAoEtE/j/hQ6RQS0T+/+BDAOBKRP7/4EMDAAAAmB1KRP7/4EMAgElEPjviQwCASUT+v+NDAwAAAACASUR+5uRDAOBJRH7G5UMAQEpE/n/mQwIAAAAAAAAAAAAAAAAAAAAAAAAAAABMRP7/6UMCAAAAAAAAAAAAAAAAAAAAAAAAAADATUT+f+ZD\"],\"~:name\",\"svg-path\",\"~:width\",null,\"~:type\",\"~:path\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linecap\",\"round\",\"~:stroke-linejoin\",\"round\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",806,\"~:y\",449.99997181105346]],[\"^A\",[\"^ \",\"~:x\",826,\"~:y\",449.99997181105346]],[\"^A\",[\"^ \",\"~:x\",826,\"~:y\",467.99997181105346]],[\"^A\",[\"^ \",\"~:x\",806,\"~:y\",467.99997181105346]]],\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e705944588\",\"~:proportion-lock\",false,\"~:stroke-cap-end\",\"round\",\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:constraints-v\",\"~:scale\",\"~:svg-transform\",[\"^ \",\"~:a\",1,\"~:b\",0,\"~:c\",0,\"~:d\",1,\"~:e\",0,\"~:f\",0],\"~:constraints-h\",\"^H\",\"~:id\",\"~u9299427e-8172-80bb-8007-90e71cbc3433\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71cbc3432\",\"~:svg-viewbox\",[\"^ \",\"~:y\",3,\"~:y1\",3,\"^9\",20,\"~:x\",2,\"~:x1\",2,\"~:y2\",21,\"~:x2\",22,\"~:height\",18],\"~:applied-tokens\",[\"^ \",\"~:stroke-color\",\"color.icon.default\"],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71cbc3432\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2,\"^T\",\"#ffffff\",\"~:stroke-opacity\",1]],\"~:x\",null,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",806,\"~:y\",449.99997181105346,\"^9\",20,\"^R\",18,\"^O\",806,\"^N\",449.99997181105346,\"^Q\",826,\"^P\",467.99997181105346]],\"~:fills\",[],\"~:flip-x\",null,\"^R\",null,\"~:flip-y\",null]]",
"~u94eaebe4-addd-80d1-8007-79d509800792": "[\"~#shape\",[\"^ \",\"~:y\",578.0000417226197,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",314.0000081062317,\"~:y\",578.0000417226197]],[\"^K\",[\"^ \",\"~:x\",356.0000081062317,\"~:y\",578.0000417226197]],[\"^K\",[\"^ \",\"~:x\",356.0000081062317,\"~:y\",594.0000417226197]],[\"^K\",[\"^ \",\"~:x\",314.0000081062317,\"~:y\",594.0000417226197]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800792\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d509800791\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d509800791\",\"~:strokes\",[],\"~:x\",314.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",314.0000081062317,\"~:y\",578.0000417226197,\"^D\",42,\"~:height\",16,\"~:x1\",314.0000081062317,\"~:y1\",578.0000417226197,\"~:x2\",356.0000081062317,\"~:y2\",594.0000417226197]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d509800793\"]]]",
"~u9299427e-8172-80bb-8007-90e72469bf90": "[\"~#shape\",[\"^ \",\"~:y\",455.9999966065857,\"~:rx\",0,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:hide-in-viewer\",true,\"~:name\",\"heart\",\"~:width\",24,\"~:type\",\"~:frame\",\"~:svg-attrs\",[\"^ \",\"^8\",\"24\",\"~:height\",\"24\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1140,\"~:y\",455.9999966065857]],[\"^>\",[\"^ \",\"~:x\",1164,\"~:y\",455.9999966065857]],[\"^>\",[\"^ \",\"~:x\",1164,\"~:y\",479.9999966065857]],[\"^>\",[\"^ \",\"~:x\",1140,\"~:y\",479.9999966065857]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e72469bf90\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8e\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e72469bf8e\",\"~:strokes\",[],\"~:x\",1140,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1140,\"~:y\",455.9999966065857,\"^8\",24,\"^<\",24,\"~:x1\",1140,\"~:y1\",455.9999966065857,\"~:x2\",1164,\"~:y2\",479.9999966065857]],\"~:fills\",[],\"~:flip-x\",null,\"~:ry\",0,\"^<\",24,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e72469bf91\",\"~u9299427e-8172-80bb-8007-90e72469bf92\"]]]",
"~u9299427e-8172-80bb-8007-90e71cbc3430": "[\"~#shape\",[\"^ \",\"~:y\",446.9999966065857,\"~:rx\",0,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:hide-in-viewer\",true,\"~:name\",\"heart\",\"~:width\",24,\"~:type\",\"~:frame\",\"~:svg-attrs\",[\"^ \",\"^8\",\"24\",\"~:height\",\"24\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",804,\"~:y\",446.9999966065857]],[\"^>\",[\"^ \",\"~:x\",828,\"~:y\",446.9999966065857]],[\"^>\",[\"^ \",\"~:x\",828,\"~:y\",470.9999966065857]],[\"^>\",[\"^ \",\"~:x\",804,\"~:y\",470.9999966065857]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c4\",\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",0,\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71cbc3430\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71cbc342f\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71cbc342f\",\"~:strokes\",[],\"~:x\",804,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",804,\"~:y\",446.9999966065857,\"^8\",24,\"^<\",24,\"~:x1\",804,\"~:y1\",446.9999966065857,\"~:x2\",828,\"~:y2\",470.9999966065857]],\"~:fills\",[],\"~:flip-x\",null,\"~:ry\",0,\"^<\",24,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71cbc3431\",\"~u9299427e-8172-80bb-8007-90e71cbc3432\"]]]",
"~u94eaebe4-addd-80d1-8007-79d509800793": "[\"~#shape\",[\"^ \",\"~:y\",579.0000417226199,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",316.0000081062317,\"~:y\",579.0000417226199]],[\"^S\",[\"^ \",\"~:x\",354.0000081062317,\"~:y\",579.0000417226199]],[\"^S\",[\"^ \",\"~:x\",354.0000081062317,\"~:y\",594.0000417226195]],[\"^S\",[\"^ \",\"~:x\",316.0000081062317,\"~:y\",594.0000417226199]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800793\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d509800792\",\"~:position-data\",[[\"^ \",\"~:y\",593.340087890625,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.94000244140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",316.0299987792969,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.08001708984375,\"^L\",\"Label\"]],\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d509800792\",\"~:strokes\",[],\"~:x\",316.0000081062317,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",316.0000081062317,\"~:y\",579.0000417226199,\"^Q\",38,\"^11\",15,\"~:x1\",316.0000081062317,\"~:y1\",579.0000417226199,\"~:x2\",354.0000081062317,\"~:y2\",594.0000417226199]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e72469bf91": "[\"~#shape\",[\"^ \",\"~:y\",456.0000271241638,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:name\",\"base-background\",\"~:width\",24,\"~:type\",\"~:rect\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linejoin\",\"round\",\"~:stroke-linecap\",\"round\",\"~:id\",\"base-background\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1140,\"~:y\",456.0000271241638]],[\"^?\",[\"^ \",\"~:x\",1164,\"~:y\",456.0000271241638]],[\"^?\",[\"^ \",\"~:x\",1164,\"~:y\",480.0000271241638]],[\"^?\",[\"^ \",\"~:x\",1140,\"~:y\",480.0000271241638]]],\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c5\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:hidden\",true,\"^=\",\"~u9299427e-8172-80bb-8007-90e72469bf91\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e72469bf90\",\"~:svg-viewbox\",[\"^ \",\"~:y\",0,\"~:y1\",0,\"^6\",24,\"~:x\",0,\"~:x1\",0,\"~:y2\",24,\"~:x2\",24,\"~:height\",24],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e72469bf90\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-color\",\"#ffffff\",\"~:stroke-opacity\",1,\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2]],\"~:x\",1140,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1140,\"~:y\",456.0000271241638,\"^6\",24,\"^K\",24,\"^H\",1140,\"^G\",456.0000271241638,\"^J\",1164,\"^I\",480.0000271241638]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",24,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71cbc3431": "[\"~#shape\",[\"^ \",\"~:y\",447.0000271241638,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",null,\"~:index\",null,\"~:name\",\"base-background\",\"~:width\",24,\"~:type\",\"~:rect\",\"~:svg-attrs\",[\"^ \",\"~:fill\",\"none\",\"~:stroke-linejoin\",\"round\",\"~:stroke-linecap\",\"round\",\"~:id\",\"base-background\"],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",804,\"~:y\",447.0000271241638]],[\"^?\",[\"^ \",\"~:x\",828,\"~:y\",447.0000271241638]],[\"^?\",[\"^ \",\"~:x\",828,\"~:y\",471.0000271241638]],[\"^?\",[\"^ \",\"~:x\",804,\"~:y\",471.0000271241638]]],\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c5\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:hidden\",true,\"^=\",\"~u9299427e-8172-80bb-8007-90e71cbc3431\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71cbc3430\",\"~:svg-viewbox\",[\"^ \",\"~:y\",0,\"~:y1\",0,\"^6\",24,\"~:x\",0,\"~:x1\",0,\"~:y2\",24,\"~:x2\",24,\"~:height\",24],\"~:svg-defs\",[\"^ \"],\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71cbc3430\",\"~:strokes\",[[\"^ \",\"~:stroke-style\",\"~:solid\",\"~:stroke-color\",\"#ffffff\",\"~:stroke-opacity\",1,\"~:stroke-alignment\",\"~:inner\",\"~:stroke-width\",2]],\"~:x\",804,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",804,\"~:y\",447.0000271241638,\"^6\",24,\"^K\",24,\"^H\",804,\"^G\",447.0000271241638,\"^J\",828,\"^I\",471.0000271241638]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",24,\"~:flip-y\",null]]",
"~u77c71dba-32ee-804c-8007-736561cf8584": "[\"~#shape\",[\"^ \",\"~:y\",222.00000357564704,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",222.00000357564704]],[\"^;\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",222.00000357564704]],[\"^;\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",302.00000357564704]],[\"^;\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",302.00000357564704]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cf857f\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cf857f\",\"~:strokes\",[],\"~:x\",379.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",222.00000357564704,\"^7\",80,\"~:height\",80,\"~:x1\",379.0000081062317,\"~:y1\",222.00000357564704,\"~:x2\",459.0000081062317,\"~:y2\",302.00000357564704]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cff457\",\"~u77c71dba-32ee-804c-8007-736561cff458\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d6859": "[\"~#shape\",[\"^ \",\"~:y\",330.00000202817546,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 2\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",330.00000202817546]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",330.00000202817546]],[\"^J\",[\"^ \",\"~:x\",555.0000081062317,\"~:y\",409.99998986432956]],[\"^J\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",409.99998986432956]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:row-reverse\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",283.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",283.0000081062317,\"~:y\",330.00000202817546,\"^D\",272,\"~:height\",79.9999878361541,\"~:x1\",283.0000081062317,\"~:y1\",330.00000202817546,\"~:x2\",555.0000081062317,\"~:y2\",409.99998986432956]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.9999878361541,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685a\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685a": "[\"~#shape\",[\"^ \",\"~:y\",329.9999959462525,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",329.9999959462525]],[\"^;\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",329.9999959462525]],[\"^;\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",409.9999959462525]],[\"^;\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",409.9999959462525]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~:strokes\",[],\"~:x\",379.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",329.9999959462525,\"^7\",80,\"~:height\",80,\"~:x1\",379.0000081062317,\"~:y1\",329.9999959462525,\"~:x2\",459.0000081062317,\"~:y2\",409.9999959462525]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685b\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685b": "[\"~#shape\",[\"^ \",\"~:y\",329.9999959462525,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",329.9999959462525]],[\"^>\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",329.9999959462525]],[\"^>\",[\"^ \",\"~:x\",459.0000081062317,\"~:y\",409.9999959462525]],[\"^>\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",409.9999959462525]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685b\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:strokes\",[],\"~:x\",379.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",379.0000081062317,\"~:y\",329.9999959462525,\"^9\",80,\"~:height\",80,\"~:x1\",379.0000081062317,\"~:y1\",329.9999959462525,\"~:x2\",459.0000081062317,\"~:y2\",409.9999959462525]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71fba0f7e": "[\"~#shape\",[\"^ \",\"~:y\",191.99999475401955,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"img-city\",\"~:width\",265,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",916,\"~:y\",191.99999475401978]],[\"^;\",[\"^ \",\"~:x\",1181,\"~:y\",191.99999475401978]],[\"^;\",[\"^ \",\"~:x\",1181,\"~:y\",369.9899634401968]],[\"^;\",[\"^ \",\"~:x\",916,\"~:y\",369.9899634401968]]],\"~:r2\",0,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c1\",\"~:layout-item-h-sizing\",\"~:fill\",\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:layout-item-v-sizing\",\"^?\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7e\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7d\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7d\",\"~:strokes\",[],\"~:x\",916,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",916,\"~:y\",191.99999475401955,\"^7\",265,\"~:height\",177.989968686177,\"~:x1\",916,\"~:y1\",191.99999475401955,\"~:x2\",1181,\"~:y2\",369.98996344019656]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^N\",177.989968686177,\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71fba0f80\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685c": "[\"~#shape\",[\"^ \",\"~:y\",353.9999959462525,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",386.0000081062317,\"~:y\",353.9999959462525]],[\"^K\",[\"^ \",\"~:x\",452.0000081062317,\"~:y\",353.9999959462525]],[\"^K\",[\"^ \",\"~:x\",452.0000081062317,\"~:y\",385.9999959462525]],[\"^K\",[\"^ \",\"~:x\",386.0000081062317,\"~:y\",385.9999959462525]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:strokes\",[],\"~:x\",386.0000081062317,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",386.0000081062317,\"~:y\",353.9999959462525,\"^E\",66,\"~:height\",32,\"~:x1\",386.0000081062317,\"~:y1\",353.9999959462525,\"~:x2\",452.0000081062317,\"~:y2\",385.9999959462525]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685d\"]]]",
"~u9299427e-8172-80bb-8007-90e71fba0f7f": "[\"~#shape\",[\"^ \",\"~:y\",198.00002998518676,\"~:hide-fill-on-export\",false,\"~:layout-item-absolute\",true,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"add-favorites\",\"~:layout-align-items\",\"~:center\",\"~:width\",48,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:touched\",[\"~#set\",[\"~:layout-item-z-index\"]],\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",1128,\"~:y\",198.00002998518676]],[\"^P\",[\"^ \",\"~:x\",1176,\"~:y\",198.00002998518676]],[\"^P\",[\"^ \",\"~:x\",1176,\"~:y\",246.00002426314086]],[\"^P\",[\"^ \",\"~:x\",1128,\"~:y\",246.00002426314086]]],\"~:r2\",50,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c2\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",50,\"~:layout-justify-content\",\"^F\",\"~:r1\",50,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7f\",\"~:parent-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7d\",\"~:layout-flex-dir\",\"~:row\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"color.bg.default\"],\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~uc8b014fe-f285-8021-8007-8ea447a0bc30\",\"~:frame-id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7d\",\"~:strokes\",[],\"~:x\",1128,\"~:proportion\",1,\"~:r4\",50,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",1128,\"~:y\",198.00002998518676,\"^G\",48,\"~:height\",47.9999942779541,\"~:x1\",1128,\"~:y1\",198.00002998518676,\"~:x2\",1176,\"~:y2\",246.00002426314086]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ffffff\",\"~:fill-opacity\",0.3]],\"~:flip-x\",null,\"^1?\",47.9999942779541,\"~:component-file\",\"~ud0eb4518-f33d-81e1-8007-8fe418fea255\",\"~:flip-y\",null,\"^N\",0,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71fba0f81\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685d": "[\"~#shape\",[\"^ \",\"~:y\",361.9999959462525,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",398.0000081062317,\"~:y\",361.9999959462525]],[\"^K\",[\"^ \",\"~:x\",440.0000081062317,\"~:y\",361.9999959462525]],[\"^K\",[\"^ \",\"~:x\",440.0000081062317,\"~:y\",377.9999959462525]],[\"^K\",[\"^ \",\"~:x\",398.0000081062317,\"~:y\",377.9999959462525]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685d\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\",\"~:strokes\",[],\"~:x\",398.0000081062317,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",398.0000081062317,\"~:y\",361.9999959462525,\"^D\",42,\"~:height\",16,\"~:x1\",398.0000081062317,\"~:y1\",361.9999959462525,\"~:x2\",440.0000081062317,\"~:y2\",377.9999959462525]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685e\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685e": "[\"~#shape\",[\"^ \",\"~:y\",362.99999594625274,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",400.0000081062317,\"~:y\",362.99999594625274]],[\"^S\",[\"^ \",\"~:x\",438.0000081062317,\"~:y\",362.99999594625274]],[\"^S\",[\"^ \",\"~:x\",438.0000081062317,\"~:y\",377.9999959462523]],[\"^S\",[\"^ \",\"~:x\",400.0000081062317,\"~:y\",377.99999594625274]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685e\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685d\",\"~:position-data\",[[\"^ \",\"~:y\",377.3399963378906,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.94000244140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",400.0299987792969,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.079986572265625,\"^L\",\"Label\"]],\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685d\",\"~:strokes\",[],\"~:x\",400.0000081062317,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",400.0000081062317,\"~:y\",362.99999594625274,\"^Q\",38,\"^11\",15,\"~:x1\",400.0000081062317,\"~:y1\",362.99999594625274,\"~:x2\",438.0000081062317,\"~:y2\",377.99999594625274]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]",
"~u9299427e-8172-80bb-8007-90e71fba0f7d": "[\"~#shape\",[\"^ \",\"~:y\",191.99998474121094,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",0,\"~:p3\",0,\"~:p4\",0],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:grow-type\",\"~:fixed\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"card-img / patinegro\",\"~:layout-align-items\",\"~:start\",\"~:width\",265,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",916,\"~:y\",191.99998474121094]],[\"^L\",[\"^ \",\"~:x\",1181,\"~:y\",191.99998474121094]],[\"^L\",[\"^ \",\"~:x\",1181,\"~:y\",369.99997875688996]],[\"^L\",[\"^ \",\"~:x\",916,\"~:y\",369.99997875688996]]],\"~:r2\",20,\"~:component-root\",true,\"~:shape-ref\",\"~u9299427e-8172-80bb-8007-90e7059421c0\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",0],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u7c4e00d1-1f97-8161-8007-8f7861f33b60\",\"~:r3\",20,\"~:layout-justify-content\",\"^E\",\"~:r1\",20,\"~:id\",\"~u9299427e-8172-80bb-8007-90e71fba0f7d\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:component-id\",\"~u9299427e-8172-80bb-8007-90e7059a83e2\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",916,\"~:proportion\",1,\"~:r4\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",916,\"~:y\",191.99998474121094,\"^F\",265,\"~:height\",177.99999401567902,\"~:x1\",916,\"~:y1\",191.99998474121094,\"~:x2\",1181,\"~:y2\",369.99997875688996]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^1:\",177.99999401567902,\"~:component-file\",\"~u31fe2e21-73e7-80f3-8007-73894fb58240\",\"~:flip-y\",null,\"~:shapes\",[\"~u9299427e-8172-80bb-8007-90e71fba0f7e\",\"~u9299427e-8172-80bb-8007-90e71fba0f7f\"]]]"
"~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^I\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~u77c71dba-32ee-804c-8007-736561cf857f\"]]]",
"~u77c71dba-32ee-804c-8007-736561cff457": "[\"~#shape\",[\"^ \",\"~:y\",396.00000357564704,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",396.00000357564704]],[\"^>\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",396.00000357564704]],[\"^>\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",476.00000357564704]],[\"^>\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",476.00000357564704]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff457\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:strokes\",[],\"~:x\",688.9999775886536,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",396.00000357564704,\"^9\",80,\"~:height\",80,\"~:x1\",688.9999775886536,\"~:y1\",396.00000357564704,\"~:x2\",768.9999775886536,\"~:y2\",476.00000357564704]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]",
"~u94eaebe4-addd-80d1-8007-79d508aa2885": "[\"~#shape\",[\"^ \",\"~:y\",612.0000188344361,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",604.9999165534973,\"~:y\",612.0000188344361]],[\"^>\",[\"^ \",\"~:x\",684.9999165534973,\"~:y\",612.0000188344361]],[\"^>\",[\"^ \",\"~:x\",684.9999165534973,\"~:y\",692.0000188344361]],[\"^>\",[\"^ \",\"~:x\",604.9999165534973,\"~:y\",692.0000188344361]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2885\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:strokes\",[],\"~:x\",604.9999165534973,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",604.9999165534973,\"~:y\",612.0000188344361,\"^9\",80,\"~:height\",80,\"~:x1\",604.9999165534973,\"~:y1\",612.0000188344361,\"~:x2\",684.9999165534973,\"~:y2\",692.0000188344361]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]",
"~u94eaebe4-addd-80d1-8007-79d508aa2886": "[\"~#shape\",[\"^ \",\"~:y\",636.0000188344361,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",611.9999165534973,\"~:y\",636.0000188344361]],[\"^K\",[\"^ \",\"~:x\",677.9999165534973,\"~:y\",636.0000188344361]],[\"^K\",[\"^ \",\"~:x\",677.9999165534973,\"~:y\",668.0000188344361]],[\"^K\",[\"^ \",\"~:x\",611.9999165534973,\"~:y\",668.0000188344361]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:strokes\",[],\"~:x\",611.9999165534973,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",611.9999165534973,\"~:y\",636.0000188344361,\"^E\",66,\"~:height\",32,\"~:x1\",611.9999165534973,\"~:y1\",636.0000188344361,\"~:x2\",677.9999165534973,\"~:y2\",668.0000188344361]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508aa2887\"]]]",
"~u94eaebe4-addd-80d1-8007-79d508aa2887": "[\"~#shape\",[\"^ \",\"~:y\",644.0000188344361,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",623.9999165534973,\"~:y\",644.0000188344361]],[\"^K\",[\"^ \",\"~:x\",665.9999165534973,\"~:y\",644.0000188344361]],[\"^K\",[\"^ \",\"~:x\",665.9999165534973,\"~:y\",660.0000188344361]],[\"^K\",[\"^ \",\"~:x\",623.9999165534973,\"~:y\",660.0000188344361]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2887\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\",\"~:strokes\",[],\"~:x\",623.9999165534973,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",623.9999165534973,\"~:y\",644.0000188344361,\"^D\",42,\"~:height\",16,\"~:x1\",623.9999165534973,\"~:y1\",644.0000188344361,\"~:x2\",665.9999165534973,\"~:y2\",660.0000188344361]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508aa2888\"]]]",
"~u94eaebe4-addd-80d1-8007-79d508aa2888": "[\"~#shape\",[\"^ \",\"~:y\",645.0000188344363,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",625.9999165534973,\"~:y\",645.0000188344363]],[\"^S\",[\"^ \",\"~:x\",663.9999165534973,\"~:y\",645.0000188344363]],[\"^S\",[\"^ \",\"~:x\",663.9999165534973,\"~:y\",660.0000188344359]],[\"^S\",[\"^ \",\"~:x\",625.9999165534973,\"~:y\",660.0000188344363]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2888\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2887\",\"~:position-data\",[[\"^ \",\"~:y\",659.3400268554688,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.94000244140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",626.0299682617188,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.08001708984375,\"^L\",\"Label\"]],\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508aa2887\",\"~:strokes\",[],\"~:x\",625.9999165534973,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",625.9999165534973,\"~:y\",645.0000188344363,\"^Q\",38,\"^11\",15,\"~:x1\",625.9999165534973,\"~:y1\",645.0000188344363,\"~:x2\",663.9999165534973,\"~:y2\",660.0000188344363]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]",
"~u77c71dba-32ee-804c-8007-736561cff45a": "[\"~#shape\",[\"^ \",\"~:y\",429.00000357564727,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",709.9999775886536,\"~:y\",429.00000357564727]],[\"^S\",[\"^ \",\"~:x\",747.9999775886536,\"~:y\",429.00000357564727]],[\"^S\",[\"^ \",\"~:x\",747.9999775886536,\"~:y\",444.0000035756468]],[\"^S\",[\"^ \",\"~:x\",709.9999775886536,\"~:y\",444.00000357564727]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff45a\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cff459\",\"~:position-data\",[[\"^ \",\"~:y\",443.3399963378906,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.93994140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",710.030029296875,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.079986572265625,\"^L\",\"Label\"]],\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cff459\",\"~:strokes\",[],\"~:x\",709.9999775886536,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",709.9999775886536,\"~:y\",429.00000357564727,\"^Q\",38,\"^11\",15,\"~:x1\",709.9999775886536,\"~:y1\",429.00000357564727,\"~:x2\",747.9999775886536,\"~:y2\",444.00000357564727]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]",
"~u77c71dba-32ee-804c-8007-736561cff459": "[\"~#shape\",[\"^ \",\"~:y\",428.00000357564704,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",707.9999775886536,\"~:y\",428.00000357564704]],[\"^K\",[\"^ \",\"~:x\",749.9999775886536,\"~:y\",428.00000357564704]],[\"^K\",[\"^ \",\"~:x\",749.9999775886536,\"~:y\",444.00000357564704]],[\"^K\",[\"^ \",\"~:x\",707.9999775886536,\"~:y\",444.00000357564704]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff459\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cff458\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cff458\",\"~:strokes\",[],\"~:x\",707.9999775886536,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",707.9999775886536,\"~:y\",428.00000357564704,\"^D\",42,\"~:height\",16,\"~:x1\",707.9999775886536,\"~:y1\",428.00000357564704,\"~:x2\",749.9999775886536,\"~:y2\",444.00000357564704]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cff45a\"]]]",
"~u77c71dba-32ee-804c-8007-736561cff458": "[\"~#shape\",[\"^ \",\"~:y\",420.00000357564704,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",695.9999775886536,\"~:y\",420.00000357564704]],[\"^K\",[\"^ \",\"~:x\",761.9999775886536,\"~:y\",420.00000357564704]],[\"^K\",[\"^ \",\"~:x\",761.9999775886536,\"~:y\",452.00000357564704]],[\"^K\",[\"^ \",\"~:x\",695.9999775886536,\"~:y\",452.00000357564704]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cff458\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:strokes\",[],\"~:x\",695.9999775886536,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",695.9999775886536,\"~:y\",420.00000357564704,\"^E\",66,\"~:height\",32,\"~:x1\",695.9999775886536,\"~:y1\",420.00000357564704,\"~:x2\",761.9999775886536,\"~:y2\",452.00000357564704]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cff459\"]]]",
"~u77c71dba-32ee-804c-8007-736561cf857f": "[\"~#shape\",[\"^ \",\"~:y\",395.99997913999186,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 1\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",593.0000386238098,\"~:y\",395.99997913999186]],[\"^J\",[\"^ \",\"~:x\",865.0000386238098,\"~:y\",395.99997913999186]],[\"^J\",[\"^ \",\"~:x\",865.0000386238098,\"~:y\",475.9999669761459]],[\"^J\",[\"^ \",\"~:x\",593.0000386238098,\"~:y\",475.9999669761459]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cf857f\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",593.0000386238098,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",593.0000386238098,\"~:y\",395.99997913999186,\"^D\",272,\"~:height\",79.99998783615405,\"~:x1\",593.0000386238098,\"~:y1\",395.99997913999186,\"~:x2\",865.0000386238098,\"~:y2\",475.9999669761459]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.99998783615405,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cf8584\"]]]",
"~u94eaebe4-addd-80d1-8007-79d50980078e": "[\"~#shape\",[\"^ \",\"~:y\",720.0000478045426,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 4\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",592.9998555183411,\"~:y\",720.0000478045426]],[\"^J\",[\"^ \",\"~:x\",864.9998555183411,\"~:y\",720.0000478045426]],[\"^J\",[\"^ \",\"~:x\",864.9998555183411,\"~:y\",800.0000356406968]],[\"^J\",[\"^ \",\"~:x\",592.9998555183411,\"~:y\",800.0000356406968]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column-reverse\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",592.9998555183411,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",592.9998555183411,\"~:y\",720.0000478045426,\"^D\",272,\"~:height\",79.9999878361541,\"~:x1\",592.9998555183411,\"~:y1\",720.0000478045426,\"~:x2\",864.9998555183411,\"~:y2\",800.0000356406968]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.9999878361541,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d50980078f\"]]]",
"~u94eaebe4-addd-80d1-8007-79d50980078f": "[\"~#shape\",[\"^ \",\"~:y\",719.9999806874634,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",604.9999775886536,\"~:y\",719.9999806874634]],[\"^;\",[\"^ \",\"~:x\",684.9999775886536,\"~:y\",719.9999806874634]],[\"^;\",[\"^ \",\"~:x\",684.9999775886536,\"~:y\",799.9999806874634]],[\"^;\",[\"^ \",\"~:x\",604.9999775886536,\"~:y\",799.9999806874634]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078e\",\"~:strokes\",[],\"~:x\",604.9999775886536,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",604.9999775886536,\"~:y\",719.9999806874634,\"^7\",80,\"~:height\",80,\"~:x1\",604.9999775886536,\"~:y1\",719.9999806874634,\"~:x2\",684.9999775886536,\"~:y2\",799.9999806874634]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d509800790\",\"~u94eaebe4-addd-80d1-8007-79d509800791\"]]]",
"~u94eaebe4-addd-80d1-8007-79d508a9dc2f": "[\"~#shape\",[\"^ \",\"~:y\",612.000024916359,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 3\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",592.9999165534973,\"~:y\",612.000024916359]],[\"^J\",[\"^ \",\"~:x\",864.9999165534973,\"~:y\",612.000024916359]],[\"^J\",[\"^ \",\"~:x\",864.9999165534973,\"~:y\",692.0000127525132]],[\"^J\",[\"^ \",\"~:x\",592.9999165534973,\"~:y\",692.0000127525132]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",592.9999165534973,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",592.9999165534973,\"~:y\",612.000024916359,\"^D\",272,\"~:height\",79.9999878361541,\"~:x1\",592.9999165534973,\"~:y1\",612.000024916359,\"~:x2\",864.9999165534973,\"~:y2\",692.0000127525132]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.9999878361541,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\"]]]",
"~u94eaebe4-addd-80d1-8007-79d509800790": "[\"~#shape\",[\"^ \",\"~:y\",720.0000417226197,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",604.9998555183411,\"~:y\",720.0000417226197]],[\"^>\",[\"^ \",\"~:x\",684.9998555183411,\"~:y\",720.0000417226197]],[\"^>\",[\"^ \",\"~:x\",684.9998555183411,\"~:y\",800.0000417226197]],[\"^>\",[\"^ \",\"~:x\",604.9998555183411,\"~:y\",800.0000417226197]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800790\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:strokes\",[],\"~:x\",604.9998555183411,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",604.9998555183411,\"~:y\",720.0000417226197,\"^9\",80,\"~:height\",80,\"~:x1\",604.9998555183411,\"~:y1\",720.0000417226197,\"~:x2\",684.9998555183411,\"~:y2\",800.0000417226197]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]",
"~u94eaebe4-addd-80d1-8007-79d508a9dc30": "[\"~#shape\",[\"^ \",\"~:y\",612.0000188344361,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",604.9999775886536,\"~:y\",612.0000188344361]],[\"^;\",[\"^ \",\"~:x\",684.9999775886536,\"~:y\",612.0000188344361]],[\"^;\",[\"^ \",\"~:x\",684.9999775886536,\"~:y\",692.0000188344361]],[\"^;\",[\"^ \",\"~:x\",604.9999775886536,\"~:y\",692.0000188344361]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc30\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d508a9dc2f\",\"~:strokes\",[],\"~:x\",604.9999775886536,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",604.9999775886536,\"~:y\",612.0000188344361,\"^7\",80,\"~:height\",80,\"~:x1\",604.9999775886536,\"~:y1\",612.0000188344361,\"~:x2\",684.9999775886536,\"~:y2\",692.0000188344361]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d508aa2885\",\"~u94eaebe4-addd-80d1-8007-79d508aa2886\"]]]",
"~u94eaebe4-addd-80d1-8007-79d509800791": "[\"~#shape\",[\"^ \",\"~:y\",744.0000417226197,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",611.9998555183411,\"~:y\",744.0000417226197]],[\"^K\",[\"^ \",\"~:x\",677.9998555183411,\"~:y\",744.0000417226197]],[\"^K\",[\"^ \",\"~:x\",677.9998555183411,\"~:y\",776.0000417226197]],[\"^K\",[\"^ \",\"~:x\",611.9998555183411,\"~:y\",776.0000417226197]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800791\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d50980078f\",\"~:strokes\",[],\"~:x\",611.9998555183411,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",611.9998555183411,\"~:y\",744.0000417226197,\"^E\",66,\"~:height\",32,\"~:x1\",611.9998555183411,\"~:y1\",744.0000417226197,\"~:x2\",677.9998555183411,\"~:y2\",776.0000417226197]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d509800792\"]]]",
"~u94eaebe4-addd-80d1-8007-79d509800792": "[\"~#shape\",[\"^ \",\"~:y\",752.0000417226197,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",623.9998555183411,\"~:y\",752.0000417226197]],[\"^K\",[\"^ \",\"~:x\",665.9998555183411,\"~:y\",752.0000417226197]],[\"^K\",[\"^ \",\"~:x\",665.9998555183411,\"~:y\",768.0000417226197]],[\"^K\",[\"^ \",\"~:x\",623.9998555183411,\"~:y\",768.0000417226197]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800792\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d509800791\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d509800791\",\"~:strokes\",[],\"~:x\",623.9998555183411,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",623.9998555183411,\"~:y\",752.0000417226197,\"^D\",42,\"~:height\",16,\"~:x1\",623.9998555183411,\"~:y1\",752.0000417226197,\"~:x2\",665.9998555183411,\"~:y2\",768.0000417226197]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d509800793\"]]]",
"~u94eaebe4-addd-80d1-8007-79d509800793": "[\"~#shape\",[\"^ \",\"~:y\",753.0000417226199,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",625.9998555183411,\"~:y\",753.0000417226199]],[\"^S\",[\"^ \",\"~:x\",663.9998555183411,\"~:y\",753.0000417226199]],[\"^S\",[\"^ \",\"~:x\",663.9998555183411,\"~:y\",768.0000417226195]],[\"^S\",[\"^ \",\"~:x\",625.9998555183411,\"~:y\",768.0000417226199]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d509800793\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d509800792\",\"~:position-data\",[[\"^ \",\"~:y\",767.340087890625,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.93994140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",626.0299072265625,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.08001708984375,\"^L\",\"Label\"]],\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d509800792\",\"~:strokes\",[],\"~:x\",625.9998555183411,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",625.9998555183411,\"~:y\",753.0000417226199,\"^Q\",38,\"^11\",15,\"~:x1\",625.9998555183411,\"~:y1\",753.0000417226199,\"~:x2\",663.9998555183411,\"~:y2\",768.0000417226199]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]",
"~u77c71dba-32ee-804c-8007-736561cf8584": "[\"~#shape\",[\"^ \",\"~:y\",396.00000357564704,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",396.00000357564704]],[\"^;\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",396.00000357564704]],[\"^;\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",476.00000357564704]],[\"^;\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",476.00000357564704]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u77c71dba-32ee-804c-8007-736561cf8584\",\"~:parent-id\",\"~u77c71dba-32ee-804c-8007-736561cf857f\",\"~:frame-id\",\"~u77c71dba-32ee-804c-8007-736561cf857f\",\"~:strokes\",[],\"~:x\",688.9999775886536,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",396.00000357564704,\"^7\",80,\"~:height\",80,\"~:x1\",688.9999775886536,\"~:y1\",396.00000357564704,\"~:x2\",768.9999775886536,\"~:y2\",476.00000357564704]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u77c71dba-32ee-804c-8007-736561cff457\",\"~u77c71dba-32ee-804c-8007-736561cff458\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d6859": "[\"~#shape\",[\"^ \",\"~:y\",504.00000202817546,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",12,\"~:p3\",0,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:wrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Board Parent 2\",\"~:layout-align-items\",\"~:start\",\"~:width\",272,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",592.9999775886536,\"~:y\",504.00000202817546]],[\"^J\",[\"^ \",\"~:x\",864.9999775886536,\"~:y\",504.00000202817546]],[\"^J\",[\"^ \",\"~:x\",864.9999775886536,\"~:y\",583.9999898643296]],[\"^J\",[\"^ \",\"~:x\",592.9999775886536,\"~:y\",583.9999898643296]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-item-v-sizing\",\"~:fix\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:layout-flex-dir\",\"~:row-reverse\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",592.9999775886536,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",592.9999775886536,\"~:y\",504.00000202817546,\"^D\",272,\"~:height\",79.9999878361541,\"~:x1\",592.9999775886536,\"~:y1\",504.00000202817546,\"~:x2\",864.9999775886536,\"~:y2\",583.9999898643296]],\"~:fills\",[],\"~:flip-x\",null,\"^15\",79.9999878361541,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685a\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685a": "[\"~#shape\",[\"^ \",\"~:y\",503.9999959462525,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:hide-in-viewer\",true,\"~:name\",\"Board Child\",\"~:width\",80,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",503.9999959462525]],[\"^;\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",503.9999959462525]],[\"^;\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",583.9999959462525]],[\"^;\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",583.9999959462525]]],\"~:show-content\",true,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d6859\",\"~:strokes\",[],\"~:x\",688.9999775886536,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",503.9999959462525,\"^7\",80,\"~:height\",80,\"~:x1\",688.9999775886536,\"~:y1\",503.9999959462525,\"~:x2\",768.9999775886536,\"~:y2\",583.9999959462525]],\"~:fills\",[],\"~:flip-x\",null,\"^K\",80,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685b\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685b": "[\"~#shape\",[\"^ \",\"~:y\",503.9999959462525,\"~:rx\",8,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",80,\"~:transforming\",false,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",503.9999959462525]],[\"^>\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",503.9999959462525]],[\"^>\",[\"^ \",\"~:x\",768.9999775886536,\"~:y\",583.9999959462525]],[\"^>\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",583.9999959462525]]],\"~:r2\",8,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685b\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:strokes\",[],\"~:x\",688.9999775886536,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",688.9999775886536,\"~:y\",503.9999959462525,\"^9\",80,\"~:height\",80,\"~:x1\",688.9999775886536,\"~:y1\",503.9999959462525,\"~:x2\",768.9999775886536,\"~:y2\",583.9999959462525]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#e8e9ea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^M\",80,\"~:flip-y\",null]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685c": "[\"~#shape\",[\"^ \",\"~:y\",527.9999959462525,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:rx\",8,\"~:layout-padding\",[\"^ \",\"~:p1\",8,\"~:p2\",12,\"~:p3\",8,\"~:p4\",12],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"Dark / Button / Primary / Text / Default\",\"~:layout-align-items\",\"~:center\",\"~:width\",66,\"~:layout-padding-type\",\"~:simple\",\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",695.9999775886536,\"~:y\",527.9999959462525]],[\"^K\",[\"^ \",\"~:x\",761.9999775886536,\"~:y\",527.9999959462525]],[\"^K\",[\"^ \",\"~:x\",761.9999775886536,\"~:y\",559.9999959462525]],[\"^K\",[\"^ \",\"~:x\",695.9999775886536,\"~:y\",559.9999959462525]]],\"~:r2\",8,\"~:show-content\",true,\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",4,\"~:column-gap\",4],\"~:transform-inverse\",[\"^;\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:r3\",8,\"~:layout-justify-content\",\"^D\",\"~:r1\",8,\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:layout-flex-dir\",\"~:row\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685a\",\"~:strokes\",[],\"~:x\",695.9999775886536,\"~:proportion\",1,\"~:r4\",8,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",695.9999775886536,\"~:y\",527.9999959462525,\"^E\",66,\"~:height\",32,\"~:x1\",695.9999775886536,\"~:y1\",527.9999959462525,\"~:x2\",761.9999775886536,\"~:y2\",559.9999959462525]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#7efff5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"~:ry\",8,\"^17\",32,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685d\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685d": "[\"~#shape\",[\"^ \",\"~:y\",535.9999959462525,\"~:hide-fill-on-export\",false,\"~:layout-gap-type\",\"~:multiple\",\"~:layout-padding\",[\"^ \",\"~:p1\",0,\"~:p2\",2,\"~:p3\",0,\"~:p4\",2],\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:layout-wrap-type\",\"~:nowrap\",\"~:layout\",\"~:flex\",\"~:hide-in-viewer\",true,\"~:name\",\"_Utilities / Text / White\",\"~:layout-align-items\",\"~:start\",\"~:width\",42,\"~:layout-padding-type\",\"~:simple\",\"~:transforming\",false,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",707.9999775886536,\"~:y\",535.9999959462525]],[\"^K\",[\"^ \",\"~:x\",749.9999775886536,\"~:y\",535.9999959462525]],[\"^K\",[\"^ \",\"~:x\",749.9999775886536,\"~:y\",551.9999959462525]],[\"^K\",[\"^ \",\"~:x\",707.9999775886536,\"~:y\",551.9999959462525]]],\"~:show-content\",true,\"~:layout-item-h-sizing\",\"~:auto\",\"~:proportion-lock\",false,\"~:layout-gap\",[\"^ \",\"~:row-gap\",0,\"~:column-gap\",6],\"~:transform-inverse\",[\"^:\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:layout-justify-content\",\"~:center\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685d\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\",\"~:layout-flex-dir\",\"~:column\",\"~:layout-align-content\",\"~:stretch\",\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685c\",\"~:strokes\",[],\"~:x\",707.9999775886536,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",707.9999775886536,\"~:y\",535.9999959462525,\"^D\",42,\"~:height\",16,\"~:x1\",707.9999775886536,\"~:y1\",535.9999959462525,\"~:x2\",749.9999775886536,\"~:y2\",551.9999959462525]],\"~:fills\",[],\"~:flip-x\",null,\"^16\",16,\"~:flip-y\",null,\"~:shapes\",[\"~u94eaebe4-addd-80d1-8007-79d5055d685e\"]]]",
"~u94eaebe4-addd-80d1-8007-79d5055d685e": "[\"~#shape\",[\"^ \",\"~:y\",536.9999959462527,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:auto-width\",\"~:index\",null,\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^8\",\"paragraph-set\",\"^9\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:path\",\"\",\"~:font-style\",\"normal\",\"^9\",[[\"^ \",\"^:\",\"1.2\",\"^;\",\"\",\"^<\",\"normal\",\"~:text-transform\",\"uppercase\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-work-sans\",\"~:font-size\",\"12\",\"~:font-weight\",\"500\",\"~:modified-at\",\"2024-06-04T14:15:09.786Z\",\"~:font-variant-id\",\"500\",\"~:text-decoration\",\"underline\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-color-ref-file\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"~:fill-opacity\",1,\"~:fill-color-ref-id\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:font-family\",\"Work Sans\",\"~:text\",\"Label\"]],\"^=\",\"uppercase\",\"^>\",\"center\",\"^?\",\"gfont-work-sans\",\"^@\",\"12\",\"^A\",\"500\",\"^8\",\"paragraph\",\"^B\",\"2024-06-04T14:15:09.786Z\",\"^C\",\"500\",\"^D\",\"underline\",\"^E\",\"0\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"^K\",\"Work Sans\"]]]],\"~:vertical-align\",\"center\",\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^I\",1]]],\"~:hide-in-viewer\",true,\"~:name\",\"Input\",\"~:saved-component-root\",null,\"~:width\",38,\"^8\",\"^L\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",709.9999775886536,\"~:y\",536.9999959462527]],[\"^S\",[\"^ \",\"~:x\",747.9999775886536,\"~:y\",536.9999959462527]],[\"^S\",[\"^ \",\"~:x\",747.9999775886536,\"~:y\",551.9999959462523]],[\"^S\",[\"^ \",\"~:x\",709.9999775886536,\"~:y\",551.9999959462527]]],\"~:layout-item-h-sizing\",\"~:fix\",\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u02e9633d-4ce7-80da-8007-736558496fa8\",\"~:id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685e\",\"~:parent-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685d\",\"~:position-data\",[[\"^ \",\"~:y\",551.3400268554688,\"^:\",\"1.2\",\"^<\",\"normal\",\"^=\",\"uppercase\",\"^>\",\"left\",\"^?\",\"sourcesanspro\",\"^@\",\"12\",\"^A\",\"500\",\"~:text-direction\",\"ltr\",\"^Q\",37.93994140625,\"^C\",\"regular\",\"^D\",\"underline\",\"^E\",\"0\",\"~:x\",710.030029296875,\"^F\",[[\"^ \",\"^G\",\"#000000\",\"^H\",\"~ucaa70d02-51e1-81ae-8007-735e7de3d7bc\",\"^I\",1,\"^J\",\"~udfa92acf-7d18-8079-8003-baba8789d8af\"]],\"~:direction\",\"ltr\",\"^K\",\"Work Sans\",\"~:height\",14.08001708984375,\"^L\",\"Label\"]],\"~:frame-id\",\"~u94eaebe4-addd-80d1-8007-79d5055d685d\",\"~:strokes\",[],\"~:x\",709.9999775886536,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",709.9999775886536,\"~:y\",536.9999959462527,\"^Q\",38,\"^11\",15,\"~:x1\",709.9999775886536,\"~:y1\",536.9999959462527,\"~:x2\",747.9999775886536,\"~:y2\",551.9999959462527]],\"^F\",[],\"~:flip-x\",null,\"^11\",15,\"~:flip-y\",null]]"
}
}
}
@@ -182,16 +150,6 @@
"~:options": {
"~:components-v2": true,
"~:base-font-size": "16px"
},
"~:components": {
"~u9299427e-8172-80bb-8007-90e7059a83e2": {
"~:id": "~u9299427e-8172-80bb-8007-90e7059a83e2",
"~:name": "patinegro",
"~:path": "card-img",
"~:modified-at": "~m1770978606872",
"~:main-instance-id": "~u9299427e-8172-80bb-8007-90e7059421c0",
"~:main-instance-page": "~u02e9633d-4ce7-80da-8007-736558496fa8"
}
}
}
}

View File

@@ -1,137 +0,0 @@
{
"~:features": {
"~#set": [
"fdata/path-data",
"plugins/runtime",
"design-tokens/v1",
"variants/v1",
"layout/grid",
"styles/v2",
"fdata/objects-map",
"render-wasm/v1",
"components/v2",
"fdata/shape-data-type"
]
},
"~:team-id": "~u99e49e93-362f-80ef-8007-3450ea52c9a4",
"~:permissions": {
"~:type": "~:membership",
"~:is-owner": true,
"~:is-admin": true,
"~:can-edit": true,
"~:can-read": true,
"~:is-logged": true
},
"~:has-media-trimmed": false,
"~:comment-thread-seqn": 0,
"~:name": "BUG 13305",
"~:revn": 11,
"~:modified-at": "~m1770911234124",
"~:vern": 0,
"~:id": "~u9666e946-78e8-8111-8007-8fe5f0f454bf",
"~:is-shared": false,
"~:migrations": {
"~#ordered-set": [
"legacy-2",
"legacy-3",
"legacy-5",
"legacy-6",
"legacy-7",
"legacy-8",
"legacy-9",
"legacy-10",
"legacy-11",
"legacy-12",
"legacy-13",
"legacy-14",
"legacy-16",
"legacy-17",
"legacy-18",
"legacy-19",
"legacy-25",
"legacy-26",
"legacy-27",
"legacy-28",
"legacy-29",
"legacy-31",
"legacy-32",
"legacy-33",
"legacy-34",
"legacy-36",
"legacy-37",
"legacy-38",
"legacy-39",
"legacy-40",
"legacy-41",
"legacy-42",
"legacy-43",
"legacy-44",
"legacy-45",
"legacy-46",
"legacy-47",
"legacy-48",
"legacy-49",
"legacy-50",
"legacy-51",
"legacy-52",
"legacy-53",
"legacy-54",
"legacy-55",
"legacy-56",
"legacy-57",
"legacy-59",
"legacy-62",
"legacy-65",
"legacy-66",
"legacy-67",
"0001-remove-tokens-from-groups",
"0002-normalize-bool-content-v2",
"0002-clean-shape-interactions",
"0003-fix-root-shape",
"0003-convert-path-content-v2",
"0005-deprecate-image-type",
"0006-fix-old-texts-fills",
"0008-fix-library-colors-v4",
"0009-clean-library-colors",
"0009-add-partial-text-touched-flags",
"0010-fix-swap-slots-pointing-non-existent-shapes",
"0011-fix-invalid-text-touched-flags",
"0012-fix-position-data",
"0013-fix-component-path",
"0013-clear-invalid-strokes-and-fills",
"0014-fix-tokens-lib-duplicate-ids",
"0014-clear-components-nil-objects",
"0015-fix-text-attrs-blank-strings",
"0015-clean-shadow-color",
"0016-copy-fills-from-position-data-to-text-node"
]
},
"~:version": 67,
"~:project-id": "~ucd8f7672-e5d1-810f-8007-87e124eda82a",
"~:created-at": "~m1770911129553",
"~:backend": "legacy-db",
"~:data": {
"~:pages": [
"~u9666e946-78e8-8111-8007-8fe5f0f49ac6"
],
"~:pages-index": {
"~u9666e946-78e8-8111-8007-8fe5f0f49ac6": {
"~:objects": {
"~#penpot/objects-map/v2": {
"~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",0,\"~:proportion\",1.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",0.01,\"~:height\",0.01,\"~:x1\",0,\"~:y1\",0,\"~:x2\",0.01,\"~:y2\",0.01]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^H\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a\"]]]",
"~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a": "[\"~#shape\",[\"^ \",\"~:y\",99.99999499320984,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Board\",\"~:width\",511.99998180389287,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",99.9999820137034,\"~:y\",99.99999499320984]],[\"^=\",[\"^ \",\"~:x\",611.9999638175963,\"~:y\",99.99999499320984]],[\"^=\",[\"^ \",\"~:x\",611.9999638175963,\"~:y\",611.9999695949548]],[\"^=\",[\"^ \",\"~:x\",99.9999820137034,\"~:y\",611.9999695949548]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:r1\",0,\"~:id\",\"~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",99.9999820137034,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",99.9999820137034,\"~:y\",99.99999499320984,\"^9\",511.99998180389287,\"~:height\",511.99997460174495,\"~:x1\",99.9999820137034,\"~:y1\",99.99999499320984,\"~:x2\",611.9999638175963,\"~:y2\",611.9999695949548]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#FFFFFF\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^K\",511.99997460174495,\"~:flip-y\",null,\"~:shapes\",[\"~u3edd6127-ced7-80c6-8007-8fe60306baa7\",\"~u3edd6127-ced7-80c6-8007-8fe61479065a\"]]]",
"~u3edd6127-ced7-80c6-8007-8fe60306baa7": "[\"~#shape\",[\"^ \",\"~:y\",109.99999433755875,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle\",\"~:width\",100.00000357627869,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",109.99998164176941,\"~:y\",109.99999433755875]],[\"^<\",[\"^ \",\"~:x\",209.9999852180481,\"~:y\",109.99999433755875]],[\"^<\",[\"^ \",\"~:x\",209.9999852180481,\"~:y\",209.9999930858612]],[\"^<\",[\"^ \",\"~:x\",109.99998164176941,\"~:y\",209.9999930858612]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",0,\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:r1\",0,\"~:id\",\"~u3edd6127-ced7-80c6-8007-8fe60306baa7\",\"~:parent-id\",\"~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a\",\"~:frame-id\",\"~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a\",\"~:strokes\",[],\"~:x\",109.99998164176941,\"~:proportion\",1,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",109.99998164176941,\"~:y\",109.99999433755875,\"^8\",100.00000357627869,\"~:height\",99.99999874830246,\"~:x1\",109.99998164176941,\"~:y1\",109.99999433755875,\"~:x2\",209.9999852180481,\"~:y2\",209.9999930858612]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^N\",99.99999874830246,\"~:flip-y\",null]]",
"~u3edd6127-ced7-80c6-8007-8fe61479065a": "[\"~#shape\",[\"^ \",\"~:y\",483.9999952316284,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Ellipse\",\"~:width\",256.000000834465,\"~:type\",\"~:circle\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",483.99998211860657,\"~:y\",483.9999952316284]],[\"^<\",[\"^ \",\"~:x\",739.9999829530716,\"~:y\",483.9999952316284]],[\"^<\",[\"^ \",\"~:x\",739.9999829530716,\"~:y\",739.9999876022339]],[\"^<\",[\"^ \",\"~:x\",483.99998211860657,\"~:y\",739.9999876022339]]],\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:constraints-v\",\"~:top\",\"~:constraints-h\",\"~:left\",\"~:id\",\"~u3edd6127-ced7-80c6-8007-8fe61479065a\",\"~:parent-id\",\"~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a\",\"~:frame-id\",\"~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a\",\"~:strokes\",[],\"~:x\",483.99998211860657,\"~:proportion\",1,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",483.99998211860657,\"~:y\",483.9999952316284,\"^8\",256.000000834465,\"~:height\",255.99999237060547,\"~:x1\",483.99998211860657,\"~:y1\",483.9999952316284,\"~:x2\",739.9999829530716,\"~:y2\",739.9999876022339]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#B1B2B5\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^J\",255.99999237060547,\"~:flip-y\",null]]"
}
},
"~:id": "~u9666e946-78e8-8111-8007-8fe5f0f49ac6",
"~:name": "Page 1"
}
},
"~:id": "~u9666e946-78e8-8111-8007-8fe5f0f454bf",
"~:options": {
"~:components-v2": true,
"~:base-font-size": "16px"
}
}
}

View File

@@ -1,98 +0,0 @@
{
"~:revn": 11,
"~:lagged": [
{
"~:id": "~u9666e946-78e8-8111-8007-8fe7be6223c2",
"~:revn": 12,
"~:file-id": "~u9666e946-78e8-8111-8007-8fe5f0f454bf",
"~:session-id": "~u3966be0d-5f49-807f-8007-8fe68b13fee6",
"~:changes": [
{
"~:type": "~:mod-obj",
"~:id": "~u3edd6127-ced7-80c6-8007-8fe5f6c52e5a",
"~:page-id": "~u9666e946-78e8-8111-8007-8fe5f0f49ac6",
"~:operations": [
{
"~:type": "~:set",
"~:attr": "~:y",
"~:val": 110.00000528339297,
"~:ignore-geometry": false,
"~:ignore-touched": false
},
{
"~:type": "~:set",
"~:attr": "~:width",
"~:val": 629.9999776102587,
"~:ignore-geometry": false,
"~:ignore-touched": false
},
{
"~:type": "~:set",
"~:attr": "~:points",
"~:val": [
{
"~#point": {
"~:x": 109.99999217353886,
"~:y": 110.00000528339297
}
},
{
"~#point": {
"~:x": 739.9999697837976,
"~:y": 110.00000528339297
}
},
{
"~#point": {
"~:x": 739.9999697837976,
"~:y": 739.9999740316338
}
},
{
"~#point": {
"~:x": 109.99999217353886,
"~:y": 739.9999740316338
}
}
],
"~:ignore-geometry": false,
"~:ignore-touched": false
},
{
"~:type": "~:set",
"~:attr": "~:x",
"~:val": 109.99999217353889,
"~:ignore-geometry": false,
"~:ignore-touched": false
},
{
"~:type": "~:set",
"~:attr": "~:selrect",
"~:val": {
"~#rect": {
"~:x": 109.99999217353889,
"~:y": 110.00000528339297,
"~:width": 629.9999776102587,
"~:height": 629.9999687482408,
"~:x1": 109.99999217353889,
"~:y1": 110.00000528339297,
"~:x2": 739.9999697837976,
"~:y2": 739.9999740316338
}
},
"~:ignore-geometry": false,
"~:ignore-touched": false
},
{
"~:type": "~:set",
"~:attr": "~:height",
"~:val": 629.9999687482408,
"~:ignore-geometry": false,
"~:ignore-touched": false
}
]
}
]
}
]
}

View File

@@ -198,10 +198,10 @@ export class WorkspacePage extends BaseWebSocketPage {
`[id="shape-00000000-0000-0000-0000-000000000000"]`,
);
this.toolbarOptions = page.getByTestId("toolbar-options");
this.rectShapeButton = page.getByRole("button", { name: "Rectangle (R)" });
this.ellipseShapeButton = page.getByRole("button", { name: "Ellipse (E)" });
this.moveButton = page.getByRole("button", { name: "Move (V)" });
this.boardButton = page.getByRole("button", { name: "Board (B)" });
this.rectShapeButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Rectangle" });
this.ellipseShapeButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Ellipse" });
this.moveButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Move" });
this.boardButton = page.getByTestId("toolbar-options").getByRole("button", { name: "Board" });
this.toggleToolbarButton = page.getByRole("button", {
name: "Toggle toolbar",
});
@@ -338,18 +338,9 @@ export class WorkspacePage extends BaseWebSocketPage {
async clickWithDragViewportAt(x, y, width, height) {
await this.page.waitForTimeout(100);
const box = await this.viewport.boundingBox();
if (!box) throw new Error('Viewport not visible');
const startX = box.x + x;
const startY = box.y + y;
const endX = startX + width;
const endY = startY + height;
await this.page.mouse.move(startX, startY);
await this.viewport.hover({ position: { x, y } });
await this.page.mouse.down();
// Use steps so mouseup is properly processed (see Playwright issue #20254)
await this.page.mouse.move(endX, endY, { steps: 10 });
await this.viewport.hover({ position: { x: x + width, y: y + height } });
await this.page.mouse.up();
}

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -1,14 +1,14 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
import { WorkspacePage } from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page);
await WorkspacePage.init(page);
});
test("User adds a library and its automatically selected in the color palette", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile();
await workspacePage.mockRPC(
"link-file-to-library",
@@ -53,7 +53,7 @@ test("User adds a library and its automatically selected in the color palette",
test("BUG 10090 - Local library should be expanded by default", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page);
await workspacePage.goToWorkspace();

View File

@@ -1,15 +1,15 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
import { WorkspacePage } from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page);
await WorkspacePage.init(page);
});
// Fix for https://tree.taiga.io/project/penpot/issue/7549
test("Bug 7549 - User clicks on color swatch to display the color picker next to it", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page);
await workspacePage.goToWorkspace();
@@ -25,7 +25,7 @@ test("Bug 7549 - User clicks on color swatch to display the color picker next to
});
test("Create a LINEAR gradient", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile();
await workspacePage.mockRPC(
/get\-file\?/,
@@ -99,7 +99,7 @@ test("Create a LINEAR gradient", async ({ page }) => {
});
test("Create a RADIAL gradient", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile();
await workspacePage.mockRPC(
/get\-file\?/,
@@ -183,7 +183,7 @@ test("Create a RADIAL gradient", async ({ page }) => {
});
test("Gradient stops limit", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.mockConfigFlags(["enable-feature-render-wasm"]);
await workspacePage.setupEmptyFile(page);
@@ -215,7 +215,7 @@ test("Gradient stops limit", async ({ page }) => {
test("Bug 9900 - Color picker has no inputs for HSV values", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page);
await workspacePage.goToWorkspace();
@@ -232,7 +232,7 @@ test("Bug 9900 - Color picker has no inputs for HSV values", async ({
});
test("Bug 10089 - Cannot change alpha", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile();
await workspacePage.mockRPC(
/get\-file\?/,

View File

@@ -1,8 +1,8 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
import { WorkspacePage } from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page);
await WorkspacePage.init(page);
});
const multipleConstraintsFileId = `03bff843-920f-81a1-8004-756365e1eb6a`;
@@ -42,7 +42,7 @@ test.describe("Constraints", () => {
test("Constraint dropdown shows 'Mixed' when multiple layers are selected with different constraints", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
const workspace = new WorkspacePage(page);
await setupFileWithMultipeConstraints(workspace);
await workspace.goToWorkspace({
fileId: multipleConstraintsFileId,
@@ -70,7 +70,7 @@ test.describe("Shape attributes", () => {
test("Cannot add a new fill when the limit has been reached", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
const workspace = new WorkspacePage(page);
await workspace.mockConfigFlags(["enable-feature-render-wasm"]);
await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "design/get-file-fills-limit.json");
@@ -94,7 +94,7 @@ test.describe("Shape attributes", () => {
test.skip("Cannot add a new text fill when the limit has been reached", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
const workspace = new WorkspacePage(page);
await workspace.mockConfigFlags(["enable-feature-render-wasm"]);
await workspace.setupEmptyFile();
await workspace.mockRPC(
@@ -128,7 +128,7 @@ test.describe("Multiple shapes attributes", () => {
test("User selects multiple shapes with sames fills, strokes, shadows and blur", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
const workspace = new WorkspacePage(page);
await setupFileWithMultipeConstraints(workspace);
await workspace.goToWorkspace({
fileId: multipleConstraintsFileId,
@@ -148,7 +148,7 @@ test.describe("Multiple shapes attributes", () => {
test("User selects multiple shapes with different fills, strokes, shadows and blur", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
const workspace = new WorkspacePage(page);
await setupFileWithMultipeAttributes(workspace);
await workspace.goToWorkspace({
fileId: multipleAttributesFileId,
@@ -168,7 +168,7 @@ test.describe("Multiple shapes attributes", () => {
test("BUG 7760 - Layout losing properties when changing parents", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile();
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-7760.json");
await workspacePage.mockRPC(
@@ -189,8 +189,8 @@ test("BUG 7760 - Layout losing properties when changing parents", async ({
await workspacePage.clickLeafLayer("Flex Board");
// Move the first board into the second
const hAuto = await workspacePage.page.getByTitle("Fit content (Horizontal)");
const vAuto = await workspacePage.page.getByTitle("Fit content (Vertical)");
const hAuto = await workspacePage.page.getByTestId("behaviour-h-auto");
const vAuto = await workspacePage.page.getByTestId("behaviour-v-auto");
await expect(vAuto.locator("input")).toBeChecked();
await expect(hAuto.locator("input")).toBeChecked();
@@ -205,7 +205,7 @@ test("BUG 7760 - Layout losing properties when changing parents", async ({
test("BUG 9061 - Group blur visibility toggle icon not updating", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "design/get-file-9061.json");
await workspace.mockRPC(
@@ -234,7 +234,7 @@ test("BUG 9061 - Group blur visibility toggle icon not updating", async ({
test("BUG 9543 - Layout padding inputs not showing 'mixed' when needed", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "design/get-file-9543.json");
await workspace.mockRPC(
@@ -267,7 +267,7 @@ test("BUG 9543 - Layout padding inputs not showing 'mixed' when needed", async (
test("BUG 11177 - Font size input not showing 'mixed' when needed", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "design/get-file-11177.json");
@@ -288,7 +288,7 @@ test("BUG 11177 - Font size input not showing 'mixed' when needed", async ({
test("BUG 12287 Fix identical text fills not being added/removed", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "design/get-file-12287.json");
@@ -323,7 +323,7 @@ test("BUG 12287 Fix identical text fills not being added/removed", async ({
});
test("BUG 12384 - Export crashing when exporting a board", async ({ page }) => {
const workspace = new WasmWorkspacePage(page);
const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile();
await workspace.mockRPC(/get\-file\?/, "design/get-file-12384.json");

View File

@@ -1,8 +1,8 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
import { WorkspacePage } from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page);
await WorkspacePage.init(page);
});
/**
@@ -32,7 +32,7 @@ test.describe("Export frames to PDF", () => {
test("Export frames menu option is NOT visible when page has no frames", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile();
await workspacePage.goToWorkspace();
@@ -48,7 +48,7 @@ test.describe("Export frames to PDF", () => {
test("Export frames menu option is visible when there are frames (even if not selected)", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupWorkspaceWithFrames(workspacePage);
// Open main menu
@@ -62,7 +62,7 @@ test.describe("Export frames to PDF", () => {
test("Export frames modal shows all frames when none are selected", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupWorkspaceWithFrames(workspacePage);
// Don't select any frame
@@ -88,7 +88,7 @@ test.describe("Export frames to PDF", () => {
test("Export frames modal shows only the selected frames", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupWorkspaceWithFrames(workspacePage);
// Select Frame 1
@@ -116,7 +116,7 @@ test.describe("Export frames to PDF", () => {
});
test("User can deselect frames in the export modal", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupWorkspaceWithFrames(workspacePage);
// Select Frame 1
@@ -149,7 +149,7 @@ test.describe("Export frames to PDF", () => {
test("Export button is disabled when all frames are deselected", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupWorkspaceWithFrames(workspacePage);
// Select Frame 1
@@ -173,7 +173,7 @@ test.describe("Export frames to PDF", () => {
});
test("User can cancel the export modal", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupWorkspaceWithFrames(workspacePage);
// Select Frame 1

View File

@@ -1,15 +1,15 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
import { WorkspacePage } from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page);
await WorkspacePage.init(page);
});
// Fix for https://tree.taiga.io/project/penpot/issue/9042
test("Bug 9042 - Measurement unit dropdowns for columns are cut off in grid layout edit mode", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page);
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-9042.json");
await workspacePage.mockRPC(
@@ -37,7 +37,7 @@ test("[Taiga #9116] Copy CSS background color in the selected format in the INSP
page,
context,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page);
await workspacePage.goToWorkspace();
@@ -87,7 +87,7 @@ test("[Taiga #10630] [INSPECT] Style assets not being displayed on info tab", as
page,
context,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page);
await workspacePage.goToWorkspace();
await workspacePage.mockRPC(

View File

@@ -1,10 +1,10 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
import { WorkspacePage } from "../pages/WorkspacePage";
const flags = ["enable-inspect-styles"];
test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page);
await WorkspacePage.init(page);
});
const setupFile = async (workspacePage) => {
@@ -90,7 +90,7 @@ const copyPropertyFromPropertyRow = async (panel, property) => {
/**
* Returns the style panel by its title
* @param {WasmWorkspacePage} workspacePage - The workspace page instance
* @param {WorkspacePage} workspacePage - The workspace page instance
* @param {string} title - The title of the panel to retrieve
*/
const getPanelByTitle = async (workspacePage, title) => {
@@ -103,7 +103,7 @@ const getPanelByTitle = async (workspacePage, title) => {
/**
* Selects a layer in the layers panel
* @param {WasmWorkspacePage} workspacePage - The workspace page instance
* @param {WorkspacePage} workspacePage - The workspace page instance
* @param {string} layerName - The name of the layer to select
* @param {string} parentLayerName - The name of the parent layer to expand (optional)
*/
@@ -118,7 +118,7 @@ const selectLayer = async (workspacePage, layerName, parentLayerName) => {
/**
* Opens the Inspect tab
* @param {WasmWorkspacePage} workspacePage - The workspace page instance
* @param {WorkspacePage} workspacePage - The workspace page instance
*/
const openInspectTab = async (workspacePage) => {
@@ -133,7 +133,7 @@ const openInspectTab = async (workspacePage) => {
/**
* @typedef {'hex' | 'rgba' | 'hsla'} ColorSpace
*
* @param {WasmWorkspacePage} workspacePage - The workspace page instance
* @param {WorkspacePage} workspacePage - The workspace page instance
* @param {ColorSpace} colorSpace - The color space to select
*/
const selectColorSpace = async (workspacePage, colorSpace) => {
@@ -148,7 +148,7 @@ const selectColorSpace = async (workspacePage, colorSpace) => {
test.describe("Inspect tab - Styles", () => {
test.skip("Open Inspect tab", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.flex);
@@ -162,7 +162,7 @@ test.describe("Inspect tab - Styles", () => {
});
test.describe("Inspect tab - Flex", () => {
test("Shape Layout Flex ", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.flex);
@@ -178,7 +178,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Shape Layout Flex Element", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(
@@ -199,7 +199,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Shape Layout Grid", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.grid);
@@ -216,7 +216,7 @@ test.describe("Inspect tab - Styles", () => {
test.describe("Inspect tab - Shadow", () => {
test("Shape Shadow - Single shadow", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.shadow);
@@ -232,7 +232,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Shape Shadow - Multiple shadow", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.shadowMultiple);
@@ -249,7 +249,7 @@ test.describe("Inspect tab - Styles", () => {
// FIXME: flaky/random (depends on trace ?)
test.skip("Shape Shadow - Composite shadow", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.shadowComposite);
@@ -278,7 +278,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Shape - Blur", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.blur);
@@ -295,7 +295,7 @@ test.describe("Inspect tab - Styles", () => {
test.describe("Inspect tab - Border radius", () => {
test("Shape - Border radius - individual", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(
@@ -325,7 +325,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Shape - Border radius - multiple", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(
@@ -365,7 +365,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Shape - Border radius - token", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(
@@ -399,7 +399,7 @@ test.describe("Inspect tab - Styles", () => {
test.describe("Inspect tab - Fill", () => {
test("Shape - Fill - Solid", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.fill.solid);
@@ -416,7 +416,7 @@ test.describe("Inspect tab - Styles", () => {
test("Change color space and ensure fill and shorthand changes", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.fill.solid);
@@ -454,7 +454,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Shape - Fill - Gradient", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.fill.gradient);
@@ -469,7 +469,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Shape - Fill - Image", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.fill.image);
@@ -489,7 +489,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Shape - Fill - Multiple", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.fill.multiple);
@@ -509,7 +509,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Shape - Fill - Token", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.fill.token);
@@ -532,7 +532,7 @@ test.describe("Inspect tab - Styles", () => {
test.describe("Inspect tab - Stroke", () => {
test("Shape - Stroke - Solid", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.stroke.solid);
@@ -547,7 +547,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Shape - Stroke - Gradient", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.stroke.gradient);
@@ -562,7 +562,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Shape - Stroke - Image", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.stroke.image);
@@ -582,7 +582,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Shape - Stroke - Multiple", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.stroke.multiple);
@@ -602,7 +602,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Shape - Stroke - Token", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.stroke.token);
@@ -625,7 +625,7 @@ test.describe("Inspect tab - Styles", () => {
test.describe("Inspect tab - Typography", () => {
test("Text - simple", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.text.simple);
@@ -643,7 +643,7 @@ test.describe("Inspect tab - Styles", () => {
});
test("Text - token", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.text.token);
@@ -679,7 +679,7 @@ test.describe("Inspect tab - Styles", () => {
await expect(textPreview).toBeVisible();
});
test("Text - composite token", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.text.compositeToken);
@@ -705,7 +705,7 @@ test.describe("Inspect tab - Styles", () => {
test.describe("Copy properties", () => {
test("Copy single property", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.flex);
@@ -722,7 +722,7 @@ test.describe("Inspect tab - Styles", () => {
expect(shorthand).toBe("display: flex;");
});
test("Copy shorthand - multiple properties", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupFile(workspacePage);
await selectLayer(workspacePage, shapeToLayerName.shadow);

View File

@@ -1,14 +1,14 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
import { WorkspacePage } from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page);
await WorkspacePage.init(page);
});
test("BUG 7466 - Layers tab height extends to the bottom when 'Pages' is collapsed", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile();
await workspace.goToWorkspace();

View File

@@ -1,9 +1,9 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
import WorkspacePage from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page);
await WasmWorkspacePage.mockConfigFlags(page, [
await WorkspacePage.init(page);
await WorkspacePage.mockConfigFlags(page, [
"enable-subscriptions",
"disable-onboarding",
]);
@@ -13,16 +13,16 @@ test.describe("Subscriptions: workspace", () => {
test("Unlimited team should have 'Power up your plan' link in main menu", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile();
await WasmWorkspacePage.mockRPC(
await WorkspacePage.mockRPC(
page,
"get-profile",
"subscription/get-profile-unlimited-subscription.json",
);
await WasmWorkspacePage.mockRPC(
await WorkspacePage.mockRPC(
page,
"get-subscription-usage",
"subscription/get-subscription-usage.json",
@@ -41,16 +41,16 @@ test.describe("Subscriptions: workspace", () => {
test("Enterprise team should not have 'Power up your plan' link in main menu", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile();
await WasmWorkspacePage.mockRPC(
await WorkspacePage.mockRPC(
page,
"get-profile",
"subscription/get-profile-enterprise-subscription.json",
);
await WasmWorkspacePage.mockRPC(
await WorkspacePage.mockRPC(
page,
"get-subscription-usage",
"subscription/get-subscription-usage.json",
@@ -69,16 +69,16 @@ test.describe("Subscriptions: workspace", () => {
test("Professional team should have 7 days autosaved versions", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile();
await WasmWorkspacePage.mockRPC(
await WorkspacePage.mockRPC(
page,
"get-profile",
"subscription/get-profile-enterprise-subscription.json",
);
await WasmWorkspacePage.mockRPC(
await WorkspacePage.mockRPC(
page,
"get-subscription-usage",
"subscription/get-subscription-usage.json",
@@ -105,22 +105,22 @@ test.describe("Subscriptions: workspace", () => {
test("Unlimited team should have 30 days autosaved versions", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile();
await WasmWorkspacePage.mockRPC(
await WorkspacePage.mockRPC(
page,
"get-profile",
"subscription/get-profile-unlimited-subscription.json",
);
await WasmWorkspacePage.mockRPC(
await WorkspacePage.mockRPC(
page,
"get-subscription-usage",
"subscription/get-subscription-usage.json",
);
await WasmWorkspacePage.mockRPC(
await WorkspacePage.mockRPC(
page,
"get-teams",
"subscription/get-teams-unlimited-one-team.json",
@@ -147,22 +147,22 @@ test.describe("Subscriptions: workspace", () => {
test("Unlimited team should have 90 days autosaved versions", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile();
await WasmWorkspacePage.mockRPC(
await WorkspacePage.mockRPC(
page,
"get-profile",
"subscription/get-profile-enterprise-subscription.json",
);
await WasmWorkspacePage.mockRPC(
await WorkspacePage.mockRPC(
page,
"get-subscription-usage",
"subscription/get-subscription-usage.json",
);
await WasmWorkspacePage.mockRPC(
await WorkspacePage.mockRPC(
page,
"get-teams",
"subscription/get-teams-enterprise-one-team.json",

View File

@@ -1493,8 +1493,10 @@ test.describe("Tokens - creation", () => {
const nameField = tokensUpdateCreateModal.getByLabel("Name");
await nameField.fill(newTokenTitle);
const referenceTabButton = tokensUpdateCreateModal.getByTestId("reference-opt");
await referenceTabButton.click();
const referenceTabButton = tokensUpdateCreateModal.getByRole("button", {
name: "Use a reference",
});
referenceTabButton.click();
const referenceField = tokensUpdateCreateModal.getByRole("textbox", {
name: "Reference",

View File

@@ -1,12 +1,12 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
import { WorkspacePage } from "../pages/WorkspacePage";
import { BaseWebSocketPage } from "../pages/BaseWebSocketPage";
import { Clipboard } from "../../helpers/Clipboard";
test.beforeEach(async ({ page, context }) => {
await Clipboard.enable(context, Clipboard.Permission.ALL);
await WasmWorkspacePage.init(page);
await WorkspacePage.init(page);
await BaseWebSocketPage.mockRPC(page, "get-teams", "get-teams-variants.json");
});
@@ -127,7 +127,7 @@ const validateVariant = async (variant) => {
};
test("User creates a variant", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage);
await workspacePage.clickLeafLayer("Rectangle");
@@ -154,7 +154,7 @@ test("User creates a variant", async ({ page }) => {
});
test("User duplicates a variant container", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0);
@@ -177,7 +177,7 @@ test("User duplicates a variant container", async ({ page }) => {
});
test("User copy paste a variant container", async ({ page, context }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
// Access to the read/write clipboard necesary for this functionality
await setupVariantsFileWithVariant(workspacePage);
await workspacePage.mockRPC(
@@ -212,7 +212,7 @@ test("User copy paste a variant container", async ({ page, context }) => {
});
test("User cut paste a variant container", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0);
@@ -240,7 +240,7 @@ test("User cut paste a variant container", async ({ page }) => {
test("User cut paste a variant container into a board, and undo twice", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0);
@@ -283,7 +283,7 @@ test("User cut paste a variant container into a board, and undo twice", async ({
});
test("User copy paste a variant", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0);
@@ -308,7 +308,7 @@ test("User copy paste a variant", async ({ page }) => {
});
test("User cut paste a variant outside the container", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0);
@@ -333,7 +333,7 @@ test("User cut paste a variant outside the container", async ({ page }) => {
});
test("User drag and drop a variant outside the container", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0);
@@ -347,7 +347,7 @@ test("User drag and drop a variant outside the container", async ({ page }) => {
});
test("User cut paste a component inside a variant", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0);
@@ -378,7 +378,7 @@ test("User cut paste a component inside a variant", async ({ page }) => {
test("User cut paste a component with path inside a variant", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage);
const variant = await findVariant(workspacePage, 0);
@@ -417,7 +417,7 @@ test("User cut paste a component with path inside a variant", async ({
test("User drag and drop a component with path inside a variant", async ({
page,
}) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage);
const variant = findVariantNoWait(workspacePage, 0);
@@ -450,7 +450,7 @@ test("User drag and drop a component with path inside a variant", async ({
});
test("User cut paste a variant into another container", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await setupVariantsFileWithVariant(workspacePage);
// Create anothe variant

View File

@@ -1,15 +1,15 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
import { WorkspacePage } from "../pages/WorkspacePage";
import { presenceFixture } from "../../data/workspace/ws-notifications";
test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page);
const workspacePage = new WasmWorkspacePage(page);
await WorkspacePage.init(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page);
});
test("Save and restore version", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.mockRPC(/get\-file\?/, "workspace/versions-init.json");
await workspacePage.mockRPC(
@@ -97,7 +97,7 @@ test("Save and restore version", async ({ page }) => {
});
test("BUG 11006 - Fix history panel shortcut", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.mockRPC(/get\-file\?/, "workspace/versions-init.json");
await workspacePage.mockRPC(
"get-file-snapshots?file-id=*",

View File

@@ -1,12 +1,12 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
import { WorkspacePage } from "../pages/WorkspacePage";
test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page);
await WorkspacePage.init(page);
});
test("Group bubbles when zooming out if they overlap", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile();
await workspacePage.setupFileWithComments();

View File

@@ -1,26 +0,0 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page);
});
test("BUG 13305 - Fix resize board to fit content", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
await workspacePage.setupEmptyFile();
await workspacePage.mockGetFile("workspace/get-file-13305.json");
await workspacePage.mockRPC("update-file?id=*", "workspace/update-file-13305.json");
await workspacePage.goToWorkspace({
fileId: "9666e946-78e8-8111-8007-8fe5f0f454bf",
pageId: "9666e946-78e8-8111-8007-8fe5f0f49ac6",
});
await workspacePage.clickLeafLayer("Board");
await workspacePage.rightSidebar.getByRole("button", { name: "Resize board to fit content" }).click();
await expect(workspacePage.rightSidebar.getByTitle("Width").getByRole("textbox")).toHaveValue("630");
await expect(workspacePage.rightSidebar.getByTitle("Height").getByRole("textbox")).toHaveValue("630");
await expect(workspacePage.rightSidebar.getByTitle("X axis").getByRole("textbox")).toHaveValue("110");
await expect(workspacePage.rightSidebar.getByTitle("Y axis").getByRole("textbox")).toHaveValue("110");
});

View File

@@ -1,5 +1,5 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
import { WorkspacePage } from "../pages/WorkspacePage";
const mainFileId = "3622460c-3408-81e2-8005-2fd0e55888b7";
const sharedFileId = "3622460c-3408-81e2-8005-2fc938010233";
@@ -13,12 +13,12 @@ const sharedFileFragmentId1 = "3622460c-3408-81e2-8005-31859c15ff91";
const sharedFileFragmentId2 = "3622460c-3408-81e2-8005-31859c15ff90";
test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page);
await WorkspacePage.init(page);
});
// Fix for https://tree.taiga.io/project/penpot/issue/9042
test("Bug 9056 - 'More info' doesn't open the update tab", async ({ page }) => {
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page);
await workspacePage.mockRPC(
@@ -76,7 +76,7 @@ test("Bug 9056 - 'More info' doesn't open the update tab", async ({ page }) => {
test("Bug 10113 - Empty library modal for non-empty library", async ({
page,
}) => {
const workspace = new WasmWorkspacePage(page);
const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile(page);
await workspace.mockRPC(/get\-file\?/, "workspace/get-file-10113.json");

View File

@@ -1,13 +1,13 @@
import { test, expect } from "@playwright/test";
import { WasmWorkspacePage } from "../pages/WasmWorkspacePage";
import { WorkspacePage } from "../pages/WorkspacePage";
import { presenceFixture } from "../../data/workspace/ws-notifications";
test.beforeEach(async ({ page }) => {
await WasmWorkspacePage.init(page);
await WorkspacePage.init(page);
const workspacePage = new WasmWorkspacePage(page);
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page);
await WasmWorkspacePage.mockRPC(page, "get-teams", "get-teams-role-viewer.json");
await WorkspacePage.mockRPC(page, "get-teams", "get-teams-role-viewer.json");
await workspacePage.goToWorkspace();
});

View File

@@ -353,24 +353,33 @@ test("Copy/paste properties", async ({ page, context }) => {
await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click();
await page.getByText("Rectangle").first().click({ button: "right" });
await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click();
await page.getByText("Board").nth(2).click({ button: "right" });
await page
.getByTestId("layer-item")
.getByText("Rectangle")
.first()
.click({ button: "right" });
await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click();
await page
.getByTestId("layer-item")
.locator("div")
.filter({ hasText: "Path" })
.getByText("Board")
.nth(1)
.click({ button: "right" });
await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click();
await page.getByText("Ellipse").click({ button: "right" });
await page
.getByTestId("layer-item")
.getByText("Path")
.click({ button: "right" });
await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click();
await page
.getByTestId("layer-item")
.getByText("Ellipse")
.click({ button: "right" });
await page.getByText("Copy/Paste as").hover();
await page.getByText("Paste properties").click();
});

View File

@@ -260,8 +260,8 @@ importers:
packages/tokenscript:
dependencies:
'@tokens-studio/tokenscript-interpreter':
specifier: ^0.26.0
version: 0.26.0
specifier: ^0.23.1
version: 0.23.1
packages/ui:
dependencies:
@@ -1720,8 +1720,8 @@ packages:
peerDependencies:
style-dictionary: '>=4.3.0 < 6'
'@tokens-studio/tokenscript-interpreter@0.26.0':
resolution: {integrity: sha512-dGjvUJnXRspWYp98FZw43l4cN+0ey/cF5sEJjL3coKc5C7DY7MsKgkmOONizmaZqf13GUIzklTEas3gt3jvrOQ==}
'@tokens-studio/tokenscript-interpreter@0.23.1':
resolution: {integrity: sha512-aIcJprCkHIyckl0Knn78Sn7ef3U3IXLjNv9MOePdNR0Mz3Z4PleerldtfLmr1DdXUXiroVSyJROyJrO3TfB2Gg==}
engines: {node: '>=16.0.0'}
hasBin: true
@@ -6715,7 +6715,7 @@ snapshots:
is-mergeable-object: 1.1.1
style-dictionary: 5.0.0-rc.1(tslib@2.8.1)
'@tokens-studio/tokenscript-interpreter@0.26.0':
'@tokens-studio/tokenscript-interpreter@0.23.1':
dependencies:
arktype: 2.1.29
commander: 14.0.3

View File

@@ -244,13 +244,6 @@
--assets-component-second-border-selected: var(--color-background-primary);
--assets-component-hightlight: var(--color-accent-secondary);
--radio-btns-background-color: var(--color-background-tertiary);
--radio-btn-background-color-selected: var(--color-background-quaternary);
--radio-btn-foreground-color: var(--color-foreground-secondary);
--radio-btn-foreground-color-selected: var(--color-accent-primary);
--radio-btn-border-color: var(--color-background-tertiary);
--radio-btn-border-color-selected: var(--color-background-quaternary);
--library-name-foreground-color: var(--color-foreground-primary);
--library-content-foreground-color: var(--color-foreground-secondary);
@@ -423,13 +416,6 @@
--tab-border-color: var(--color-background-tertiary);
--tab-border-color-selected: var(--color-background-secondary);
--radio-btns-background-color: var(--color-background-tertiary);
--radio-btn-background-color-selected: var(--color-background-primary);
--radio-btn-foreground-color: var(--color-foreground-secondary);
--radio-btn-foreground-color-selected: var(--color-accent-primary);
--radio-btn-border-color: var(--color-background-tertiary);
--radio-btn-border-color-selected: var(--color-background-secondary);
--button-icon-background-color-selected: var(--color-background-primary);
--button-icon-border-color-selected: var(--color-background-secondary);

View File

@@ -195,7 +195,7 @@
params {:exports exports
:cmd cmd
:profile-id profile-id
:force-multiple true}
:wait false}
progress-stream
(->> (ws/get-rcv-stream ws-conn)

View File

@@ -79,7 +79,7 @@
Structured tokens are non-primitive token types like `typography` or `box-shadow`."
[^js token-symbol]
(if (instance? js/Array (.-value token-symbol))
(mapv tokenscript-symbols->penpot-unit (.-value token-symbol))
(mapv structured-token->penpot-map (.-value token-symbol))
(let [entries (es6-iterator-seq (.entries (.-value token-symbol)))]
(into {} (map (fn [[k v :as V]]
[(keyword k) (tokenscript-symbols->penpot-unit v)])
@@ -88,7 +88,7 @@
(defn tokenscript-symbols->penpot-unit [^js v]
(cond
(structured-token? v) (structured-token->penpot-map v)
(list-symbol? v) (structured-token->penpot-map v)
(list-symbol? v) (tokenscript-symbols->penpot-unit (.nth 1 v))
(color-symbol? v) (.-value (.to v "hex"))
(rem-number-with-unit? v) (rem->px v)
:else (.-value v)))

View File

@@ -43,13 +43,9 @@
(> dy dx)
(assoc :x (- (:x point) (* sx (- dy dx)))))))
(defn resize-shape [{:keys [x y width height] :as shape} initial point lock? mod? snap-pixel?]
(defn resize-shape [{:keys [x y width height] :as shape} initial point lock? mod?]
(if (and (some? x) (some? y) (some? width) (some? height))
(let [draw-rect (cond-> (grc/make-rect initial (cond-> point lock? (adjust-ratio initial)))
snap-pixel?
(-> (update :width max 1)
(update :height max 1)))
(let [draw-rect (grc/make-rect initial (cond-> point lock? (adjust-ratio initial)))
shape-rect (grc/make-rect x y width height)
scalev (gpt/point (/ (:width draw-rect)
@@ -68,8 +64,8 @@
(ctm/move movev)))))
shape))
(defn- update-drawing [state initial point lock? mod? snap-pixel?]
(update-in state [:workspace-drawing :object] resize-shape initial point lock? mod? snap-pixel?))
(defn update-drawing [state initial point lock? mod?]
(update-in state [:workspace-drawing :object] resize-shape initial point lock? mod?))
(defn move-drawing
[{:keys [x y]}]
@@ -124,7 +120,7 @@
(rx/map move-drawing))
(->> ms/mouse-position
(rx/filter #(> (* (gpt/distance % initial) zoom) 10))
(rx/filter #(> (gpt/distance % initial) (/ 2 zoom)))
;; Take until before the snap calculation otherwise we could cancel the snap in the worker
;; and its a problem for fast moving drawing
(rx/take-until stopper)
@@ -135,7 +131,7 @@
(rx/map (partial array/conj current)))))
(rx/map
(fn [[_ shift? mod? point]]
#(update-drawing % initial (cond-> point snap-pixel? (gpt/round-step 1)) shift? mod? snap-pixel?))))))
#(update-drawing % initial (cond-> point snap-pixel? (gpt/round-step 1)) shift? mod?))))))
(->> (rx/of (common/handle-finish-drawing))
(rx/delay 100)))))))

View File

@@ -571,13 +571,11 @@
nil
(ctm/has-geometry? (:modifiers data))
(let [parent (:geometry-parent (:modifiers data))
kind (if (d/not-empty? parent) :parent :child)]
(d/vec2 id {:transform (ctm/modifiers->transform (:modifiers data)) :kind kind}))
(d/vec2 id (ctm/modifiers->transform (:modifiers data)))
;; Unit matrix is used for reflowing
:else
(d/vec2 id {:transform default-transform :kind :parent}))))))
(d/vec2 id default-transform))))))
(defn- parse-geometry-modifiers
[modif-tree]

View File

@@ -950,11 +950,14 @@
new-shape))
{:save-undo? save-undo? :undo-group (when new-shape? id)})
(let [modifiers (dwwt/resize-wasm-text-modifiers shape content)
options {:undo-group (when new-shape? id)}]
(if (and (not= :fixed (:grow-type shape)) finalize?)
(dwm/apply-wasm-modifiers modifiers options)
(dwm/set-wasm-modifiers modifiers options))))
(if (and (not= :fixed (:grow-type shape)) finalize?)
(dwm/apply-wasm-modifiers
(dwwt/resize-wasm-text-modifiers shape content)
{:undo-group (when new-shape? id)})
(dwm/set-wasm-modifiers
(dwwt/resize-wasm-text-modifiers shape content)
{:undo-group (when new-shape? id)})))
(when finalize?
(rx/concat

View File

@@ -53,27 +53,26 @@
([value shape-ids attributes] (update-shape-radius-all value shape-ids attributes nil))
([value shape-ids _attributes page-id] ; The attributes param is needed to have the same arity that other update functions
(when (number? value)
(let [value (max 0 value)]
(dwsh/update-shapes shape-ids
(fn [shape]
(ctsr/set-radius-to-all-corners shape value))
{:reg-objects? true
:ignore-touched true
:page-id page-id
:attrs ctt/border-radius-keys})))))
(dwsh/update-shapes shape-ids
(fn [shape]
(ctsr/set-radius-to-all-corners shape value))
{:reg-objects? true
:ignore-touched true
:page-id page-id
:attrs ctt/border-radius-keys}))))
(defn update-shape-radius-for-corners
([value shape-ids attributes] (update-shape-radius-for-corners value shape-ids attributes nil))
([value shape-ids attributes page-id]
(when (number? value)
(let [value (max 0 value)]
(dwsh/update-shapes shape-ids
(fn [shape]
(ctsr/set-radius-for-corners shape attributes value))
{:reg-objects? true
:ignore-touched true
:page-id page-id
:attrs ctt/border-radius-keys})))))
(dwsh/update-shapes shape-ids
(fn [shape]
(ctsr/set-radius-for-corners shape attributes value))
{:reg-objects? true
:ignore-touched true
:page-id page-id
:attrs ctt/border-radius-keys}))))
(defn update-opacity
([value shape-ids attributes] (update-opacity value shape-ids attributes nil))
([value shape-ids _attributes page-id] ; The attributes param is needed to have the same arity that other update functions

View File

@@ -1261,6 +1261,7 @@
(some? new-modif)
(assoc (:id frame) {:modifiers new-modif})))))
{}))]
(if (features/active-feature? state "render-wasm/v1")
(rx/of (dwm/apply-wasm-modifiers modifiers {:undo-group undo-group}))
(rx/of (dwm/apply-modifiers {:modifiers modifiers :undo-group undo-group})))))))

View File

@@ -50,41 +50,17 @@
(set/union (get team :features))
(setup-wasm-features state))))
(defn enabled-by-flags?
[{:keys [features-runtime features]} feature]
(or (contains? features-runtime feature)
(contains? features feature)))
(defn enabled-without-migration?
[{:keys [features-runtime features]} feature]
(or (contains? features-runtime feature)
(contains? global-enabled-features feature)
(contains? features feature)))
(defn wasm-url-override
[state]
(case (get (rt/get-params state) :wasm)
"true" true
"false" false
nil))
(defn active-feature?
"Given a state and feature, check if feature is enabled."
[state feature]
(assert (contains? cfeat/supported-features feature)
"feature not supported")
(let [wasm-override (when (= feature "render-wasm/v1")
(wasm-url-override state))]
(cond
(some? wasm-override)
wasm-override
(contains? cfeat/no-migration-features feature)
(enabled-without-migration? state feature)
:else
(enabled-by-flags? state feature))))
(assert (contains? cfeat/supported-features feature) "feature not supported")
(let [runtime-features (get state :features-runtime)
enabled-features (get state :features)]
(or (contains? runtime-features feature)
(if (contains? cfeat/no-migration-features feature)
(or (contains? global-enabled-features feature)
(contains? enabled-features feature))
(contains? enabled-features feature)))))
(def ^:private features-ref
(l/derived (l/key :features) st/state))

View File

@@ -10,9 +10,9 @@
[app.util.dom :as dom]
[rumext.v2 :as mf]))
(mf/defc file-uploader
(mf/defc file-uploader*
{::mf/forward-ref true}
[{:keys [accept multi label-text label-class input-id on-selected data-testid] :as props} input-ref]
[{:keys [accept multi label-text label-class input-id on-selected data-testid]} input-ref]
(let [opt-pick-one #(if multi % (first %))
on-files-selected

View File

@@ -1,107 +0,0 @@
;; 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.components.radio-buttons
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.main.ui.ds.foundations.assets.icon :refer [icon*]]
[app.main.ui.formats :as fmt]
[app.util.dom :as dom]
[rumext.v2 :as mf]))
(def context
(mf/create-context nil))
(mf/defc radio-button
{::mf/props :obj}
[{:keys [icon id value disabled title icon-class type]}]
(let [context (mf/use-ctx context)
allow-empty (unchecked-get context "allow-empty")
type (if ^boolean type
type
(if ^boolean allow-empty
"checkbox"
"radio"))
on-change (unchecked-get context "on-change")
selected (unchecked-get context "selected")
name (unchecked-get context "name")
encode-fn (unchecked-get context "encode-fn")
checked? (= selected value)
value (encode-fn value)]
[:label {:html-for id
:data-testid id
:title title
:class (stl/css-case
:radio-icon true
:checked checked?
:disabled disabled)}
(if (some? icon)
[:> icon* {:icon-id icon :class icon-class :aria-hidden true}]
[:span {:class (stl/css :title-name)} value])
[:input {:id id
:on-change on-change
:type type
:name name
:disabled disabled
:value value
:default-checked checked?}]]))
(mf/defc radio-buttons
{::mf/props :obj}
[{:keys [name children on-change selected class wide encode-fn decode-fn allow-empty] :as props}]
(let [encode-fn (d/nilv encode-fn identity)
decode-fn (d/nilv decode-fn identity)
nitems (if (array? children)
(count (keep identity children))
1)
;; FIXME: we should handle this with CSS
width (mf/with-memo [nitems]
(if (= wide true)
"unset"
(fmt/format-pixels
(+ (* 4 (- nitems 1))
(* 32 nitems)))))
on-change'
(mf/use-fn
(mf/deps selected on-change)
(fn [event]
(let [input (dom/get-target event)
value (dom/get-target-val event)
;; Only allow null values when the "allow-empty" prop is true
value (when (or (not allow-empty)
(not= value selected)) value)]
(when (fn? on-change)
(on-change (decode-fn value) event))
(dom/blur! input))))
context-value
(mf/spread-object props
;; We pass a special metadata for disable
;; key casing transformation in this
;; concrete case, because this component
;; uses legacy mode and props are in
;; kebab-case style
^{::mf/transform false}
{:on-change on-change'
:encode-fn encode-fn
:decode-fn decode-fn})]
[:& (mf/provider context) {:value context-value}
[:div {:class (dm/str class " " (stl/css :radio-btn-wrapper))
:style {:width width}
:key (dm/str name "-" selected)}
children]]))

View File

@@ -1,79 +0,0 @@
// 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
@use "refactor/common-refactor.scss" as deprecated;
.radio-btn-wrapper {
@include deprecated.flexCenter;
border-radius: deprecated.$br-8;
height: deprecated.$s-32;
background-color: var(--input-background-color);
gap: deprecated.$s-4;
}
.radio-icon {
--radio-icon-border-color: var(--radio-btn-border-color);
@include deprecated.buttonStyle;
@include deprecated.flexCenter;
@include deprecated.focusRadio;
height: deprecated.$s-32;
flex-grow: 1;
border-radius: deprecated.$s-8;
box-sizing: border-box;
border: deprecated.$br-2 solid var(--radio-icon-border-color);
input {
display: none;
}
svg {
@extend .button-icon;
stroke: var(--radio-btn-foreground-color);
}
.title-name {
@include deprecated.uppercaseTitleTipography;
color: var(--radio-btn-foreground-color);
}
&:hover {
svg {
stroke: var(--radio-btn-foreground-color-selected);
}
}
}
.checked {
--radio-icon-border-color: var(--radio-btn-border-color-selected);
background-color: var(--radio-btn-background-color-selected);
svg {
stroke: var(--radio-btn-foreground-color-selected);
}
.title-name {
color: var(--radio-btn-foreground-color-selected);
}
}
.disabled {
cursor: default;
background-color: transparent;
border: deprecated.$s-2 solid transparent;
svg {
stroke: var(--button-foreground-color-disabled);
}
.title-name {
color: var(--button-foreground-color-disabled);
}
&:hover {
background-color: transparent;
border: deprecated.$s-2 solid transparent;
svg {
stroke: var(--button-foreground-color-disabled);
}
.title-name {
color: var(--button-foreground-color-disabled);
}
}
}

View File

@@ -17,7 +17,7 @@
[app.main.repo :as rp]
[app.main.store :as st]
[app.main.ui.components.context-menu-a11y :refer [context-menu*]]
[app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.components.file-uploader :refer [file-uploader*]]
[app.main.ui.ds.product.empty-placeholder :refer [empty-placeholder*]]
[app.main.ui.icons :as deprecated-icon]
[app.main.ui.notifications.context-notification :refer [context-notification]]
@@ -184,11 +184,11 @@
:on-click on-click
:tab-index "0"}
[:span (tr "labels.add-custom-font")]
[:& file-uploader {:input-id "font-upload"
:accept accept-font-types
:multi true
:ref input-ref
:on-selected on-selected}]]
[:> file-uploader* {:input-id "font-upload"
:accept accept-font-types
:multi true
:ref input-ref
:on-selected on-selected}]]
(when-let [url cf/terms-of-service-uri]
[:& context-notification {:content (tr "dashboard.fonts.hero-text2" url)

View File

@@ -16,7 +16,7 @@
[app.main.data.modal :as modal]
[app.main.data.notifications :as ntf]
[app.main.store :as st]
[app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.components.file-uploader :refer [file-uploader*]]
[app.main.ui.ds.product.loader :refer [loader*]]
[app.main.ui.icons :as deprecated-icon]
[app.main.ui.notifications.context-notification :refer [context-notification]]
@@ -58,10 +58,10 @@
[{:keys [project-id on-finish-import]} external-ref]
(let [on-file-selected (use-import-file project-id on-finish-import)]
[:form.import-file {:aria-hidden "true"}
[:& file-uploader {:accept ".penpot,.zip"
:multi true
:ref external-ref
:on-selected on-file-selected}]]))
[:> file-uploader* {:accept ".penpot,.zip"
:multi true
:ref external-ref
:on-selected on-file-selected}]]))
(defn- update-entry-name
[entries file-id new-name]

View File

@@ -19,7 +19,7 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.components.file-uploader :refer [file-uploader*]]
[app.main.ui.components.forms :as fm]
[app.main.ui.dashboard.change-owner]
[app.main.ui.dashboard.subscription :refer [members-cta*
@@ -1315,10 +1315,10 @@
[:img {:class (stl/css :team-image)
:src (cfg/resolve-team-photo-url team)}]
(when can-edit
[:& file-uploader {:accept "image/jpeg,image/png"
:multi false
:ref finput
:on-selected on-file-selected}])]
[:> file-uploader* {:accept "image/jpeg,image/png"
:multi false
:ref finput
:on-selected on-file-selected}])]
[:div {:class (stl/css :block-label)}
(tr "dashboard.team-info")]
[:div {:class (stl/css :block-text)}

View File

@@ -11,8 +11,10 @@
[app.main.data.modal :as modal]
[app.main.repo :as rp]
[app.main.store :as st]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.ds.notifications.context-notification :refer [context-notification*]]
[app.main.ui.icons :as deprecated-icon]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as k]
@@ -97,8 +99,11 @@
[:div {:class (stl/css :modal-container)}
[:div {:class (stl/css :modal-header)}
[:h2 {:class (stl/css :modal-title)} title]
[:button {:class (stl/css :modal-close-btn)
:on-click cancel-fn} deprecated-icon/close]]
[:> icon-button* {:variant "ghost"
:class (stl/css :modal-close-btn)
:icon i/close
:aria-label (tr "labels.close")
:on-click cancel-fn}]]
[:div {:class (stl/css :modal-content)}
(when (and (string? subtitle) (not= subtitle ""))
@@ -124,14 +129,10 @@
[:div {:class (stl/css :modal-footer)}
[:div {:class (stl/css :action-buttons)}
(when-not (= cancel-label :omit)
[:input {:class (stl/css :cancel-button)
:type "button"
:value cancel-label
:on-click cancel-fn}])
[:> button* {:variant "secondary"
:on-click cancel-fn}
cancel-label])
[:input {:class (stl/css-case :accept-btn true
:danger (= accept-style :danger)
:primary (= accept-style :primary))
:type "button"
:value accept-label
:on-click accept-fn}]]]]]))
[:> button* {:variant (if (= accept-style :danger) "destructive" "primary")
:on-click accept-fn}
accept-label]]]]]))

View File

@@ -33,7 +33,9 @@
}
.modal-close-btn {
@extend .modal-close-btn-base;
position: absolute;
top: var(--sp-s);
right: var(--sp-s);
}
.modal-content {
@@ -53,17 +55,6 @@
@extend .modal-action-btns;
}
.cancel-button {
@extend .modal-cancel-btn;
}
.accept-btn {
@extend .modal-accept-btn;
&.danger {
@extend .modal-danger-btn;
}
}
.modal-scd-msg {
margin-block: 0;
}

View File

@@ -15,6 +15,7 @@
display: inline-flex;
align-items: center;
justify-content: center;
column-gap: var(--sp-xs);
}

View File

@@ -208,7 +208,7 @@
;; FIXME: deprecated, should be refactored in two components and use
;; the generic progress reporter
(mf/defc progress-widget
(mf/defc progress-widget*
{::mf/wrap [mf/memo]}
[]
(let [state (mf/deref refs/export)

View File

@@ -19,7 +19,10 @@
[app.main.store :as st]
[app.main.ui.components.code-block :refer [code-block]]
[app.main.ui.components.copy-button :refer [copy-button*]]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.hooks.resize :refer [use-resize-hook]]
[app.main.ui.icons :as deprecated-icon]
[app.main.ui.shapes.text.fontfaces :refer [shapes->fonts]]
@@ -260,8 +263,9 @@
[:div {:class (stl/css-case :element-options true
:viewer-code-block (= :viewer from))}
[:div {:class (stl/css :attributes-block)}
[:button {:class (stl/css :download-button)
:on-click handle-copy-all-code}
[:> button* {:variant "secondary"
:class (stl/css :download-button)
:on-click handle-copy-all-code}
"Copy all code"]]
#_[:div.attributes-block
@@ -288,10 +292,10 @@
;; :options [{:label "CSS" :value "css"}]}]
[:div {:class (stl/css :action-btns)}
[:button {:class (stl/css :expand-button)
:on-click on-expand}
deprecated-icon/code]
[:> icon-button* {:variant "ghost"
:aria-label "Expand"
:on-click on-expand
:icon i/code}]
[:> copy-button* {:data copy-css-fn
:class (stl/css :css-copy-btn)
:on-copied on-style-copied}]]]
@@ -318,21 +322,21 @@
:rotated collapsed-markup?)}
deprecated-icon/arrow]]
[:& radio-buttons {:selected markup-type
:on-change set-markup
:class (stl/css :code-lang-options)
:wide true
:name "listing-style"}
[:& radio-button {:value "html"
:id :html}]
[:& radio-button {:value "svg"
:id :svg}]]
[:> radio-buttons* {:selected markup-type
:on-change set-markup
:name "listing-style"
:options [{:id "html"
:label "HTML"
:value "html"}
{:id "svg"
:label "SVG"
:value "svg"}]}]
[:div {:class (stl/css :action-btns)}
[:button {:class (stl/css :expand-button)
:on-click on-expand}
deprecated-icon/code]
[:> icon-button* {:variant "ghost"
:aria-label "Expand"
:on-click on-expand
:icon i/code}]
[:> copy-button* {:data copy-html-fn
:class (stl/css :html-copy-btn)
:on-copied on-markup-copied}]]]

View File

@@ -17,16 +17,18 @@
padding-inline: var(--sp-m);
}
.attributes-block {
display: flex;
flex-direction: column;
row-gap: 12px;
}
.viewer-code-block {
height: calc(100vh - #{deprecated.$s-108}); // TODO: Fix this hardcoded value
}
.download-button {
@extend .button-secondary;
@include deprecated.uppercaseTitleTipography;
height: deprecated.$s-32;
width: 100%;
margin: deprecated.$s-8 0;
margin: var(--sp-s) 0;
}
.code-block {
@@ -73,7 +75,6 @@
gap: deprecated.$s-4;
}
.expand-button,
.css-copy-btn,
.html-copy-btn {
@extend .button-tertiary;
@@ -85,9 +86,6 @@
}
}
.code-lang-options {
max-width: deprecated.$s-108;
}
.code-lang-select {
@include deprecated.uppercaseTitleTipography;
width: deprecated.$s-72;

View File

@@ -14,7 +14,7 @@
[app.main.data.profile :as du]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.components.file-uploader :refer [file-uploader*]]
[app.main.ui.components.forms :as fm]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@@ -110,11 +110,11 @@
[:span {:class (stl/css :update-overlay)
:on-click on-image-click} (tr "labels.update")]
[:img {:src photo}]
[:& file-uploader {:accept "image/jpeg,image/png"
:multi false
:ref input-ref
:on-selected on-file-selected
:data-testid "profile-image-input"}]]]))
[:> file-uploader* {:accept "image/jpeg,image/png"
:multi false
:ref input-ref
:on-selected on-file-selected
:data-testid "profile-image-input"}]]]))
;; --- Profile Page

View File

@@ -27,9 +27,8 @@
[okulary.core :as l]
[rumext.v2 :as mf]))
(mf/defc comments-menu
{::mf/props :obj
::mf/memo true}
(mf/defc comments-menu*
{::mf/memo true}
[]
(let [state (mf/deref refs/comments-local)
cmode (:mode state)

View File

@@ -14,10 +14,13 @@
[app.main.data.viewer.shortcuts :as sc]
[app.main.store :as st]
[app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.exports.assets :refer [progress-widget]]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.exports.assets :refer [progress-widget*]]
[app.main.ui.formats :as fmt]
[app.main.ui.icons :as deprecated-icon]
[app.main.ui.viewer.comments :refer [comments-menu]]
[app.main.ui.viewer.comments :refer [comments-menu*]]
[app.main.ui.viewer.interactions :refer [flows-menu* interactions-menu*]]
[app.util.dom :as dom]
[app.util.i18n :refer [tr]]
@@ -33,20 +36,12 @@
[]
(modal/show! :login-register {}))
(mf/defc zoom-widget
{::mf/memo true
::mf/props :obj}
[{:keys [zoom
on-increase
on-decrease
on-zoom-reset
on-fullscreen
on-zoom-fit
on-zoom-fill]
:as props}]
(mf/defc zoom-widget*
{::mf/memo true}
[{:keys [zoom on-increase on-decrease on-zoom-reset on-fullscreen on-zoom-fit on-zoom-fill]}]
(let [open* (mf/use-state false)
open? (deref open*)
(let [open* (mf/use-state false)
open? (deref open*)
open-dropdown
(mf/use-fn
(fn [event]
@@ -75,7 +70,7 @@
[:div {:class (stl/css-case :zoom-widget true
:selected open?)
:on-click open-dropdown
:on-click (if open? close-dropdown open-dropdown)
:title (tr "workspace.header.zoom")}
[:span {:class (stl/css :label)} (fmt/format-percent zoom)]
[:& dropdown {:show open?
@@ -83,18 +78,18 @@
[:ul {:class (stl/css :dropdown)}
[:li {:class (stl/css :basic-zoom-bar)}
[:span {:class (stl/css :zoom-btns)}
[:button {:class (stl/css :zoom-btn)
:on-click on-decrease}
[:span {:class (stl/css :zoom-icon)}
deprecated-icon/remove-icon]]
[:p {:class (stl/css :zoom-text)}
[:> icon-button* {:variant "ghost"
:aria-label (tr "shortcuts.decrease-zoom")
:on-click on-decrease
:icon i/remove}]
[:p {:class (stl/css :zoom-text)}
(fmt/format-percent zoom)]
[:button {:class (stl/css :zoom-btn)
:on-click on-increase}
[:span {:class (stl/css :zoom-icon)}
deprecated-icon/add]]]
[:button {:class (stl/css :reset-btn)
:on-click on-zoom-reset}
[:> icon-button* {:variant "ghost"
:aria-label (tr "shortcuts.increase-zoom")
:on-click on-increase
:icon i/add}]]
[:> button* {:variant "ghost"
:on-click on-zoom-reset}
(tr "workspace.header.reset-zoom")]]
[:li {:class (stl/css :zoom-option)
@@ -119,7 +114,7 @@
[:span {:class (stl/css :shortcut-key)
:key (dm/str "zoom-fullscreen-" sc)} sc])]]]]]))
(mf/defc header-options
(mf/defc header-options*
[{:keys [section zoom page file index permissions interactions-mode share]}]
(let [fullscreen? (mf/deref fullscreen-ref)
@@ -159,6 +154,7 @@
handle-zoom-fit
(mf/use-fn
#(st/emit! dv/zoom-to-fit))]
(mf/with-effect [permissions share]
(when (and
(:in-team permissions)
@@ -167,7 +163,7 @@
(open-share-dialog)))
[:div {:class (stl/css :options-zone)}
[:& progress-widget]
[:> progress-widget*]
(case section
:interactions [:*
@@ -175,40 +171,41 @@
[:> flows-menu* {:page page :index index}])
[:> interactions-menu*
{:interactions-mode interactions-mode}]]
:comments [:& comments-menu]
:comments [:> comments-menu*]
[:div {:class (stl/css :view-options)}])
[:& zoom-widget
{:zoom zoom
:on-increase handle-increase
:on-decrease handle-decrease
:on-zoom-reset handle-zoom-reset
:on-zoom-fill handle-zoom-fill
:on-zoom-fit handle-zoom-fit
:on-fullscreen toggle-fullscreen}]
[:> zoom-widget* {:zoom zoom
:on-increase handle-increase
:on-decrease handle-decrease
:on-zoom-reset handle-zoom-reset
:on-zoom-fill handle-zoom-fill
:on-zoom-fit handle-zoom-fit
:on-fullscreen toggle-fullscreen}]
(when (:in-team permissions)
[:span {:on-click go-to-workspace
:class (stl/css :edit-btn)}
deprecated-icon/curve])
[:> icon-button* {:variant "ghost"
:aria-label (tr "viewer.header.edit-in-workspace")
:on-click go-to-workspace
:icon i/curve}])
[:span {:title (tr "viewer.header.fullscreen")
:class (stl/css-case :fullscreen-btn true
:selected fullscreen?)
:on-click toggle-fullscreen}
deprecated-icon/expand]
[:> icon-button* {:variant "ghost"
:aria-pressed fullscreen?
:aria-label (tr "viewer.header.fullscreen")
:on-click toggle-fullscreen
:icon i/expand}]
(when (:in-team permissions)
[:button {:on-click open-share-dialog
:class (stl/css :share-btn)}
[:> button* {:variant "primary"
:class (stl/css :share-btn)
:on-click open-share-dialog}
(tr "labels.share")])
(when-not (:is-logged permissions)
[:span {:on-click open-login-dialog
:class (stl/css :go-log-btn)} (tr "labels.log-or-sign")])]))
(mf/defc header-sitemap
[{:keys [project file page frame toggle-thumbnails] :as props}]
(mf/defc header-sitemap*
[{:keys [project file page frame toggle-thumbnails]}]
(let [project-name (:name project)
file-name (:name file)
page-name (:name page)
@@ -317,44 +314,44 @@
:pointer-events (when-not (:in-team permissions) "none")}}
penpot-logo-icon]
[:& header-sitemap {:project project
:file file
:page page
:frame frame
:toggle-thumbnails toggle-thumbnails
:index index}]]
[:> header-sitemap* {:project project
:file file
:page page
:frame frame
:toggle-thumbnails toggle-thumbnails
:index index}]]
[:div {:class (stl/css :mode-zone)}
[:button {:on-click navigate
:data-value "interactions"
:class (stl/css-case :mode-zone-btn true
:selected (= section :interactions))
:title (tr "viewer.header.interactions-section" (sc/get-tooltip :open-interactions))}
deprecated-icon/play]
[:> icon-button* {:variant "ghost"
:aria-pressed (= section :interactions)
:aria-label (tr "viewer.header.interactions-section" (sc/get-tooltip :open-interactions))
:data-value "interactions"
:on-click navigate
:icon i/play}]
(when (or (:in-team permissions)
(= (:who-comment permissions) "all"))
[:button {:on-click navigate
:data-value "comments"
:class (stl/css-case :mode-zone-btn true
:selected (= section :comments))
:title (tr "viewer.header.comments-section" (sc/get-tooltip :open-comments))}
deprecated-icon/comments])
[:> icon-button* {:variant "ghost"
:aria-pressed (= section :comments)
:aria-label (tr "viewer.header.comments-section" (sc/get-tooltip :open-comments))
:data-value "comments"
:on-click navigate
:icon i/comments}])
(when (or (:in-team permissions)
(and (= (:type permissions) :share-link)
(= (:who-inspect permissions) "all")))
[:button {:on-click go-to-inspect
:class (stl/css-case :mode-zone-btn true
:selected (= section :inspect))
:title (tr "viewer.header.inspect-section" (sc/get-tooltip :open-inspect))}
deprecated-icon/code])]
[:> icon-button* {:variant "ghost"
:aria-pressed (= section :inspect)
:aria-label (tr "viewer.header.inspect-section" (sc/get-tooltip :open-inspect))
:on-click go-to-inspect
:icon i/code}])]
[:& header-options {:section section
:permissions permissions
:page page
:file file
:index index
:zoom zoom
:interactions-mode interactions-mode
:share share}]]))
[:> header-options* {:section section
:permissions permissions
:page page
:file file
:index index
:zoom zoom
:interactions-mode interactions-mode
:share share}]]))

View File

@@ -12,7 +12,7 @@
grid-column: 1 / span 1;
grid-row: 1 / span 1;
display: grid;
grid-template-columns: 1fr deprecated.$s-92 1fr;
grid-template-columns: 1fr auto 1fr;
justify-content: space-between;
align-items: center;
height: deprecated.$s-48;
@@ -130,23 +130,9 @@
// SECTION BUTTONS
.mode-zone {
@include deprecated.flexRow;
height: 100%;
}
.mode-zone-btn {
@extend .button-tertiary;
@include deprecated.flexCenter;
height: deprecated.$s-32;
width: deprecated.$s-28;
padding: 0;
svg {
@extend .button-icon;
}
}
.selected {
@extend .button-icon-selected;
display: flex;
flex-direction: row;
gap: var(--sp-xs);
}
// OPTION AREA
@@ -165,33 +151,8 @@
cursor: pointer;
}
.fullscreen-btn {
@extend .button-tertiary;
@include deprecated.flexCenter;
height: deprecated.$s-32;
width: deprecated.$s-28;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
}
.share-btn {
@extend .button-primary;
height: deprecated.$s-32;
min-width: deprecated.$s-72;
margin-left: deprecated.$s-4;
}
.edit-btn {
@extend .button-tertiary;
@include deprecated.flexCenter;
height: deprecated.$s-32;
width: deprecated.$s-28;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
margin-left: var(--sp-xs);
}
.go-log-btn {
@@ -245,43 +206,15 @@
display: flex;
}
.zoom-btn {
@extend .button-tertiary;
height: deprecated.$s-28;
width: deprecated.$s-28;
border-radius: deprecated.$br-8;
.zoom-icon {
@include deprecated.flexCenter;
width: deprecated.$s-24;
height: deprecated.$s-32;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
}
&:hover {
.zoom-icon svg {
stroke: var(--button-tertiary-foreground-color-hover);
}
}
}
.zoom-text {
@include deprecated.flexCenter;
height: 100%;
min-width: deprecated.$s-64;
min-width: deprecated.$s-48;
padding: 0;
margin: 0 deprecated.$s-2;
color: var(--modal-title-foreground-color);
}
.reset-btn {
@extend .button-tertiary;
color: var(--button-tertiary-foreground-color-hover);
height: deprecated.$s-28;
border-radius: deprecated.$br-8;
}
.zoom-option {
@extend .menu-item-base;
.shortcuts {

View File

@@ -20,6 +20,9 @@
[app.main.router :as rt]
[app.main.store :as st]
[app.main.ui.components.select :refer [select]]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.icons :as deprecated-icon]
[app.util.clipboard :as clipboard]
[app.util.dom :as dom]
@@ -171,10 +174,11 @@
[:div {:class (stl/css :share-link-header)}
[:h2 {:class (stl/css :share-link-title)}
(tr "common.share-link.title")]
[:button {:class (stl/css :modal-close-button)
:on-click on-close
:title (tr "labels.close")}
deprecated-icon/close]]
[:> icon-button* {:variant "ghost"
:class (stl/css :modal-close-button)
:aria-label (tr "labels.close")
:on-click on-close
:icon i/close}]]
[:div {:class (stl/css :modal-content)}
[:div {:class (stl/css :share-link-section)}
(when (and (not confirm?) (some? current-link))
@@ -185,10 +189,10 @@
:placeholder (tr "common.share-link.placeholder")
:read-only true}]
[:button {:class (stl/css :copy-button)
:title (tr "viewer.header.share.copy-link")
:on-click copy-link}
deprecated-icon/clipboard]])
[:> icon-button* {:variant "ghost"
:aria-label (tr "viewer.header.share.copy-link")
:on-click copy-link
:icon i/clipboard}]])
[:div {:class (stl/css :hint-wrapper)}
(when (not ^boolean confirm?)
@@ -199,28 +203,22 @@
[:div {:class (stl/css :description)}
(tr "common.share-link.confirm-deletion-link-description")]
[:div {:class (stl/css :actions)}
[:input {:type "button"
:class (stl/css :button-cancel)
:on-click #(reset! confirm* false)
:value (tr "labels.cancel")}]
[:input {:type "button"
:class (stl/css :button-danger)
:on-click delete-link
:value (tr "common.share-link.destroy-link")}]]]
[:> button* {:variant "secondary"
:on-click #(reset! confirm* false)}
(tr "labels.cancel")]
[:> button* {:variant "destructive"
:on-click delete-link}
(tr "common.share-link.destroy-link")]]]
(some? current-link)
[:input
{:type "button"
:class (stl/css :button-danger)
:on-click try-delete-link
:value (tr "common.share-link.destroy-link")}]
[:> button* {:variant "destructive"
:on-click try-delete-link}
(tr "common.share-link.destroy-link")]
:else
[:input
{:type "button"
:class (stl/css :button-active)
:on-click create-link
:value (tr "common.share-link.get-link")}])]]
[:> button* {:variant "primary"
:on-click create-link}
(tr "common.share-link.get-link")])]]
(when (not ^boolean confirm?)
@@ -305,6 +303,7 @@
:options [{:value "team" :label (tr "common.share-link.team-members")}
{:value "all" :label (tr "common.share-link.all-users")}]
:on-change on-comment-change}]]]
[:div {:class (stl/css :inspect-mode)}
[:div {:class (stl/css :subtitle)}
(tr "common.share-link.permissions-can-inspect")]
@@ -315,6 +314,3 @@
:options [{:value "team" :label (tr "common.share-link.team-members")}
{:value "all" :label (tr "common.share-link.all-users")}]
:on-change on-inspect-change}]]]])])]]]))

View File

@@ -30,7 +30,9 @@
}
.modal-close-button {
@extend .modal-close-btn-base;
position: absolute;
top: var(--sp-s);
right: var(--sp-s);
}
.modal-content {
@@ -74,18 +76,6 @@
}
}
.copy-button {
@extend .button-secondary;
@include deprecated.flexRow;
gap: deprecated.$s-8;
height: deprecated.$s-32;
width: deprecated.$s-28;
svg {
@extend .button-icon;
stroke: var(--icon-foreground-hover);
}
}
.description {
@include deprecated.bodySmallTypography;
color: var(--modal-text-foreground-color);
@@ -97,18 +87,6 @@
justify-content: flex-end;
}
.button-active {
@extend .modal-accept-btn;
}
.button-cancel {
@extend .modal-cancel-btn;
}
.button-danger {
@extend .modal-danger-btn;
}
.permissions-section {
@include deprecated.flexColumn;
gap: deprecated.$s-8;

View File

@@ -25,10 +25,11 @@
[app.main.features :as features]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.components.file-uploader :refer [file-uploader*]]
[app.main.ui.components.numeric-input :refer [numeric-input*]]
[app.main.ui.components.radio-buttons :refer [radio-buttons radio-button]]
[app.main.ui.components.select :refer [select]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]]
[app.main.ui.hooks :as hooks]
@@ -415,24 +416,25 @@
:on-change handle-change-mode}]])
(when (and (= origin :sidebar) show-tokens? token-color)
[:& radio-buttons {:selected color-style
:on-change toggle-token-color
:name "color-style"}
[:& radio-button {:icon i/swatches
:value :direct-color
:title (tr "labels.color")
:id "opt-color"}]
[:& radio-button {:icon i/tokens
:value :token-color
:title (tr "workspace.colorpicker.color-tokens")
:id "opt-token-color"}]])]
[:> radio-buttons* {:selected color-style
:on-change toggle-token-color
:name "color-style"
:options [{:id "swap-opt-list"
:icon i/swatches
:label (tr "labels.color")
:value :direct-color}
{:id "swap-opt-grid"
:icon i/tokens
:label (tr "workspace.colorpicker.color-tokens")
:value :token-color}]}])]
(when (and (not= selected-mode :image)
(= color-style :direct-color))
[:button {:class (stl/css-case :picker-btn true
:selected picking-color?)
:on-click handle-click-picker}
deprecated-icon/picker])
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.colorpicker.get-color")
:aria-pressed picking-color?
:on-click handle-click-picker
:icon i/picker}])
(when (= color-style :token-color)
[:div {:class (stl/css :token-color-title)}
@@ -483,12 +485,11 @@
:aria-label (tr "media.choose-image")
:on-click on-fill-image-click}
(tr "media.choose-image")
[:& file-uploader
{:input-id "fill-image-upload"
:accept "image/jpeg,image/png"
:multi false
:ref fill-image-ref
:on-selected on-fill-image-selected}]]])
[:> file-uploader* {:input-id "fill-image-upload"
:accept "image/jpeg,image/png"
:multi false
:ref fill-image-ref
:on-selected on-fill-image-selected}]]])
[:*
[:div {:class (stl/css :colorpicker-tabs)}

View File

@@ -46,52 +46,6 @@
width: px2rem(68);
}
// TODO: change to DS button component
.picker-btn {
display: flex;
justify-content: center;
align-items: center;
border: none;
background: none;
cursor: pointer;
border-radius: $br-8;
background-color: transparent;
border: $b-1 solid transparent;
height: var(--sp-xl);
width: var(--sp-xl);
border-radius: $br-4;
padding: 0;
margin-top: var(--sp-xs);
svg {
@extend .button-icon;
stroke: var(--button-tertiary-foreground-color-rest);
}
&:hover {
svg {
stroke: var(--button-tertiary-foreground-color-focus);
}
}
&:focus,
&:focus-visible {
outline: none;
svg {
stroke: var(--button-secondary-foreground-color-hover);
}
}
&:active {
outline: none;
border: $b-1 solid transparent;
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
&.selected {
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
}
.gradient-buttons {
display: flex;
align-items: center;

View File

@@ -30,6 +30,7 @@
[app.main.ui.components.search-bar :refer [search-bar*]]
[app.main.ui.components.title-bar :refer [title-bar*]]
[app.main.ui.context :as ctx]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]]
@@ -44,12 +45,6 @@
[cuerdas.core :as str]
[rumext.v2 :as mf]))
(def ^:private close-icon
(deprecated-icon/icon-xref :close (stl/css :close-icon)))
(def ^:private add-icon
(deprecated-icon/icon-xref :add (stl/css :add-icon)))
(defn- get-library-summary
"Given a library data return a summary representation of this library"
[data]
@@ -168,12 +163,10 @@
[:div {:class (stl/css :sample-library-item)
:key (dm/str id)}
[:div {:class (stl/css :sample-library-item-name)} (:name library)]
[:input {:class (stl/css-case :sample-library-button true
:sample-library-add (nil? importing?)
:sample-library-adding (some? importing?))
:type "button"
:value (if (= importing? id) (tr "labels.adding") (tr "labels.add"))
:on-click import-library}]]))
[:> button* {:variant "secondary"
:on-click import-library
:disabled (some? importing?)}
(if (= importing? id) (tr "labels.adding") (tr "labels.add"))]]))
(defn- empty-library?
"Check if currentt library summary has elements or not"
@@ -322,14 +315,12 @@
[:> library-description* {:summary summary}]]]
(if ^boolean is-shared
[:input {:class (stl/css :item-unpublish)
:type "button"
:value (tr "common.unpublish")
:on-click unpublish}]
[:input {:class (stl/css :item-publish)
:type "button"
:value (tr "common.publish")
:on-click publish}])]
[:> button* {:variant "secondary"
:on-click unpublish}
(tr "common.unpublish")]
[:> button* {:variant "primary"
:on-click publish}
(tr "common.publish")])]
(for [{:keys [id name data connected-to connected-to-names] :as library} linked-libraries]
(let [disabled? (some #(contains? linked-libraries-ids %) connected-to)]
@@ -377,12 +368,11 @@
(let [summary (-> (:library-summary library)
(adapt-backend-summary))]
[:> library-description* {:summary summary}])]]
[:button {:class (stl/css :item-button-shared)
:data-library-id (dm/str id)
:title (tr "workspace.libraries.shared-library-btn")
:on-click link-library}
add-icon]])]
[:> icon-button* {:variant "secondary"
:aria-label (tr "workspace.libraries.shared-library-btn")
:icon i/add
:data-library-id (dm/str id)
:on-click link-library}]])]
(when (empty? shared-libraries)
[:div {:class (stl/css :section-list-empty)}
@@ -647,11 +637,13 @@
:on-click close-dialog-outside
:data-testid "libraries-modal"}
[:div {:class (stl/css :modal-dialog)}
[:button {:class (stl/css :close-btn)
:on-click close-dialog
:aria-label (tr "labels.close")
:data-testid "close-libraries"}
close-icon]
[:> icon-button* {:variant "ghost"
:class (stl/css :close-btn)
:icon i/close
:aria-label (tr "labels.close")
:data-testid "close-libraries"
:on-click close-dialog}]
[:div {:class (stl/css :modal-title)}
(tr "workspace.libraries.libraries")]

View File

@@ -33,7 +33,7 @@
background-color: var(--modal-background-color);
border: $b-2 solid var(--modal-border-color);
display: grid;
grid-template-rows: auto 1fr;
grid-template-rows: 0 auto 1fr;
min-width: $sz-364;
min-height: $sz-192;
height: $sz-520;
@@ -42,21 +42,10 @@
max-width: $sz-712;
}
// TODO: Remove this extended creating modal component
.close-btn {
@extend .modal-close-btn-base;
}
.close-icon {
display: flex;
justify-content: center;
align-items: center;
height: $sz-16;
width: $sz-16;
color: transparent;
fill: none;
stroke-width: $b-1;
stroke: var(--icon-foreground);
position: absolute;
top: var(--sp-s);
right: var(--sp-s);
}
.modal-title {
@@ -120,46 +109,6 @@
height: fit-content;
}
.item-publish,
.item-unpublish {
// TODO: remove this extended by using DS button component
@extend .button-primary;
@include t.use-typography("headline-small");
height: $sz-32;
min-width: px2rem(92);
padding: var(--sp-s) var(--sp-xxl);
margin: 0;
border-radius: $br-8;
}
.item-unpublish {
// TODO: remove this extended by using DS button component
@extend .button-secondary;
}
.item-button,
.item-button-shared {
// TODO: remove this extended by using DS button component
@extend .button-secondary;
height: $sz-32;
width: $sz-32;
margin-inline-start: var(--sp-xxs);
padding: var(--sp-s);
}
.detach-icon,
.add-icon {
display: flex;
justify-content: center;
align-items: center;
height: $sz-16;
width: $sz-16;
color: transparent;
fill: none;
stroke-width: $b-1;
stroke: var(--icon-foreground);
}
.section-list-shared {
max-height: px2rem(272);
}
@@ -170,26 +119,6 @@
color: var(--title-foreground-color);
}
.search-icon {
display: flex;
justify-content: center;
align-items: center;
width: px2rem(20);
padding: 0 0 0 var(--sp-s);
svg {
display: flex;
justify-content: center;
align-items: center;
color: transparent;
fill: none;
height: px2rem(12);
width: px2rem(12);
stroke-width: 1.33px;
stroke: var(--icon-foreground);
}
}
// empty state
.section-list-empty {
display: grid;
@@ -428,24 +357,3 @@
text-overflow: ellipsis;
max-width: px2rem(232);
}
// TODO: Remove this extended using a DS component
.sample-library-add {
@extend .button-secondary;
}
// TODO: Remove this extended using a DS component
.sample-library-adding {
@extend .button-disabled;
}
.sample-library-button {
@include t.use-typography("headline-small");
height: $sz-32;
width: px2rem(80);
margin: 0;
border-radius: $br-8;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

View File

@@ -853,8 +853,9 @@
[:*
[:> icon-button* {:variant "ghost"
:aria-pressed show-menu?
:aria-label (tr "shortcut-subsection.main-menu")
:on-click open-menu
:on-click (if show-menu? close-all-menus open-menu)
:icon i/menu}]
[:> dropdown-menu* {:show show-menu?

View File

@@ -18,9 +18,10 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.hooks :as h]
[app.main.ui.hooks.resize :as r]
[app.main.ui.icons :as deprecated-icon]
[app.main.ui.workspace.color-palette :refer [color-palette*]]
[app.main.ui.workspace.color-palette-ctx-menu :refer [color-palette-ctx-menu*]]
[app.main.ui.workspace.text-palette :refer [text-palette]]
@@ -178,27 +179,27 @@
[:ul {:class (dm/str size-classname " " (stl/css-case :palette-btn-list true
:hidden-bts hide-palettes?))}
[:li {:class (stl/css :palette-item)}
[:button {:title (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-colorpalette))
:aria-label (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-colorpalette))
:class (stl/css-case :palette-btn true
:selected color-palette?)
:on-click on-select-color-palette}
deprecated-icon/drop-icon]]
[:> icon-button* {:variant "ghost"
:aria-pressed (some? color-palette?)
:aria-label (tr "workspace.toolbar.color-palette" (sc/get-tooltip :toggle-colorpalette))
:on-click on-select-color-palette
:icon i/drop}]]
[:li {:class (stl/css :palette-item)}
[:button {:title (tr "workspace.toolbar.text-palette" (sc/get-tooltip :toggle-textpalette))
:aria-label (tr "workspace.toolbar.text-palette" (sc/get-tooltip :toggle-textpalette))
:class (stl/css-case :palette-btn true
:selected text-palette?)
:on-click on-select-text-palette}
deprecated-icon/text-palette]]]
[:> icon-button* {:variant "ghost"
:aria-pressed (some? text-palette?)
:aria-label (tr "workspace.toolbar.text-palette" (sc/get-tooltip :toggle-textpalette))
:on-click on-select-text-palette
:icon i/text-palette}]]]
(if any-palette?
[:*
[:button {:class (stl/css :palette-actions)
:on-click #(swap! state* update :show-menu not)}
deprecated-icon/menu]
[:div {:class (stl/css :menu-btn)}
[:> icon-button* {:variant "ghost"
:aria-pressed show-menu?
:aria-label (tr "labels.options")
:on-click #(swap! state* update :show-menu not)
:icon i/menu}]]
[:div {:class (stl/css :palette)
:ref container}
(when text-palette?

View File

@@ -49,7 +49,6 @@
&.wide {
width: 100%;
}
.resize-area {
grid-area: resize;
height: deprecated.$s-8;
@@ -72,49 +71,22 @@
&.small-palette {
display: flex;
}
.palette-item {
@include deprecated.flexCenter;
border-radius: deprecated.$br-8;
opacity: deprecated.$op-10;
transition: opacity 1s ease;
.palette-btn {
@extend .button-tertiary;
height: deprecated.$s-32;
width: deprecated.$s-32;
border-radius: deprecated.$br-8;
background-clip: padding-box;
padding: 0;
svg {
@extend .button-icon-small;
stroke: var(--icon-foreground);
}
&.selected {
@extend .button-icon-selected;
}
}
}
}
.palette-actions {
@extend .button-tertiary;
grid-area: actions;
height: calc(var(--height) - deprecated.$s-16);
width: deprecated.$s-32;
padding: 0;
margin-left: deprecated.$s-4;
border-radius: deprecated.$br-8;
background-color: var(--palette-background-color);
z-index: deprecated.$z-index-2;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
}
.palette {
grid-area: palette;
width: 100%;
min-width: 0;
}
.palette-item {
display: flex;
align-items: center;
}
}
.menu-btn {
display: flex;
align-items: center;
margin-left: var(--sp-s);
}
.handler {

View File

@@ -29,7 +29,7 @@
:style {:background-color color}
:src (cfg/resolve-profile-photo-url profile)}]]))
(mf/defc active-sessions
(mf/defc active-sessions*
{::mf/memo true}
[]
(let [profiles (mf/deref refs/profiles)

View File

@@ -20,23 +20,19 @@
[app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.context :as ctx]
[app.main.ui.dashboard.team]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.exports.assets :refer [progress-widget]]
[app.main.ui.exports.assets :refer [progress-widget*]]
[app.main.ui.formats :as fmt]
[app.main.ui.icons :as deprecated-icon]
[app.main.ui.workspace.presence :refer [active-sessions]]
[app.main.ui.workspace.presence :refer [active-sessions*]]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[okulary.core :as l]
[rumext.v2 :as mf]))
(def ref:persistence-status
(l/derived :status refs/persistence))
;; --- Zoom Widget
(mf/defc zoom-widget-workspace
(mf/defc zoom-widget-workspace*
{::mf/wrap [mf/memo]
::mf/wrap-props false}
[{:keys [zoom on-increase on-decrease on-zoom-reset on-zoom-fit on-zoom-selected]}]
@@ -72,11 +68,12 @@
zoom (fmt/format-percent zoom {:precision 0})]
[:*
[:div {:on-click open-dropdown
[:div {:on-click (if open? close-dropdown open-dropdown)
:class (stl/css-case :zoom-widget true
:selected open?)
:title (tr "workspace.header.zoom")}
[:span {:class (stl/css :label)} zoom]]
[:& dropdown {:show open? :on-close close-dropdown}
[:ul {:class (stl/css :dropdown)}
[:li {:class (stl/css :basic-zoom-bar)}
@@ -90,9 +87,10 @@
:aria-label (tr "shortcuts.increase-zoom")
:on-click on-increase
:icon i/add}]]
[:button {:class (stl/css :reset-btn)
:on-click on-zoom-reset}
[:> button* {:variant "ghost"
:on-click on-zoom-reset}
(tr "workspace.header.reset-zoom")]]
[:li {:class (stl/css :zoom-option)
:on-click on-zoom-fit}
(tr "workspace.header.zoom-fit-all")
@@ -100,6 +98,7 @@
(for [sc (scd/split-sc (sc/get-tooltip :fit-all))]
[:span {:class (stl/css :shortcut-key)
:key (str "zoom-fit-" sc)} sc])]]
[:li {:class (stl/css :zoom-option)
:on-click on-zoom-selected}
(tr "workspace.header.zoom-selected")
@@ -198,51 +197,43 @@
[:div {:class (stl/css :workspace-header-right)}
[:div {:class (stl/css :users-section)}
[:& active-sessions]]
[:> active-sessions*]]
[:& progress-widget]
[:> progress-widget*]
[:div {:class (stl/css :separator)}]
[:div {:class (stl/css :zoom-section)}
[:& zoom-widget-workspace
{:zoom zoom
:on-increase on-increase
:on-decrease on-decrease
:on-zoom-reset on-zoom-reset
:on-zoom-fit on-zoom-fit
:on-zoom-selected on-zoom-selected}]]
[:> zoom-widget-workspace* {:zoom zoom
:on-increase on-increase
:on-decrease on-decrease
:on-zoom-reset on-zoom-reset
:on-zoom-fit on-zoom-fit
:on-zoom-selected on-zoom-selected}]]
[:div {:class (stl/css :comments-section)}
[:button {:title (tr "workspace.toolbar.comments" (sc/get-tooltip :add-comment))
:aria-label (tr "workspace.toolbar.comments" (sc/get-tooltip :add-comment))
:class (stl/css-case :comments-btn true
:selected (= selected-drawtool :comments))
:on-click toggle-comments
:data-tool "comments"
:style {:position "relative"}}
deprecated-icon/comments
(when ^boolean has-unread-comments?
[:div {:class (stl/css :unread)}])]]
[:div {:class (stl/css :comments-button-wrapper)}
[:> icon-button* {:variant "ghost"
:aria-pressed (= selected-drawtool :comments)
:aria-label (tr "workspace.toolbar.comments" (sc/get-tooltip :add-comment))
:on-click toggle-comments
:icon i/comments}]
(when ^boolean has-unread-comments?
[:div {:class (stl/css :unread)}])]
(when-not ^boolean read-only?
[:div {:class (stl/css :history-section)}
[:button
{:title (tr "workspace.sidebar.history")
:aria-label (tr "workspace.sidebar.history")
:class (stl/css-case :selected (contains? layout :document-history)
:history-button true)
:on-click toggle-history}
deprecated-icon/history]])
[:> icon-button* {:variant "ghost"
:aria-pressed (contains? layout :document-history)
:aria-label (tr "workspace.sidebar.history")
:on-click toggle-history
:icon i/history}])
(when display-share-button?
[:a {:class (stl/css :viewer-btn)
:title (tr "workspace.header.share")
:on-click open-share-dialog}
deprecated-icon/share])
[:a {:class (stl/css :viewer-btn)
:title (tr "workspace.header.viewer" (sc/get-tooltip :open-viewer))
:on-click nav-to-viewer}
deprecated-icon/play]]))
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.header.share")
:on-click open-share-dialog
:icon i/to-corner}])
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.header.viewer" (sc/get-tooltip :open-viewer))
:on-click nav-to-viewer
:icon i/play}]]))

View File

@@ -11,8 +11,8 @@
justify-content: space-between;
align-items: center;
min-width: deprecated.$s-256;
padding: deprecated.$s-8;
gap: deprecated.$s-8;
padding: deprecated.$s-8 deprecated.$s-12;
gap: deprecated.$s-4;
background-color: var(--panel-background-color);
}
@@ -28,19 +28,14 @@
}
.zoom-widget {
@include deprecated.buttonStyle;
display: flex;
align-items: center;
justify-content: center;
height: deprecated.$s-28;
max-width: deprecated.$s-48;
width: deprecated.$s-48;
border-radius: deprecated.$br-8;
height: deprecated.$s-32;
.label {
@include deprecated.bodySmallTypography;
height: 100%;
padding: deprecated.$s-8 0;
color: var(--button-tertiary-foreground-color-rest);
}
@@ -84,13 +79,6 @@
color: var(--modal-title-foreground-color);
}
.reset-btn {
@extend .button-tertiary;
color: var(--button-tertiary-foreground-color-hover);
height: deprecated.$s-28;
border-radius: deprecated.$br-8;
}
.zoom-option {
@extend .menu-item-base;
@@ -113,127 +101,11 @@
}
}
.comments-btn {
@extend .button-tertiary;
border-radius: deprecated.$br-8;
margin: 0;
height: deprecated.$s-28;
width: deprecated.$s-28;
border: none;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
height: deprecated.$s-16;
width: deprecated.$s-16;
}
&:hover {
background-color: transparent;
border: none;
}
&.selected {
background-color: var(--button-tertiary-background-color-selected);
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
.comments-button-wrapper {
position: relative;
}
.history-button {
@extend .button-tertiary;
border-radius: deprecated.$br-8;
margin: 0;
height: deprecated.$s-28;
width: deprecated.$s-28;
border: none;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
height: deprecated.$s-16;
width: deprecated.$s-16;
}
&:hover {
background-color: transparent;
border: none;
}
&.selected {
background-color: var(--button-tertiary-background-color-selected);
svg {
stroke: var(--button-tertiary-foreground-color-active);
}
}
}
.persistence-status-widget {
@include deprecated.flexCenter;
width: deprecated.$s-28;
height: deprecated.$s-28;
}
.status-icon {
@include deprecated.flexCenter;
width: deprecated.$s-24;
height: deprecated.$s-24;
margin: 0;
border-radius: deprecated.$br-circle;
svg {
@extend .button-icon;
stroke: var(--status-widget-icon-foreground-color);
}
}
.pending-status {
background-color: var(--status-widget-background-color-warning);
}
.saving-status {
background-color: var(--status-widget-background-color-pending);
svg {
animation: spin-animation 1s infinite;
animation-timing-function: linear;
}
}
.saved-status {
background-color: var(--status-widget-background-color-success);
}
.error-status {
background-color: var(--status-widget-background-color-error);
}
.share-btn,
.viewer-btn {
@extend .button-tertiary;
border-radius: deprecated.$br-8;
margin: 0;
width: deprecated.$s-28;
height: deprecated.$s-28;
border: none;
svg {
@extend .button-icon;
height: deprecated.$s-16;
width: deprecated.$s-16;
stroke: var(--icon-foreground);
}
&:hover {
background-color: transparent;
border: none;
}
}
.unread {
.comments-button-unread {
position: absolute;
width: 8px;
height: 8px;

View File

@@ -7,7 +7,6 @@
(ns app.main.ui.workspace.shapes.text.text-edition-outline
(:require
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.main.data.helpers :as dsh]
[app.main.data.workspace.texts :as dwt]
[app.main.features :as features]
@@ -19,19 +18,14 @@
(mf/defc text-edition-outline
[{:keys [shape zoom modifiers]}]
(if (features/active-feature? @st/state "render-wasm/v1")
(let [selrect-transform (mf/deref refs/workspace-selrect)
[selrect transform] (dsh/get-selrect selrect-transform shape)
[sr-width sr-height]
(if (or (mth/close? (:width selrect) 0.01) (mth/close? (:height selrect) 0.01))
(let [{:keys [width height]} (wasm.api/get-text-dimensions (:id shape))]
[width height])
[(:width selrect) (:height selrect)])]
(let [{:keys [width height]} (wasm.api/get-text-dimensions (:id shape))
selrect-transform (mf/deref refs/workspace-selrect)
[selrect transform] (dsh/get-selrect selrect-transform shape)]
[:rect.main.viewport-selrect
{:x (:x selrect)
:y (:y selrect)
:width sr-width
:height sr-height
:width (max width (:width selrect))
:height (max height (:height selrect))
:transform transform
:style {:stroke "var(--color-accent-tertiary)"
:stroke-width (/ 1 zoom)

View File

@@ -17,8 +17,9 @@
[app.main.ui.components.context-menu-a11y :refer [context-menu*]]
[app.main.ui.components.search-bar :refer [search-bar*]]
[app.main.ui.context :as ctx]
[app.main.ui.ds.buttons.button :refer [button*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.icons :as deprecated-icon]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.workspace.sidebar.assets.common :as cmm]
[app.main.ui.workspace.sidebar.assets.file-library :refer [file-library*]]
[app.util.dom :as dom]
@@ -161,43 +162,40 @@
:id "typographies"
:handler on-section-filter-change}])]
[:article {:class (stl/css :assets-bar)}
[:article {:class (stl/css :assets-bar)}
[:div {:class (stl/css :assets-header)}
(when-not ^boolean read-only?
(if (and (= num-libs 1) (empty? components))
[:button {:class (stl/css :add-library-button)
:on-click show-libraries-dialog
:data-testid "libraries"}
[:> button* {:variant "primary"
:on-click show-libraries-dialog
:data-testid "libraries"}
(tr "workspace.assets.add-library")]
[:button {:class (stl/css :libraries-button)
:on-click show-libraries-dialog
:data-testid "libraries"}
[:> button* {:variant "secondary"
:on-click show-libraries-dialog
:data-testid "libraries"}
(tr "workspace.assets.manage-library")]))
[:div {:class (stl/css :search-wrapper)}
[:> search-bar* {:on-change on-search-term-change
:value term
:placeholder (tr "workspace.assets.search")}
[:button
{:on-click on-open-menu
:title (tr "workspace.assets.filter")
:class (stl/css-case :section-button true
:opened menu-open?)}
deprecated-icon/filter-icon]]
[:> icon-button* {:variant "secondary"
:icon i/filter
:class (stl/css :filter-button)
:aria-pressed menu-open?
:aria-label (tr "workspace.assets.filter")
:on-click on-open-menu}]]
[:> context-menu*
{:on-close on-menu-close
:selectable true
:selected section
:show menu-open?
:fixed true
:min-width true
:width size
:top 158
:left 18
:options options}]
[:> context-menu* {:on-close on-menu-close
:selectable true
:selected section
:show menu-open?
:fixed true
:min-width true
:width size
:top 158
:left 18
:options options}]
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.assets.sort")

View File

@@ -17,89 +17,14 @@
padding-top: deprecated.$s-8;
}
.libraries-button {
@extend .button-secondary;
@include deprecated.uppercaseTitleTipography;
gap: deprecated.$s-2;
height: deprecated.$s-32;
width: 100%;
margin-bottom: deprecated.$s-4;
border-radius: deprecated.$s-8;
&:hover {
background-color: var(--button-secondary-background-color-hover);
color: var(--button-secondary-foreground-color-hover);
border: deprecated.$s-1 solid var(--button-secondary-border-color-hover);
}
&:focus {
background-color: var(--button-secondary-background-color-focus);
color: var(--button-secondary-foreground-color-focus);
border: deprecated.$s-1 solid var(--button-secondary-border-color-focus);
}
.assets-header {
display: flex;
flex-direction: column;
gap: var(--sp-xxs);
}
.add-library-button {
@extend .button-primary;
@include deprecated.uppercaseTitleTipography;
gap: deprecated.$s-2;
height: deprecated.$s-32;
width: 100%;
margin-bottom: deprecated.$s-4;
border-radius: deprecated.$s-8;
}
.section-button {
@include deprecated.flexCenter;
@include deprecated.buttonStyle;
height: deprecated.$s-32;
width: deprecated.$s-32;
margin: 0;
border: deprecated.$s-1 solid var(--input-border-color-rest);
border-radius: deprecated.$br-8 deprecated.$br-2 deprecated.$br-2 deprecated.$br-8;
background-color: var(--input-background-color-rest);
svg {
height: deprecated.$s-16;
width: deprecated.$s-16;
stroke: var(--icon-foreground);
}
&:focus {
border: deprecated.$s-1 solid var(--input-border-color-focus);
outline: 0;
background-color: var(--input-background-color-focus);
color: var(--input-foreground-color-focus);
svg {
background-color: var(--input-background-color-focus);
}
}
&:hover {
border: deprecated.$s-1 solid var(--input-border-color-hover);
background-color: var(--input-background-color-hover);
svg {
background-color: var(--input-background-color-hover);
stroke: var(--button-foreground-hover);
}
&:focus {
border: deprecated.$s-1 solid var(--input-border-color-focus);
outline: 0;
background-color: var(--input-background-color-focus);
color: var(--input-foreground-color-focus);
svg {
background-color: var(--input-background-color-focus);
}
}
}
&.opened {
@extend .button-icon-selected;
}
.filter-button {
border-radius: deprecated.$br-8 0 0 deprecated.$br-8;
}
.sections-container {
@@ -125,10 +50,6 @@
border-radius: deprecated.$br-8;
}
.section-btn {
@include deprecated.buttonStyle;
}
.assets-header {
padding: 0 0 deprecated.$s-24 deprecated.$s-12;
}

View File

@@ -22,10 +22,10 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.editable-label :refer [editable-label*]]
[app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.components.file-uploader :refer [file-uploader*]]
[app.main.ui.context :as ctx]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
[app.main.ui.hooks :as h]
[app.main.ui.workspace.sidebar.assets.common :as cmm]
@@ -563,27 +563,27 @@
[:> cmm/asset-section-block* {:role :title-button}
(when ^boolean is-open
[:div
[:& radio-buttons {:selected (if is-listing-thumbs "grid" "list")
:on-change toggle-list-style
:name "listing-style"}
[:& radio-button {:icon i/view-as-list
:value "list"
:title (tr "workspace.assets.list-view")
:id "opt-list"}]
[:& radio-button {:icon i/flex-grid
:value "grid"
:title (tr "workspace.assets.grid-view")
:id "opt-grid"}]]])
[:> radio-buttons* {:selected (if is-listing-thumbs "grid" "list")
:on-change toggle-list-style
:name "listing-style"
:options [{:id "opt-list"
:icon i/view-as-list
:label (tr "workspace.assets.list-view")
:value "list"}
{:id "opt-grid"
:icon i/flex-grid
:label (tr "workspace.assets.grid-view")
:value "grid"}]}]])
(when (and (not read-only?) is-local)
[:> icon-button* {:variant "ghost"
:aria-label (tr "workspace.assets.components.add-component")
:on-click add-component
:icon i/add}
[:& file-uploader {:accept dwm/accept-image-types
:multi true
:ref input-ref
:on-selected on-file-selected}]])]
[:> file-uploader* {:accept dwm/accept-image-types
:multi true
:ref input-ref
:on-selected on-file-selected}]])]
[:> cmm/asset-section-block* {:role :content}
(when ^boolean is-open

View File

@@ -23,7 +23,7 @@
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.workspace.sidebar.assets.common :as cmm]
[app.main.ui.workspace.sidebar.assets.groups :as grp]
[app.main.ui.workspace.sidebar.options.menus.typography :refer [typography-entry]]
[app.main.ui.workspace.sidebar.options.menus.typography :refer [typography-entry*]]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[cuerdas.core :as str]
@@ -113,18 +113,17 @@
:on-drag-over dom/prevent-default
:on-drop on-drop}
[:& typography-entry
{:file-id file-id
:typography typography
:local? local?
:selected? (contains? selected typography-id)
:on-click on-asset-click
:on-change handle-change
:on-context-menu on-context-menu
:editing? editing?
:renaming? renaming?
:focus-name? rename?
:external-open* open*}]
[:> typography-entry* {:file-id file-id
:typography typography
:local? local?
:selected? (contains? selected typography-id)
:on-click on-asset-click
:on-change handle-change
:on-context-menu on-context-menu
:editing? editing?
:renaming? renaming?
:focus-name? rename?
:external-open* open*}]
(when ^boolean dragging?
[:div {:class (stl/css :dragging)}])]))

View File

@@ -291,13 +291,12 @@
:value current-search
:on-clear clear-search-text
:placeholder (tr "workspace.sidebar.layers.search")}
[:button {:on-click on-toggle-filters-click
:class (stl/css-case
:filter-button true
:opened show-menu?
:active active?)}
[:> icon* {:icon-id i/filter}]]]
[:> icon-button* {:variant "secondary"
:class (stl/css :filter-button)
:aria-pressed show-menu?
:aria-label (tr "workspace.sidebar.layers.filter")
:on-click on-toggle-filters-click
:icon i/filter}]]
[:> icon-button* {:variant "ghost"
:aria-label (tr "labels.close")
:on-click toggle-search

View File

@@ -19,39 +19,7 @@
padding: 0 deprecated.$s-12 0 deprecated.$s-8;
gap: deprecated.$s-4;
.filter-button {
@include deprecated.flexCenter;
@include deprecated.buttonStyle;
height: deprecated.$s-32;
width: deprecated.$s-32;
margin: 0;
border: deprecated.$s-1 solid var(--color-background-tertiary);
border-radius: deprecated.$br-8 deprecated.$br-2 deprecated.$br-2 deprecated.$br-8;
background-color: var(--color-background-tertiary);
svg {
height: deprecated.$s-16;
width: deprecated.$s-16;
stroke: var(--icon-foreground);
}
&:focus {
border: deprecated.$s-1 solid var(--input-border-color-focus);
outline: 0;
background-color: var(--input-background-color-active);
color: var(--input-foreground-color-active);
svg {
background-color: var(--input-background-color-active);
}
}
&:hover {
border: deprecated.$s-1 solid var(--input-border-color-hover);
background-color: var(--input-background-color-hover);
svg {
background-color: var(--input-background-color-hover);
stroke: var(--button-foreground-hover);
}
}
&.opened {
@extend .button-icon-selected;
}
border-radius: deprecated.$br-8 0 0 deprecated.$br-8;
}
}
}
@@ -143,7 +111,7 @@
.filters-container {
@extend .menu-dropdown;
position: absolute;
left: deprecated.$s-20;
left: deprecated.$s-16;
width: deprecated.$s-192;
.filter-menu-item {
@include deprecated.bodySmallTypography;

View File

@@ -12,7 +12,7 @@
[app.main.data.workspace.drawing :as dwd]
[app.main.store :as st]
[app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.icons :as deprecated-icon]
[app.util.dom :as dom]
@@ -95,15 +95,15 @@
(when preset-match
[:span {:class (stl/css :check-icon)} deprecated-icon/tick])])))]]]
[:& radio-buttons {:selected (or (d/name orientation) "")
:on-change on-orientation-change
:name "frame-orientation"
:wide true
:class (stl/css :radio-buttons)}
[:& radio-button {:icon i/size-vertical
:value "vertical"
:id "size-vertical"}]
[:& radio-button {:icon i/size-horizontal
:value "horizontal"
:id "size-horizontal"}]]]))
[:> radio-buttons* {:class (stl/css :radio-buttons)
:selected (or (d/name orientation) "")
:on-change on-orientation-change
:name "frame-orientation"
:options [{:id "size-vertical"
:icon i/size-vertical
:label (tr "workspace.options.orientation.vertical")
:value "vertical"}
{:id "size-horizontal"
:icon i/size-horizontal
:label (tr "workspace.options.orientation.horizontal")
:value "horizontal"}]}]]))

View File

@@ -10,7 +10,8 @@
[app.main.data.workspace :as dw]
[app.main.data.workspace.shortcuts :as sc]
[app.main.store :as st]
[app.main.ui.icons :as deprecated-icon]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf]))
@@ -42,68 +43,59 @@
(when-not (and disabled-align disabled-distribute)
[:div {:class (stl/css :align-options)}
[:div {:class (stl/css :align-group-horizontal)}
[:button {:class (stl/css-case :align-button true
:disabled disabled-align)
:disabled disabled-align
:title (tr "workspace.align.hleft" (sc/get-tooltip :align-left))
:data-value "hleft"
:on-click align-objects}
deprecated-icon/align-left]
[:> icon-button* {:variant "ghost"
:icon i/align-left
:aria-label (tr "workspace.align.hleft" (sc/get-tooltip :align-left))
:on-click align-objects
:data-value "hleft"
:disabled disabled-align}]
[:button {:class (stl/css-case :align-button true
:disabled disabled-align)
:disabled disabled-align
:title (tr "workspace.align.hcenter" (sc/get-tooltip :align-hcenter))
:data-value "hcenter"
:on-click align-objects}
deprecated-icon/align-horizontal-center]
[:> icon-button* {:variant "ghost"
:icon i/align-horizontal-center
:aria-label (tr "workspace.align.hcenter" (sc/get-tooltip :align-hcenter))
:on-click align-objects
:data-value "hcenter"
:disabled disabled-align}]
[:button {:class (stl/css-case :align-button true
:disabled disabled-align)
:disabled disabled-align
:title (tr "workspace.align.hright" (sc/get-tooltip :align-right))
:data-value "hright"
:on-click align-objects}
deprecated-icon/align-right]
[:> icon-button* {:variant "ghost"
:icon i/align-right
:aria-label (tr "workspace.align.hright" (sc/get-tooltip :align-right))
:on-click align-objects
:data-value "hright"
:disabled disabled-align}]
[:button {:class (stl/css-case :align-button true
:disabled disabled-distribute)
:disabled disabled-distribute
:title (tr "workspace.align.hdistribute" (sc/get-tooltip :h-distribute))
:data-value "horizontal"
:on-click distribute-objects}
deprecated-icon/distribute-horizontally]]
[:> icon-button* {:variant "ghost"
:icon i/distribute-horizontally
:aria-label (tr "workspace.align.hdistribute" (sc/get-tooltip :h-distribute))
:on-click distribute-objects
:data-value "horizontal"
:disabled disabled-distribute}]]
[:div {:class (stl/css :align-group-vertical)}
[:button {:class (stl/css-case :align-button true
:disabled disabled-align)
:disabled disabled-align
:title (tr "workspace.align.vtop" (sc/get-tooltip :align-top))
:data-value "vtop"
:on-click align-objects}
deprecated-icon/align-top]
[:> icon-button* {:variant "ghost"
:icon i/align-top
:aria-label (tr "workspace.align.vtop" (sc/get-tooltip :align-top))
:on-click align-objects
:data-value "vtop"
:disabled disabled-align}]
[:button {:class (stl/css-case :align-button true
:disabled disabled-align)
:disabled disabled-align
:title (tr "workspace.align.vcenter" (sc/get-tooltip :align-vcenter))
:data-value "vcenter"
:on-click align-objects}
deprecated-icon/align-vertical-center]
[:> icon-button* {:variant "ghost"
:icon i/align-vertical-center
:aria-label (tr "workspace.align.vcenter" (sc/get-tooltip :align-vcenter))
:on-click align-objects
:data-value "vcenter"
:disabled disabled-align}]
[:button {:class (stl/css-case :align-button true
:disabled disabled-align)
:disabled disabled-align
:title (tr "workspace.align.vbottom" (sc/get-tooltip :align-bottom))
:data-value "vbottom"
:on-click align-objects}
deprecated-icon/align-bottom]
[:button {:title (tr "workspace.align.vdistribute" (sc/get-tooltip :v-distribute))
:class (stl/css-case :align-button true
:disabled disabled-distribute)
:disabled disabled-distribute
:data-value "vertical"
:on-click distribute-objects}
deprecated-icon/distribute-vertical-spacing]]])))
[:> icon-button* {:variant "ghost"
:icon i/align-bottom
:aria-label (tr "workspace.align.vbottom" (sc/get-tooltip :align-bottom))
:on-click align-objects
:data-value "vbottom"
:disabled disabled-align}]
[:> icon-button* {:variant "ghost"
:icon i/distribute-vertical-spacing
:aria-label (tr "workspace.align.vdistribute" (sc/get-tooltip :v-distribute))
:on-click distribute-objects
:data-value "vertical"
:disabled disabled-distribute}]]])))

View File

@@ -4,12 +4,10 @@
//
// Copyright (c) KALEIDOS INC
@use "refactor/common-refactor.scss" as deprecated;
@use "../../../sidebar/common/sidebar.scss" as sidebar;
.align-options {
@include sidebar.option-grid-structure;
height: deprecated.$s-32;
}
.align-group-horizontal,
.align-group-vertical {
@@ -26,27 +24,3 @@
.align-group-vertical {
grid-column: 5 / span 4;
}
.align-button {
@extend .button-tertiary;
height: deprecated.$s-32;
width: deprecated.$s-32;
padding: 0;
border-radius: deprecated.$br-8;
svg {
@extend .button-icon;
stroke: var(--icon-foreground);
}
&.disabled {
cursor: default;
svg {
stroke: var(--button-foreground-color-disabled);
}
&:hover {
background-color: var(--panel-background-color);
svg {
stroke: var(--button-foreground-color-disabled);
}
}
}
}

View File

@@ -15,7 +15,6 @@
[app.main.ui.components.title-bar :refer [title-bar*]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.icons :as deprecated-icon]
[app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf]))
@@ -103,10 +102,12 @@
[:div {:class (stl/css-case :first-row true
:hidden hidden?)}
[:div {:class (stl/css :blur-info)}
[:button {:class (stl/css-case :show-more true
:selected more-options?)
:on-click toggle-more-options}
deprecated-icon/menu]
[:> icon-button* {:variant "secondary"
:class (stl/css :show-more)
:aria-label (tr "labels.options")
:aria-pressed more-options?
:on-click toggle-more-options
:icon i/menu}]
[:span {:class (stl/css :label)}
(tr "workspace.options.blur-options.title")]]
[:div {:class (stl/css :actions)}

View File

@@ -37,21 +37,7 @@
border-radius: deprecated.$br-8;
background-color: var(--input-details-color);
.show-more {
@extend .button-secondary;
height: deprecated.$s-32;
width: deprecated.$s-28;
border-radius: deprecated.$br-8 0 0 deprecated.$br-8;
box-sizing: border-box;
border: deprecated.$s-1 solid var(--button-secondary-background-color-rest);
svg {
@extend .button-icon;
}
&.selected {
background-color: var(--button-radio-background-color-active);
svg {
stroke: var(--button-radio-foreground-color-active);
}
}
}
.label {
@include deprecated.bodySmallTypography;

View File

@@ -15,15 +15,12 @@
[app.main.data.workspace.shortcuts :as sc]
[app.main.features :as features]
[app.main.store :as st]
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.radio-buttons :refer [radio-buttons*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.icons :as deprecated-icon]
[app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf]))
(def ^:private flatten-icon
(deprecated-icon/icon-xref :boolean-flatten (stl/css :flatten-icon)))
(mf/defc bool-options*
[{:keys [total-selected shapes shapes-with-children]}]
(let [head (first shapes)
@@ -70,41 +67,40 @@
(st/emit! (dwb/change-bool-type head-id bool-type)))))))
flatten-objects
(mf/use-fn #(st/emit! (dwps/convert-selected-to-path)))]
(mf/use-fn
#(st/emit! (dwps/convert-selected-to-path)))]
(when (not (and disabled-bool-btns disabled-flatten))
[:div {:class (stl/css :boolean-options)}
[:div {:class (stl/css :bool-group)}
[:& radio-buttons {:selected (d/name head-bool-type)
:class (stl/css :boolean-radio-btn)
:on-change on-change
:name "bool-options"}
[:& radio-button {:icon i/boolean-union
:value "union"
:disabled disabled-bool-btns
:title (str (tr "workspace.shape.menu.union") " (" (sc/get-tooltip :bool-union) ")")
:id "bool-opt-union"}]
[:& radio-button {:icon i/boolean-difference
:value "difference"
:disabled disabled-bool-btns
:title (str (tr "workspace.shape.menu.difference") " (" (sc/get-tooltip :bool-difference) ")")
:id "bool-opt-differente"}]
[:& radio-button {:icon i/boolean-intersection
:value "intersection"
:disabled disabled-bool-btns
:title (str (tr "workspace.shape.menu.intersection") " (" (sc/get-tooltip :bool-intersection) ")")
:id "bool-opt-intersection"}]
[:& radio-button {:icon i/boolean-exclude
:value "exclude"
:disabled disabled-bool-btns
:title (str (tr "workspace.shape.menu.exclude") " (" (sc/get-tooltip :bool-exclude) ")")
:id "bool-opt-exclude"}]]]
[:div {:class (stl/css :boolean-group)}
[:> radio-buttons* {:class (stl/css :boolean-radio-btn)
:variant "ghost"
:selected (d/name head-bool-type)
:on-change on-change
:name "bool-options"
:options [{:id "bool-opt-union"
:icon i/boolean-union
:label (str (tr "workspace.shape.menu.union") " (" (sc/get-tooltip :bool-union) ")")
:value "union"
:disabled disabled-bool-btns}
{:id "bool-opt-differente"
:icon i/boolean-difference
:label (str (tr "workspace.shape.menu.difference") " (" (sc/get-tooltip :bool-difference) ")")
:value "difference"
:disabled disabled-bool-btns}
{:id "bool-opt-intersection"
:icon i/boolean-intersection
:label (str (tr "workspace.shape.menu.intersection") " (" (sc/get-tooltip :bool-intersection) ")")
:value "intersection"
:disabled disabled-bool-btns}
{:id "bool-opt-exclude"
:icon i/boolean-exclude
:label (str (tr "workspace.shape.menu.exclude") " (" (sc/get-tooltip :bool-exclude) ")")
:value "exclude"
:disabled disabled-bool-btns}]}]]
[:button
{:title (tr "workspace.shape.menu.flatten")
:class (stl/css-case
:flatten-button true
:disabled disabled-flatten)
:disabled disabled-flatten
:on-click flatten-objects}
flatten-icon]])))
[:> icon-button* {:variant "ghost"
:icon i/boolean-flatten
:aria-label (tr "workspace.shape.menu.flatten")
:on-click flatten-objects
:disabled disabled-flatten}]])))

View File

@@ -4,45 +4,18 @@
//
// Copyright (c) KALEIDOS INC
@use "refactor/common-refactor.scss" as deprecated;
@use "../../../sidebar/common/sidebar.scss" as sidebar;
.boolean-options {
@include sidebar.option-grid-structure;
height: var(--sp-xxxl);
}
.bool-group {
.boolean-group {
display: grid;
grid-template-columns: subgrid;
grid-column: 1 / span 4;
}
.flatten-button {
@extend .button-tertiary;
height: deprecated.$s-32;
width: deprecated.$s-32;
border-radius: deprecated.$br-8;
grid-column: 5 / span 1;
--flatten-icon-foreground-color: var(--icon-foreground);
&.disabled {
cursor: default;
--flatten-icon-foreground-color: var(--button-foreground-color-disabled);
&:hover {
background-color: var(--panel-background-color);
--flatten-icon-foreground-color: var(--button-foreground-color-disabled);
}
}
}
.flatten-icon {
@extend .button-icon;
stroke: var(--flatten-icon-foreground-color);
}
.boolean-radio-btn {
background-color: transparent;
gap: var(--sp-xs);
}

View File

@@ -333,9 +333,9 @@
:on-change on-radius-r3-change
:value (:r3 values)}]]]))
[:> icon-button* {:class (stl/css-case :selected radius-expanded)
:variant "ghost"
[:> icon-button* {:variant "ghost"
:on-click toggle-radius-mode
:aria-pressed radius-expanded
:aria-label (if radius-expanded
(tr "workspace.options.radius.hide-all-corners")
(tr "workspace.options.radius.show-single-corners"))

View File

@@ -36,12 +36,6 @@
color: var(--color-accent-primary);
}
.selected {
border-color: var(--button-icon-border-color-selected);
background-color: var(--button-icon-background-color-selected);
color: var(--button-icon-foreground-color-selected);
}
.icon {
margin-inline: var(--sp-xs);
}

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