Merge remote-tracking branch 'origin/staging' into develop
138
CHANGES.md
|
@ -1,36 +1,136 @@
|
|||
# CHANGELOG
|
||||
|
||||
## :rocket: Next
|
||||
## 2.0.0 - I Just Can't Get Enough
|
||||
|
||||
### :rocket: Epics and highlights
|
||||
- Grid CSS layout [Taiga #4915](https://tree.taiga.io/project/penpot/epic/4915)
|
||||
- UI redesign [Taiga #4958](https://tree.taiga.io/project/penpot/epic/4958)
|
||||
- New components System [Taiga #2662](https://tree.taiga.io/project/penpot/epic/2662)
|
||||
- Swap components [Taiga #1331](https://tree.taiga.io/project/penpot/us/1331)
|
||||
- Images as fill [Taiga #2983](https://tree.taiga.io/project/penpot/us/2983)
|
||||
- HTML code generation [Taiga #5277](https://tree.taiga.io/project/penpot/us/5277)
|
||||
- Light and dark themes [Taiga #2287](https://tree.taiga.io/project/penpot/us/2287)
|
||||
|
||||
### :boom: Breaking changes & Deprecations
|
||||
|
||||
### :sparkles: New features
|
||||
- New strokes default to inside border [Taiga #6847](https://tree.taiga.io/project/penpot/issue/6847)
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
### :arrow_up: Deps updates
|
||||
|
||||
### :heart: Community contributions by (Thank you!)
|
||||
|
||||
## 1.20.0
|
||||
|
||||
### :boom: Breaking changes & Deprecations
|
||||
### :heart: Community contributions (Thank you!)
|
||||
- New Hausa, Yoruba and Igbo translations and update translation files (by All For Tech Empowerment Foundation) [Taiga #6950](https://tree.taiga.io/project/penpot/us/6950), [Taiga #6534](https://tree.taiga.io/project/penpot/us/6534)
|
||||
- Hide bounding-box when editing shape (by @VasilevsVV) [#3930](https://github.com/penpot/penpot/pull/3930)
|
||||
- CTRL + "+" to zoom into canvas instead of browser (by @audriu) [#3848](https://github.com/penpot/penpot/pull/3848)
|
||||
- Add dev deps.edn in the project root (by @PEZ) [#3794](https://github.com/penpot/penpot/pull/3794)
|
||||
- Allow passing overrides to frontend nginx config (by @m90) [#3602](https://github.com/penpot/penpot/pull/3602)
|
||||
- Update index.njk to remove typo (by @fdvmoreira) [#155](https://github.com/penpot/penpot-docs/pull/155)
|
||||
- Typo (by StephanEggermont) [#157](https://github.com/penpot/penpot-docs/pull/157)
|
||||
|
||||
### :sparkles: New features
|
||||
|
||||
- Send comments with Ctrl+Enter / Cmd + Enter [Taiga #6085](https://tree.taiga.io/project/penpot/issue/6085)
|
||||
- Select through stroke only rectangle [Taiga #5484](https://tree.taiga.io/project/penpot/issue/5484)
|
||||
- Stroke default position [Taiga #6847](https://tree.taiga.io/project/penpot/issue/6847)
|
||||
- Override browser Ctrl+ and Ctrl- zoom with Penpot Zoom [Taiga #3200](https://tree.taiga.io/project/penpot/us/3200)
|
||||
- Reduce handlers for the flex layout gaps and paddings
|
||||
- Improve the way handlers work on flex layouts [Taiga #6598](https://tree.taiga.io/project/penpot/us/6598)
|
||||
- Add menu entry for toggle between light/dark theme [Taiga #6829](https://tree.taiga.io/project/penpot/issue/6829)
|
||||
- Switch themes shortcut [Taiga #6644](https://tree.taiga.io/project/penpot/us/6644)
|
||||
- Constraints section at design tab new position [Taiga #6830](https://tree.taiga.io/project/penpot/issue/6830)
|
||||
- [PICKER] File library colors order [Taiga #5399](https://tree.taiga.io/project/penpot/us/5399)
|
||||
- Onboarding invitations improvements [Taiga #5974](https://tree.taiga.io/project/penpot/us/5974)
|
||||
- [PERFORMANCE] Workspace thumbnails refactor [Taiga #5828](https://tree.taiga.io/project/penpot/us/5828)
|
||||
- [PERFORMANCE] Add performance optimizations to shape rendering [Taiga #5835](https://tree.taiga.io/project/penpot/us/5835)
|
||||
- [PERFORMANCE] Optimize SVG output [Taiga #4134](https://tree.taiga.io/project/penpot/us/4134)
|
||||
- [PERFORMANCE] Optimize svg on importation [Taiga #5879](https://tree.taiga.io/project/penpot/us/5879)
|
||||
- [PERFORMANCE] Optimization tasks related to design tab file [Taiga #5760](https://tree.taiga.io/project/penpot/us/5760)
|
||||
- [INSTALL] Ability to setup features by team [Taiga #6108](https://tree.taiga.io/project/penpot/us/6108)
|
||||
- [IMAGES] Keep aspect ratio option [Taiga #6933](https://tree.taiga.io/project/penpot/us/6933)
|
||||
- [INSPECT] UI review [Taiga #5687](https://tree.taiga.io/project/penpot/us/5687)
|
||||
- [GRID LAYOUT] Phase 1 [Taiga #4303](https://tree.taiga.io/project/penpot/us/4303)
|
||||
- [GRID LAYOUT] Inspect code for Grid [Taiga #5277](https://tree.taiga.io/project/penpot/us/5277)
|
||||
- [GRID LAYOUT] Phase 1 polishing [Taiga #5612](https://tree.taiga.io/project/penpot/us/5612)
|
||||
- [GRID LAYOUT] Improvements & Feedback [Taiga #6047](https://tree.taiga.io/project/penpot/us/6047)
|
||||
- [COMPONENTS] Naming of the main component [Taiga #5291](https://tree.taiga.io/project/penpot/us/5291)
|
||||
- [COMPONENTS] Rework inside of components - Library page [Taiga #2918](https://tree.taiga.io/project/penpot/us/2918)
|
||||
- [COMPONENTS] Update component when updating main instance [Taiga #3794](https://tree.taiga.io/project/penpot/us/3794)
|
||||
- [COMPONENTS] Main component new behavior [Taiga #3796](https://tree.taiga.io/project/penpot/us/3796)
|
||||
- [COMPONENTS] Main component look & feel [Taiga #5290](https://tree.taiga.io/project/penpot/us/5290)
|
||||
- [COMPONENTS] Library view [Taiga #2880](https://tree.taiga.io/project/penpot/us/2880)
|
||||
- [COMPONENTS] Positioning inside a component should relative, as in boards [Taiga #2826](https://tree.taiga.io/project/penpot/us/2826)
|
||||
- [COMPONENTS] Update message should show only if affecting at components that are being used at a file [Taiga #1397](https://tree.taiga.io/project/penpot/us/1397)
|
||||
- [COMPONENTS] Annotations [Taiga #4957](https://tree.taiga.io/project/penpot/us/4957)
|
||||
- [COMPONENTS] Synchronization order for nested components [Taiga #5439](https://tree.taiga.io/project/penpot/us/5439)
|
||||
- [COMPONENTS] Libraries modal zero case [Taiga #5294](https://tree.taiga.io/project/penpot/us/5294)
|
||||
- [COMPONENTS] Contextual menu casuistics [Taiga #5292](https://tree.taiga.io/project/penpot/us/5292)
|
||||
- [COMPONENTS] Libraries publishing flow review [Taiga #5293](https://tree.taiga.io/project/penpot/us/5293)
|
||||
- [COMPONENTS] Add loading text to Libraries modal [Taiga #6702](https://tree.taiga.io/project/penpot/us/6702)
|
||||
- [COMPONENTS] Components rename and organization in bulk [Taiga #2877](https://tree.taiga.io/project/penpot/us/2877)
|
||||
- [COMPONENTS] Info overlay about components V2 [Taiga #6276](https://tree.taiga.io/project/penpot/us/6276)
|
||||
- [REDESIGN] New styles basics [Taiga #4967](https://tree.taiga.io/project/penpot/us/4967)
|
||||
- [REDESIGN] Layers tab redesign [Taiga #4966](https://tree.taiga.io/project/penpot/us/4966)
|
||||
- [REDESIGN] Design tab phase 1 [Taiga #4982](https://tree.taiga.io/project/penpot/us/4966)
|
||||
- [REDESIGN] Assets tab redesign [Taiga #4984](https://tree.taiga.io/project/penpot/us/4984)
|
||||
- [REDESIGN] Palette panels (colors, typographies...) [Taiga #4983](https://tree.taiga.io/project/penpot/us/4983)
|
||||
- [REDESIGN] Workspace structure [Taiga #4988](https://tree.taiga.io/project/penpot/us/4988)
|
||||
- [REDESIGN] Shortcut tab [Taiga #4989](https://tree.taiga.io/project/penpot/us/4989)
|
||||
- [REDESIGN] Toolbar [Taiga #5500](https://tree.taiga.io/project/penpot/us/5500)
|
||||
- [REDESIGN] History tab [Taiga #5481](https://tree.taiga.io/project/penpot/us/5481)
|
||||
- [REDESIGN] Path options/toolbar [Taiga #5815](https://tree.taiga.io/project/penpot/us/5815)
|
||||
- [REDESIGN] Design tab phase 2 [Taiga #5814](https://tree.taiga.io/project/penpot/us/5814)
|
||||
- [REDESIGN] Design tab phase 3 and dashboard details [Taiga #5920](https://tree.taiga.io/project/penpot/us/5920)
|
||||
- [REDESIGN] Dashboard [Taiga #5164](https://tree.taiga.io/project/penpot/us/5164)
|
||||
- [REDESIGN] New Dashboard UI [Taiga #5869](https://tree.taiga.io/project/penpot/us/5869)
|
||||
- [REDESIGN] Prototype tab [Taiga #4985](https://tree.taiga.io/project/penpot/us/4985)
|
||||
- [REDESIGN] Code tab [Taiga #4986](https://tree.taiga.io/project/penpot/us/4986)
|
||||
- [REDESIGN] Modals and alert messages [Taiga #5915](https://tree.taiga.io/project/penpot/us/5915)
|
||||
- [REDESIGN] Comments page [Taiga #5917](https://tree.taiga.io/project/penpot/us/5917)
|
||||
- [REDESIGN] View Mode [Taiga #5163](https://tree.taiga.io/project/penpot/us/5163)
|
||||
- [REDESIGN] Miscellaneous tasks [Taiga #6050](https://tree.taiga.io/project/penpot/us/6050)
|
||||
- [REDESIGN] Swap components [Taiga #6739](https://tree.taiga.io/project/penpot/us/6739)
|
||||
- [REDESIGN] Font selector [Taiga #6677](https://tree.taiga.io/project/penpot/us/6677)
|
||||
- [REDESIGN] Colour system of alerts and notifications [Taiga #6746](https://tree.taiga.io/project/penpot/us/6746)
|
||||
- [REDESIGN] Review text in paragraphs for accessibility [Taiga #6703](https://tree.taiga.io/project/penpot/us/6703)
|
||||
- [REDESIGN] Interaction icons [Taiga #6880](https://tree.taiga.io/project/penpot/us/6880)
|
||||
- [REDESIGN] Panels visual separations [Taiga #6692](https://tree.taiga.io/project/penpot/us/6692)
|
||||
- [REDESIGN] Onboarding slides [Taiga #6678](https://tree.taiga.io/project/penpot/us/6678)
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Fix pixelated thumbnails [Github #3681](https://github.com/penpot/penpot/issues/3681) [Github #3661](https://github.com/penpot/penpot/issues/3661)
|
||||
### :bug Bugs fixed
|
||||
- Fix pixelated thumbnails [Github #3681](https://github.com/penpot/penpot/issues/3681), [Github #3661](https://github.com/penpot/penpot/issues/3661)
|
||||
- Fix problem with not applying colors to boards [Github #3941](https://github.com/penpot/penpot/issues/3941)
|
||||
- Fix problem with path editor undoing changes [Github #3998](https://github.com/penpot/penpot/issues/3998)
|
||||
- [View mode] Open overlay places frame in the wrong position when paired with a fixed element [Taiga #6385](https://tree.taiga.io/project/penpot/issue/6385)
|
||||
- Flex Layout: Fit-content not recalculated after deleting an element [Taiga #5968](https://tree.taiga.io/project/penpot/issue/5968)
|
||||
- Selecting from Color Palette does not work for board when there is no existing fill [Taiga #6464](https://tree.taiga.io/project/penpot/issue/6464)
|
||||
- Color thumbnails are consistently rounded in the inspect code mode [Taiga #5886](https://tree.taiga.io/project/penpot/issue/5886)
|
||||
- Adding vector path points before first point of existing open path not working [Taiga #6593](https://tree.taiga.io/project/penpot/issue/6593)
|
||||
- Some image formats include the extension when importing [Taiga #5485](https://tree.taiga.io/project/penpot/issue/5485)
|
||||
- Gradient color tool doesn't work properly with flipped items [Taiga #6485](https://tree.taiga.io/project/penpot/issue/6485)
|
||||
- [TEXT] Align options are not shown when several text are selected [Taiga #5948](https://tree.taiga.io/project/penpot/issue/5948)
|
||||
- [VIEW MODE] Comments not working properly on multiple pages [Taiga #6281](https://tree.taiga.io/project/penpot/issue/6281)
|
||||
- [PERFORMANCE] Alignments are slow [Taiga #5865](https://tree.taiga.io/project/penpot/issue/5865)
|
||||
- [EXPORT] Exporting an element with a non-visible drop shadow displays the shadow either way [Taiga #6768](https://tree.taiga.io/project/penpot/issue/6768)
|
||||
- [SAFARI] Color picker cursor is not pointing correctly [Taiga #6733](https://tree.taiga.io/project/penpot/issue/6733)
|
||||
- [Import Files] When user has imported .penpot file with new file name of previously downloaded library file the default library file name is set for it [Taiga #5596](https://tree.taiga.io/project/penpot/issue/5596)
|
||||
- Issue when resizing a duotone FA icon [Taiga #5935](https://tree.taiga.io/project/penpot/issue/5935)
|
||||
- "Hide grid" keyboard shortcut broken [Taiga #5102](https://tree.taiga.io/project/penpot/issue/5102)
|
||||
- Picking a gradient color in recent colors for a new color in the assets tab crashes Penpot [Taiga #5601](https://tree.taiga.io/project/penpot/issue/5601)
|
||||
- Thumbnails not loading [Taiga #6012](https://tree.taiga.io/project/penpot/issue/6012)
|
||||
- Don't show signup link/form when registration is disabled. [Taiga #1196](https://tree.taiga.io/project/penpot/issue/1196)
|
||||
- Registration Page UI UX issue with small resolutions [Taiga #1693](https://tree.taiga.io/project/penpot/issue/1693)
|
||||
- [LOGIN] "E-Mail-Adress" input field is set to type 'text' instead of 'eMail [Taiga #1921](https://tree.taiga.io/project/penpot/issue/1921)
|
||||
- Handling correctly slashes "/" in emails [Taiga #4906](https://tree.taiga.io/project/penpot/issue/4906)
|
||||
- Tab character in texts crashes the app [Taiga #4418](https://tree.taiga.io/project/penpot/issue/4418)
|
||||
- Text does not match export [Taiga #4129](https://tree.taiga.io/project/penpot/issue/4129)
|
||||
- Scrollbars cover the layers carets [Taiga #4431](https://tree.taiga.io/project/penpot/issue/4431)
|
||||
- Horizontal ruler disappear when overlapping a board [Taiga #4138](https://tree.taiga.io/project/penpot/issue/4138)
|
||||
- Resize shape + Alt key is not working [Taiga #3447](https://tree.taiga.io/project/penpot/issue/3447)
|
||||
- Libraries images broken on premise [Taiga #4573](https://tree.taiga.io/project/penpot/issue/4573)
|
||||
- [VIEWER] Cannot scroll down in code </> mode [Taiga #4655](https://tree.taiga.io/project/penpot/issue/4655)
|
||||
- Strange cursor behavior after clicking viewport with text tool [Taiga #4363](https://tree.taiga.io/project/penpot/issue/4363)
|
||||
- Selected color affects all of them [Taiga #5285](https://tree.taiga.io/project/penpot/issue/5285)
|
||||
- Fix problem with shadow negative spread [Github #3421](https://github.com/penpot/penpot/issues/3421)
|
||||
- Fix problem with linked colors to strokes [Github #3522](https://github.com/penpot/penpot/issues/3522)
|
||||
- Fix problem with hand tool stuck [Github #3318](https://github.com/penpot/penpot/issues/3318)
|
||||
- Fix problem with fix scrolling on nested elements [Github #3508](https://github.com/penpot/penpot/issues/3508)
|
||||
- Fix problem when changing typography assets [Github #3683](https://github.com/penpot/penpot/issues/3683)
|
||||
|
||||
### :arrow_up: Deps updates
|
||||
|
||||
### :heart: Community contributions by (Thank you!)
|
||||
|
||||
## 1.19.5
|
||||
|
||||
|
|
|
@ -37,6 +37,13 @@
|
|||
|
||||
<h2>GENERAL NOTES</h2>
|
||||
|
||||
<h3>HTTP Transport & Methods</h3>
|
||||
<p>The HTTP is the transport method for accesing this API; all
|
||||
functions can be called using POST HTTP method; the functions
|
||||
that starts with <b>get-</b> in the name, can use GET HTTP
|
||||
method which in many cases benefits from the HTTP cache.</p>
|
||||
|
||||
|
||||
<h3>Authentication</h3>
|
||||
<p>The penpot backend right now offers two way for authenticate the request:
|
||||
<b>cookies</b> (the same mechanism that we use ourselves on accessing the API from the
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
[app.loggers.audit :as audit]
|
||||
[app.main :as-alias main]
|
||||
[app.rpc.commands.profile :as profile]
|
||||
[app.setup :as-alias setup]
|
||||
[app.tokens :as tokens]
|
||||
[app.util.json :as json]
|
||||
[app.util.time :as dt]
|
||||
|
@ -37,7 +38,7 @@
|
|||
;; HELPERS
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn- obfuscate-string
|
||||
(defn obfuscate-string
|
||||
[s]
|
||||
(if (< (count s) 10)
|
||||
(apply str (take (count s) (repeat "*")))
|
||||
|
@ -413,7 +414,7 @@
|
|||
::props]))
|
||||
|
||||
(defn get-info
|
||||
[{:keys [provider ::main/props] :as cfg} {:keys [params] :as request}]
|
||||
[{:keys [provider ::setup/props] :as cfg} {:keys [params] :as request}]
|
||||
(when-let [error (get params :error)]
|
||||
(ex/raise :type :internal
|
||||
:code :error-on-retrieving-code
|
||||
|
@ -508,7 +509,7 @@
|
|||
(if profile
|
||||
(let [sxf (session/create-fn cfg (:id profile))
|
||||
token (or (:invitation-token info)
|
||||
(tokens/generate (::main/props cfg)
|
||||
(tokens/generate (::setup/props cfg)
|
||||
{:iss :auth
|
||||
:exp (dt/in-future "15m")
|
||||
:profile-id (:id profile)}))
|
||||
|
@ -536,7 +537,7 @@
|
|||
:iss :prepared-register
|
||||
:is-active true
|
||||
:exp (dt/in-future {:hours 48}))
|
||||
token (tokens/generate (::main/props cfg) info)
|
||||
token (tokens/generate (::setup/props cfg) info)
|
||||
params (d/without-nils
|
||||
{:token token
|
||||
:fullname (:fullname info)})
|
||||
|
@ -551,7 +552,7 @@
|
|||
(defn- auth-handler
|
||||
[cfg {:keys [params] :as request}]
|
||||
(let [props (audit/extract-utm-params params)
|
||||
state (tokens/generate (::main/props cfg)
|
||||
state (tokens/generate (::setup/props cfg)
|
||||
{:iss :oauth
|
||||
:invitation-token (:invitation-token params)
|
||||
:props props
|
||||
|
@ -618,7 +619,7 @@
|
|||
[_]
|
||||
(s/keys :req [::session/manager
|
||||
::http/client
|
||||
::main/props
|
||||
::setup/props
|
||||
::db/pool
|
||||
::providers]))
|
||||
|
||||
|
|
|
@ -277,7 +277,7 @@
|
|||
(update :fill-color-ref-file lookup-index)
|
||||
|
||||
;; This covers the old shapes and the new :strokes
|
||||
(uuid? (:storage-color-ref-file form))
|
||||
(uuid? (:stroke-color-ref-file form))
|
||||
(update :stroke-color-ref-file lookup-index)
|
||||
|
||||
;; This covers all text shapes that have typography referenced
|
||||
|
|
|
@ -806,7 +806,8 @@
|
|||
:width (:width (:selrect root-shape))
|
||||
:height (:height (:selrect root-shape))
|
||||
:name (:name component)
|
||||
:shapes [new-id]})
|
||||
:shapes [new-id]
|
||||
:show-content true})
|
||||
(assoc :frame-id nil
|
||||
:parent-id nil))
|
||||
root-shape' (assoc root-shape
|
||||
|
@ -846,13 +847,15 @@
|
|||
|
||||
(fix-shape [shape]
|
||||
(if (or (nil? (:parent-id shape)) (ctk/instance-head? shape))
|
||||
(assoc shape
|
||||
:type :frame ; Old groups must be converted
|
||||
:fills (or (:fills shape) []) ; to frames and conform to spec
|
||||
:shapes (or (:shapes shape) [])
|
||||
:hide-in-viewer (or (:hide-in-viewer shape) true)
|
||||
:rx (or (:rx shape) 0)
|
||||
:ry (or (:ry shape) 0))
|
||||
(let [frame? (= :frame (:type shape))]
|
||||
(assoc shape
|
||||
:type :frame ; Old groups must be converted
|
||||
:fills (or (:fills shape) []) ; to frames and conform to spec
|
||||
:shapes (or (:shapes shape) [])
|
||||
:hide-in-viewer (if frame? (boolean (:hide-in-viewer shape)) true)
|
||||
:show-content (if frame? (boolean (:show-content shape)) true)
|
||||
:rx (or (:rx shape) 0)
|
||||
:ry (or (:ry shape) 0)))
|
||||
shape))]
|
||||
(-> file-data
|
||||
(update :pages-index update-vals fix-container)
|
||||
|
@ -1089,7 +1092,12 @@
|
|||
(let [shapes (cfh/get-children-with-self (:objects component)
|
||||
(:id component))
|
||||
|
||||
root-shape (first shapes)
|
||||
;; Let's calculate the top shame name from the components path and name
|
||||
root-shape (-> (first shapes)
|
||||
(assoc :name (cfh/merge-path-item (:path component) (:name component))))
|
||||
|
||||
shapes (assoc shapes 0 root-shape)
|
||||
|
||||
orig-pos (gpt/point (:x root-shape) (:y root-shape))
|
||||
delta (gpt/subtract position orig-pos)
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
[app.metrics :as mtx]
|
||||
[app.rpc :as-alias rpc]
|
||||
[app.rpc.doc :as-alias rpc.doc]
|
||||
[app.setup :as-alias setup]
|
||||
[clojure.spec.alpha :as s]
|
||||
[integrant.core :as ig]
|
||||
[promesa.exec :as px]
|
||||
|
@ -136,7 +137,7 @@
|
|||
::rpc/routes
|
||||
::rpc.doc/routes
|
||||
::oidc/routes
|
||||
::main/props
|
||||
::setup/props
|
||||
::assets/routes
|
||||
::debug/routes
|
||||
::db/pool
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
[app.config :as cf]
|
||||
[app.db :as db]
|
||||
[app.main :as-alias main]
|
||||
[app.setup :as-alias setup]
|
||||
[app.tokens :as tokens]
|
||||
[ring.request :as rreq]))
|
||||
|
||||
|
@ -42,7 +43,7 @@
|
|||
(defn- wrap-soft-auth
|
||||
"Soft Authentication, will be executed synchronously on the undertow
|
||||
worker thread."
|
||||
[handler {:keys [::main/props]}]
|
||||
[handler {:keys [::setup/props]}]
|
||||
(letfn [(handle-request [request]
|
||||
(try
|
||||
(let [token (get-token request)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
[app.db.sql :as sql]
|
||||
[app.http.client :as http]
|
||||
[app.main :as-alias main]
|
||||
[app.setup :as-alias setup]
|
||||
[app.tokens :as tokens]
|
||||
[app.worker :as-alias wrk]
|
||||
[clojure.spec.alpha :as s]
|
||||
|
@ -30,7 +31,7 @@
|
|||
|
||||
(defmethod ig/pre-init-spec ::routes [_]
|
||||
(s/keys :req [::http/client
|
||||
::main/props
|
||||
::setup/props
|
||||
::db/pool]))
|
||||
|
||||
(defmethod ig/init-key ::routes
|
||||
|
@ -106,7 +107,7 @@
|
|||
[cfg headers]
|
||||
(let [tdata (get headers "x-penpot-data")]
|
||||
(when-not (str/empty? tdata)
|
||||
(let [result (tokens/verify (::main/props cfg) {:token tdata :iss :profile-identity})]
|
||||
(let [result (tokens/verify (::setup/props cfg) {:token tdata :iss :profile-identity})]
|
||||
(:profile-id result)))))
|
||||
|
||||
(defn- parse-notification
|
||||
|
|
|
@ -55,8 +55,8 @@
|
|||
convention."
|
||||
([cfg-or-client request]
|
||||
(let [client (resolve-client cfg-or-client)]
|
||||
(send! client request {})))
|
||||
(send! client request {:sync? true})))
|
||||
([cfg-or-client request options]
|
||||
(let [client (resolve-client cfg-or-client)]
|
||||
(send! client request options))))
|
||||
(send! client request (merge {:sync? true} options)))))
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
[app.rpc.commands.auth :as auth]
|
||||
[app.rpc.commands.files-create :refer [create-file]]
|
||||
[app.rpc.commands.profile :as profile]
|
||||
[app.setup :as-alias setup]
|
||||
[app.srepl.helpers :as srepl]
|
||||
[app.storage :as-alias sto]
|
||||
[app.storage.tmp :as tmp]
|
||||
|
@ -340,7 +341,7 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn- resend-email-notification
|
||||
[{:keys [::db/pool ::main/props] :as cfg} {:keys [params] :as request}]
|
||||
[{:keys [::db/pool ::setup/props] :as cfg} {:keys [params] :as request}]
|
||||
|
||||
(when-not (contains? params :force)
|
||||
(ex/raise :type :validation
|
||||
|
|
|
@ -60,8 +60,12 @@
|
|||
|
||||
(defmethod handle-error :restriction
|
||||
[err _ _]
|
||||
{::rres/status 400
|
||||
::rres/body (ex-data err)})
|
||||
(let [{:keys [code] :as data} (ex-data err)]
|
||||
(if (= code :method-not-allowed)
|
||||
{::rres/status 405
|
||||
::rres/body data}
|
||||
{::rres/status 400
|
||||
::rres/body data})))
|
||||
|
||||
(defmethod handle-error :rate-limit
|
||||
[err _ _]
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[app.db.sql :as sql]
|
||||
[app.http.session.tasks :as-alias tasks]
|
||||
[app.main :as-alias main]
|
||||
[app.setup :as-alias setup]
|
||||
[app.tokens :as tokens]
|
||||
[app.util.time :as dt]
|
||||
[clojure.spec.alpha :as s]
|
||||
|
@ -138,7 +139,7 @@
|
|||
(declare ^:private gen-token)
|
||||
|
||||
(defn create-fn
|
||||
[{:keys [::manager ::main/props]} profile-id]
|
||||
[{:keys [::manager ::setup/props]} profile-id]
|
||||
(us/assert! ::manager manager)
|
||||
(us/assert! ::us/uuid profile-id)
|
||||
|
||||
|
@ -196,7 +197,7 @@
|
|||
(neg? (compare default-renewal-max-age elapsed)))))
|
||||
|
||||
(defn- wrap-soft-auth
|
||||
[handler {:keys [::manager ::main/props]}]
|
||||
[handler {:keys [::manager ::setup/props]}]
|
||||
(us/assert! ::manager manager)
|
||||
(letfn [(handle-request [request]
|
||||
(try
|
||||
|
@ -248,6 +249,7 @@
|
|||
renewal (dt/plus created-at default-renewal-max-age)
|
||||
expires (dt/plus created-at max-age)
|
||||
secure? (contains? cf/flags :secure-session-cookies)
|
||||
strict? (contains? cf/flags :strict-session-cookies)
|
||||
cors? (contains? cf/flags :cors)
|
||||
name (cf/get :auth-token-cookie-name default-auth-token-cookie-name)
|
||||
comment (str "Renewal at: " (dt/format-instant renewal :rfc1123))
|
||||
|
@ -256,7 +258,7 @@
|
|||
:expires expires
|
||||
:value token
|
||||
:comment comment
|
||||
:same-site (if cors? :none :lax)
|
||||
:same-site (if cors? :none (if strict? :strict :lax))
|
||||
:secure secure?}]
|
||||
(update response :cookies assoc name cookie)))
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
[app.main :as-alias main]
|
||||
[app.rpc :as-alias rpc]
|
||||
[app.rpc.retry :as rtry]
|
||||
[app.setup :as-alias setup]
|
||||
[app.tokens :as tokens]
|
||||
[app.util.services :as-alias sv]
|
||||
[app.util.time :as dt]
|
||||
|
@ -261,7 +262,7 @@
|
|||
(s/def ::tasks/uri ::us/string)
|
||||
|
||||
(defmethod ig/pre-init-spec ::tasks/archive-task [_]
|
||||
(s/keys :req [::db/pool ::main/props ::http.client/client]))
|
||||
(s/keys :req [::db/pool ::setup/props ::http.client/client]))
|
||||
|
||||
(defmethod ig/init-key ::tasks/archive
|
||||
[_ cfg]
|
||||
|
@ -287,7 +288,7 @@
|
|||
(px/sleep 100)
|
||||
(recur (+ total ^long n)))
|
||||
(when (pos? total)
|
||||
(l/debug :hint "events archived" :total total)))))))))
|
||||
(l/dbg :hint "events archived" :total total)))))))))
|
||||
|
||||
(def ^:private sql:retrieve-batch-of-audit-log
|
||||
"select *
|
||||
|
@ -322,7 +323,7 @@
|
|||
:context]))
|
||||
|
||||
(send [events]
|
||||
(let [token (tokens/generate (::main/props cfg)
|
||||
(let [token (tokens/generate (::setup/props cfg)
|
||||
{:iss "authentication"
|
||||
:iat (dt/now)
|
||||
:uid uuid/zero})
|
||||
|
@ -331,11 +332,11 @@
|
|||
"origin" (cf/get :public-uri)
|
||||
"cookie" (u/map->query-string {:auth-token token})}
|
||||
params {:uri uri
|
||||
:timeout 6000
|
||||
:timeout 12000
|
||||
:method :post
|
||||
:headers headers
|
||||
:body body}
|
||||
resp (http.client/req! cfg params {:sync? true})]
|
||||
resp (http.client/req! cfg params)]
|
||||
(if (= (:status resp) 204)
|
||||
true
|
||||
(do
|
||||
|
@ -355,7 +356,7 @@
|
|||
(map row->event))
|
||||
events (into [] xform rows)]
|
||||
(when-not (empty? events)
|
||||
(l/trace :hint "archive events chunk" :uri uri :events (count events))
|
||||
(l/trc :hint "archive events chunk" :uri uri :events (count events))
|
||||
(when (send events)
|
||||
(mark-as-archived conn rows)
|
||||
(count events)))))))
|
||||
|
|
|
@ -221,7 +221,7 @@
|
|||
{::db/pool (ig/ref ::db/pool)}
|
||||
|
||||
::http.awsns/routes
|
||||
{::props (ig/ref ::setup/props)
|
||||
{::setup/props (ig/ref ::setup/props)
|
||||
::db/pool (ig/ref ::db/pool)
|
||||
::http.client/client (ig/ref ::http.client/client)}
|
||||
|
||||
|
@ -262,7 +262,7 @@
|
|||
::oidc/routes
|
||||
{::http.client/client (ig/ref ::http.client/client)
|
||||
::db/pool (ig/ref ::db/pool)
|
||||
::props (ig/ref ::setup/props)
|
||||
::setup/props (ig/ref ::setup/props)
|
||||
::oidc/providers {:google (ig/ref ::oidc.providers/google)
|
||||
:github (ig/ref ::oidc.providers/github)
|
||||
:gitlab (ig/ref ::oidc.providers/gitlab)
|
||||
|
@ -274,7 +274,7 @@
|
|||
::db/pool (ig/ref ::db/pool)
|
||||
::rpc/routes (ig/ref ::rpc/routes)
|
||||
::rpc.doc/routes (ig/ref ::rpc.doc/routes)
|
||||
::props (ig/ref ::setup/props)
|
||||
::setup/props (ig/ref ::setup/props)
|
||||
::mtx/routes (ig/ref ::mtx/routes)
|
||||
::oidc/routes (ig/ref ::oidc/routes)
|
||||
::http.debug/routes (ig/ref ::http.debug/routes)
|
||||
|
@ -286,7 +286,7 @@
|
|||
{::db/pool (ig/ref ::db/pool)
|
||||
::session/manager (ig/ref ::session/manager)
|
||||
::sto/storage (ig/ref ::sto/storage)
|
||||
::props (ig/ref ::setup/props)}
|
||||
::setup/props (ig/ref ::setup/props)}
|
||||
|
||||
::http.ws/routes
|
||||
{::db/pool (ig/ref ::db/pool)
|
||||
|
@ -322,7 +322,7 @@
|
|||
::rpc/climit (ig/ref ::rpc/climit)
|
||||
::rpc/rlimit (ig/ref ::rpc/rlimit)
|
||||
::setup/templates (ig/ref ::setup/templates)
|
||||
::props (ig/ref ::setup/props)}
|
||||
::setup/props (ig/ref ::setup/props)}
|
||||
|
||||
:app.rpc.doc/routes
|
||||
{:methods (ig/ref :app.rpc/methods)}
|
||||
|
@ -331,7 +331,7 @@
|
|||
{::rpc/methods (ig/ref :app.rpc/methods)
|
||||
::db/pool (ig/ref ::db/pool)
|
||||
::session/manager (ig/ref ::session/manager)
|
||||
::props (ig/ref ::setup/props)}
|
||||
::setup/props (ig/ref ::setup/props)}
|
||||
|
||||
::wrk/registry
|
||||
{::mtx/metrics (ig/ref ::mtx/metrics)
|
||||
|
@ -388,7 +388,7 @@
|
|||
:app.tasks.telemetry/handler
|
||||
{::db/pool (ig/ref ::db/pool)
|
||||
::http.client/client (ig/ref ::http.client/client)
|
||||
::props (ig/ref ::setup/props)}
|
||||
::setup/props (ig/ref ::setup/props)}
|
||||
|
||||
[::srepl/urepl ::srepl/server]
|
||||
{::srepl/port (cf/get :urepl-port 6062)
|
||||
|
@ -402,7 +402,7 @@
|
|||
|
||||
::setup/props
|
||||
{::db/pool (ig/ref ::db/pool)
|
||||
::key (cf/get :secret-key)
|
||||
::setup/key (cf/get :secret-key)
|
||||
|
||||
;; NOTE: this dependency is only necessary for proper initialization ordering, props
|
||||
;; module requires the migrations to run before initialize.
|
||||
|
@ -412,7 +412,7 @@
|
|||
{}
|
||||
|
||||
::audit.tasks/archive
|
||||
{::props (ig/ref ::setup/props)
|
||||
{::setup/props (ig/ref ::setup/props)
|
||||
::db/pool (ig/ref ::db/pool)
|
||||
::http.client/client (ig/ref ::http.client/client)}
|
||||
|
||||
|
|
|
@ -27,10 +27,12 @@
|
|||
[app.rpc.helpers :as rph]
|
||||
[app.rpc.retry :as retry]
|
||||
[app.rpc.rlimit :as rlimit]
|
||||
[app.setup :as-alias setup]
|
||||
[app.storage :as-alias sto]
|
||||
[app.util.services :as sv]
|
||||
[app.util.time :as dt]
|
||||
[clojure.spec.alpha :as s]
|
||||
[cuerdas.core :as str]
|
||||
[integrant.core :as ig]
|
||||
[promesa.core :as p]
|
||||
[ring.request :as rreq]
|
||||
|
@ -71,24 +73,31 @@
|
|||
(defn- rpc-handler
|
||||
"Ring handler that dispatches cmd requests and convert between
|
||||
internal async flow into ring async flow."
|
||||
[methods {:keys [params path-params] :as request}]
|
||||
(let [type (keyword (:type path-params))
|
||||
etag (rreq/get-header request "if-none-match")
|
||||
profile-id (or (::session/profile-id request)
|
||||
(::actoken/profile-id request))
|
||||
[methods {:keys [params path-params method] :as request}]
|
||||
(let [handler-name (:type path-params)
|
||||
etag (rreq/get-header request "if-none-match")
|
||||
profile-id (or (::session/profile-id request)
|
||||
(::actoken/profile-id request))
|
||||
|
||||
data (-> params
|
||||
(assoc ::request-at (dt/now))
|
||||
(assoc ::session/id (::session/id request))
|
||||
(assoc ::cond/key etag)
|
||||
(cond-> (uuid? profile-id)
|
||||
(assoc ::profile-id profile-id)))
|
||||
data (-> params
|
||||
(assoc ::request-at (dt/now))
|
||||
(assoc ::session/id (::session/id request))
|
||||
(assoc ::cond/key etag)
|
||||
(cond-> (uuid? profile-id)
|
||||
(assoc ::profile-id profile-id)))
|
||||
|
||||
data (vary-meta data assoc ::http/request request)
|
||||
method (get methods type default-handler)]
|
||||
data (vary-meta data assoc ::http/request request)
|
||||
handler-fn (get methods (keyword handler-name) default-handler)]
|
||||
|
||||
(when (and (or (= method :get)
|
||||
(= method :head))
|
||||
(not (str/starts-with? handler-name "get-")))
|
||||
(ex/raise :type :restriction
|
||||
:code :method-not-allowed
|
||||
:hint "method not allowed for this request"))
|
||||
|
||||
(binding [cond/*enabled* true]
|
||||
(let [response (method data)]
|
||||
(let [response (handler-fn data)]
|
||||
(handle-response request response)))))
|
||||
|
||||
(defn- wrap-metrics
|
||||
|
@ -240,7 +249,7 @@
|
|||
::ldap/provider
|
||||
::sto/storage
|
||||
::mtx/metrics
|
||||
::main/props]
|
||||
::setup/props]
|
||||
:opt [::climit
|
||||
::rlimit]))
|
||||
|
||||
|
@ -257,7 +266,7 @@
|
|||
(defmethod ig/pre-init-spec ::routes [_]
|
||||
(s/keys :req [::methods
|
||||
::db/pool
|
||||
::main/props
|
||||
::setup/props
|
||||
::session/manager]))
|
||||
|
||||
(defmethod ig/init-key ::routes
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
[app.rpc :as-alias rpc]
|
||||
[app.rpc.doc :as-alias doc]
|
||||
[app.rpc.quotes :as quotes]
|
||||
[app.setup :as-alias setup]
|
||||
[app.tokens :as tokens]
|
||||
[app.util.services :as sv]
|
||||
[app.util.time :as dt]
|
||||
|
@ -23,7 +24,7 @@
|
|||
(dissoc row :perms))
|
||||
|
||||
(defn create-access-token
|
||||
[{:keys [::db/conn ::main/props]} profile-id name expiration]
|
||||
[{:keys [::db/conn ::setup/props]} profile-id name expiration]
|
||||
(let [created-at (dt/now)
|
||||
token-id (uuid/next)
|
||||
token (tokens/generate props {:iss "access-token"
|
||||
|
@ -47,7 +48,7 @@
|
|||
[{:keys [::db/pool] :as system} profile-id name expiration]
|
||||
(db/with-atomic [conn pool]
|
||||
(let [props (:app.setup/props system)]
|
||||
(create-access-token {::db/conn conn ::main/props props}
|
||||
(create-access-token {::db/conn conn ::setup/props props}
|
||||
profile-id
|
||||
name
|
||||
expiration))))
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
[app.rpc.commands.teams :as teams]
|
||||
[app.rpc.doc :as-alias doc]
|
||||
[app.rpc.helpers :as rph]
|
||||
[app.setup :as-alias setup]
|
||||
[app.tokens :as tokens]
|
||||
[app.util.services :as sv]
|
||||
[app.util.time :as dt]
|
||||
|
@ -88,7 +89,7 @@
|
|||
(profile/strip-private-attrs))
|
||||
|
||||
invitation (when-let [token (:invitation-token params)]
|
||||
(tokens/verify (::main/props cfg) {:token token :iss :team-invitation}))
|
||||
(tokens/verify (::setup/props cfg) {:token token :iss :team-invitation}))
|
||||
|
||||
;; If invitation member-id does not matches the profile-id, we just proceed to ignore the
|
||||
;; invitation because invitations matches exactly; and user can't login with other email and
|
||||
|
@ -133,7 +134,7 @@
|
|||
(defn recover-profile
|
||||
[{:keys [::db/pool] :as cfg} {:keys [token password]}]
|
||||
(letfn [(validate-token [token]
|
||||
(let [tdata (tokens/verify (::main/props cfg) {:token token :iss :password-recovery})]
|
||||
(let [tdata (tokens/verify (::setup/props cfg) {:token token :iss :password-recovery})]
|
||||
(:profile-id tdata)))
|
||||
|
||||
(update-password [conn profile-id]
|
||||
|
@ -170,7 +171,7 @@
|
|||
:code :registration-disabled)))
|
||||
|
||||
(when (contains? params :invitation-token)
|
||||
(let [invitation (tokens/verify (::main/props cfg) {:token (:invitation-token params) :iss :team-invitation})]
|
||||
(let [invitation (tokens/verify (::setup/props cfg) {:token (:invitation-token params) :iss :team-invitation})]
|
||||
(when-not (= (:email params) (:member-email invitation))
|
||||
(ex/raise :type :restriction
|
||||
:code :email-does-not-match-invitation
|
||||
|
@ -233,7 +234,7 @@
|
|||
|
||||
params (d/without-nils params)
|
||||
|
||||
token (tokens/generate (::main/props cfg) params)]
|
||||
token (tokens/generate (::setup/props cfg) params)]
|
||||
(with-meta {:token token}
|
||||
{::audit/profile-id uuid/zero})))
|
||||
|
||||
|
@ -340,7 +341,7 @@
|
|||
|
||||
(defn register-profile
|
||||
[{:keys [::db/conn] :as cfg} {:keys [token fullname] :as params}]
|
||||
(let [claims (tokens/verify (::main/props cfg) {:token token :iss :prepared-register})
|
||||
(let [claims (tokens/verify (::setup/props cfg) {:token token :iss :prepared-register})
|
||||
params (-> claims
|
||||
(into params)
|
||||
(assoc :fullname fullname))
|
||||
|
@ -357,7 +358,7 @@
|
|||
(create-profile-rels! conn))))
|
||||
|
||||
invitation (when-let [token (:invitation-token params)]
|
||||
(tokens/verify (::main/props cfg) {:token token :iss :team-invitation}))]
|
||||
(tokens/verify (::setup/props cfg) {:token token :iss :team-invitation}))]
|
||||
|
||||
;; If profile is filled in claims, means it tries to register
|
||||
;; again, so we proceed to update the modified-at attr
|
||||
|
@ -377,7 +378,7 @@
|
|||
;; email.
|
||||
(and (some? invitation) (= (:email profile) (:member-email invitation)))
|
||||
(let [claims (assoc invitation :member-id (:id profile))
|
||||
token (tokens/generate (::main/props cfg) claims)
|
||||
token (tokens/generate (::setup/props cfg) claims)
|
||||
resp {:invitation-token token}]
|
||||
(-> resp
|
||||
(rph/with-transform (session/create-fn cfg (:id profile)))
|
||||
|
@ -404,7 +405,7 @@
|
|||
;; In all other cases, send a verification email.
|
||||
:else
|
||||
(do
|
||||
(send-email-verification! conn (::main/props cfg) profile)
|
||||
(send-email-verification! conn (::setup/props cfg) profile)
|
||||
(rph/with-meta profile
|
||||
{::audit/replace-props (audit/profile->props profile)
|
||||
::audit/profile-id (:id profile)})))))
|
||||
|
@ -429,14 +430,14 @@
|
|||
(defn request-profile-recovery
|
||||
[{:keys [::db/pool] :as cfg} {:keys [email] :as params}]
|
||||
(letfn [(create-recovery-token [{:keys [id] :as profile}]
|
||||
(let [token (tokens/generate (::main/props cfg)
|
||||
(let [token (tokens/generate (::setup/props cfg)
|
||||
{:iss :password-recovery
|
||||
:exp (dt/in-future "15m")
|
||||
:profile-id id})]
|
||||
(assoc profile :token token)))
|
||||
|
||||
(send-email-notification [conn profile]
|
||||
(let [ptoken (tokens/generate (::main/props cfg)
|
||||
(let [ptoken (tokens/generate (::setup/props cfg)
|
||||
{:iss :profile-identity
|
||||
:profile-id (:id profile)
|
||||
:exp (dt/in-future {:days 30})})]
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
[app.rpc.commands.profile :as profile]
|
||||
[app.rpc.doc :as-alias doc]
|
||||
[app.rpc.helpers :as rph]
|
||||
[app.setup :as-alias setup]
|
||||
[app.tokens :as tokens]
|
||||
[app.util.services :as sv]
|
||||
[clojure.spec.alpha :as s]))
|
||||
|
@ -40,7 +41,7 @@
|
|||
{::rpc/auth false
|
||||
::doc/added "1.15"
|
||||
::doc/module :auth}
|
||||
[{:keys [::main/props ::ldap/provider] :as cfg} params]
|
||||
[{:keys [::setup/props ::ldap/provider] :as cfg} params]
|
||||
(when-not provider
|
||||
(ex/raise :type :restriction
|
||||
:code :ldap-not-initialized
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
[app.rpc.climit :as climit]
|
||||
[app.rpc.doc :as-alias doc]
|
||||
[app.rpc.helpers :as rph]
|
||||
[app.setup :as-alias setup]
|
||||
[app.storage :as sto]
|
||||
[app.tokens :as tokens]
|
||||
[app.util.services :as sv]
|
||||
|
@ -296,12 +297,12 @@
|
|||
|
||||
(defn- request-email-change!
|
||||
[{:keys [::conn] :as cfg} {:keys [profile email] :as params}]
|
||||
(let [token (tokens/generate (::main/props cfg)
|
||||
(let [token (tokens/generate (::setup/props cfg)
|
||||
{:iss :change-email
|
||||
:exp (dt/in-future "15m")
|
||||
:profile-id (:id profile)
|
||||
:email email})
|
||||
ptoken (tokens/generate (::main/props cfg)
|
||||
ptoken (tokens/generate (::setup/props cfg)
|
||||
{:iss :profile-identity
|
||||
:profile-id (:id profile)
|
||||
:exp (dt/in-future {:days 30})})]
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
[app.rpc.helpers :as rph]
|
||||
[app.rpc.permissions :as perms]
|
||||
[app.rpc.quotes :as quotes]
|
||||
[app.setup :as-alias setup]
|
||||
[app.storage :as sto]
|
||||
[app.tokens :as tokens]
|
||||
[app.util.services :as sv]
|
||||
|
@ -691,7 +692,7 @@
|
|||
|
||||
(defn- create-invitation-token
|
||||
[cfg {:keys [profile-id valid-until team-id member-id member-email role]}]
|
||||
(tokens/generate (::main/props cfg)
|
||||
(tokens/generate (::setup/props cfg)
|
||||
{:iss :team-invitation
|
||||
:exp valid-until
|
||||
:profile-id profile-id
|
||||
|
@ -702,7 +703,7 @@
|
|||
|
||||
(defn- create-profile-identity-token
|
||||
[cfg profile]
|
||||
(tokens/generate (::main/props cfg)
|
||||
(tokens/generate (::setup/props cfg)
|
||||
{:iss :profile-identity
|
||||
:profile-id (:id profile)
|
||||
:exp (dt/in-future {:days 30})}))
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
[app.rpc.doc :as-alias doc]
|
||||
[app.rpc.helpers :as rph]
|
||||
[app.rpc.quotes :as quotes]
|
||||
[app.setup :as-alias setup]
|
||||
[app.tokens :as tokens]
|
||||
[app.tokens.spec.team-invitation :as-alias spec.team-invitation]
|
||||
[app.util.services :as sv]
|
||||
|
@ -38,7 +39,7 @@
|
|||
::doc/module :auth}
|
||||
[{:keys [::db/pool] :as cfg} {:keys [token] :as params}]
|
||||
(db/with-atomic [conn pool]
|
||||
(let [claims (tokens/verify (::main/props cfg) {:token token})
|
||||
(let [claims (tokens/verify (::setup/props cfg) {:token token})
|
||||
cfg (assoc cfg :conn conn)]
|
||||
(process-token cfg params claims))))
|
||||
|
||||
|
|
|
@ -50,16 +50,15 @@
|
|||
:cause cause))))
|
||||
instance-id)))
|
||||
|
||||
(s/def ::main/key ::us/string)
|
||||
(s/def ::main/props
|
||||
(s/map-of ::us/keyword some?))
|
||||
(s/def ::key ::us/string)
|
||||
(s/def ::props (s/map-of ::us/keyword some?))
|
||||
|
||||
(defmethod ig/pre-init-spec ::props [_]
|
||||
(s/keys :req [::db/pool]
|
||||
:opt [::main/key]))
|
||||
:opt [::key]))
|
||||
|
||||
(defmethod ig/init-key ::props
|
||||
[_ {:keys [::db/pool ::main/key] :as cfg}]
|
||||
[_ {:keys [::db/pool ::key] :as cfg}]
|
||||
(db/with-atomic [conn pool]
|
||||
(db/xact-lock! conn 0)
|
||||
(when-not key
|
||||
|
|
|
@ -10,10 +10,15 @@
|
|||
(:require
|
||||
[app.binfile.common :as bfc]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.changes :as cpc]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.files.repair :as cfr]
|
||||
[app.common.files.validate :as cfv]
|
||||
[app.common.logging :as l]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.db :as db]
|
||||
[app.features.fdata :as feat.fdata]
|
||||
|
@ -133,4 +138,102 @@
|
|||
(fn [touched]
|
||||
(disj touched :shapes-group))))]
|
||||
file (-> file
|
||||
(update :data fix-fdata))))
|
||||
(update :data fix-fdata))))
|
||||
|
||||
(defn add-swap-slots
|
||||
[file libs _opts]
|
||||
;; Detect swapped copies and try to generate a valid swap-slot.
|
||||
(letfn [(process-fdata [data]
|
||||
;; Walk through all containers in the file, both pages and deleted components.
|
||||
(reduce process-container data (ctf/object-containers-seq data)))
|
||||
|
||||
(process-container [data container]
|
||||
;; Walk through all shapes in depth-first tree order.
|
||||
(l/dbg :hint "Processing container" :type (:type container) :name (:name container))
|
||||
(let [root-shape (ctn/get-container-root container)]
|
||||
(ctf/update-container data
|
||||
container
|
||||
#(reduce process-shape % (ctn/get-direct-children container root-shape)))))
|
||||
|
||||
(process-shape [container shape]
|
||||
;; Look for head copies in the first level (either component roots or inside main components).
|
||||
;; Even if they have been swapped, we don't add slot to them because there is no way to know
|
||||
;; the original shape. Only children.
|
||||
(if (and (ctk/instance-head? shape)
|
||||
(ctk/in-component-copy? shape)
|
||||
(nil? (ctk/get-swap-slot shape)))
|
||||
(process-copy-head container shape)
|
||||
(reduce process-shape container (ctn/get-direct-children container shape))))
|
||||
|
||||
(process-copy-head [container head-shape]
|
||||
;; Process recursively all children, comparing each one with the corresponding child in the main
|
||||
;; component, looking by position. If the shape-ref does not point to the found child, then it has
|
||||
;; been swapped and need to set up a slot.
|
||||
(l/trc :hint "Processing copy-head" :id (:id head-shape) :name (:name head-shape))
|
||||
(let [component-shape (ctf/find-ref-shape file container libs head-shape :include-deleted? true :with-context? true)
|
||||
component-container (:container (meta component-shape))]
|
||||
(loop [container container
|
||||
children (map #(ctn/get-shape container %) (:shapes head-shape))
|
||||
component-children (map #(ctn/get-shape component-container %) (:shapes component-shape))]
|
||||
(let [child (first children)
|
||||
component-child (first component-children)]
|
||||
(if (or (nil? child) (nil? component-child))
|
||||
container
|
||||
(let [container (if (and (not (ctk/is-main-of? component-child child))
|
||||
(nil? (ctk/get-swap-slot child))
|
||||
(ctk/instance-head? child))
|
||||
(let [slot (guess-swap-slot component-child component-container)]
|
||||
(l/dbg :hint "child" :id (:id child) :name (:name child) :slot slot)
|
||||
(ctn/update-shape container (:id child)
|
||||
#(update % :touched
|
||||
cfh/set-touched-group
|
||||
(ctk/build-swap-slot-group slot))))
|
||||
container)]
|
||||
(recur (process-copy-head container child)
|
||||
(rest children)
|
||||
(rest component-children))))))))
|
||||
|
||||
(guess-swap-slot [shape container]
|
||||
;; To guess the slot, we must follow the chain until we find the definitive main. But
|
||||
;; we cannot navigate by shape-ref, because main shapes may also have been swapped. So
|
||||
;; chain by position, too.
|
||||
(if-let [slot (ctk/get-swap-slot shape)]
|
||||
slot
|
||||
(if-not (ctk/in-component-copy? shape)
|
||||
(:id shape)
|
||||
(let [head-copy (ctn/get-component-shape (:objects container) shape)]
|
||||
(if (= (:id head-copy) (:id shape))
|
||||
(:id shape)
|
||||
(let [head-main (ctf/find-ref-shape file
|
||||
container
|
||||
libs
|
||||
head-copy
|
||||
:include-deleted? true
|
||||
:with-context? true)
|
||||
container-main (:container (meta head-main))
|
||||
shape-main (find-match-by-position shape
|
||||
head-copy
|
||||
container
|
||||
head-main
|
||||
container-main)]
|
||||
(guess-swap-slot shape-main container-main)))))))
|
||||
|
||||
(find-match-by-position [shape-copy head-copy container-copy head-main container-main]
|
||||
;; Find the shape in the main that has the same position under its parent than
|
||||
;; the copy under its one. To get the parent we must process recursively until
|
||||
;; the component head, because mains may also have been swapped.
|
||||
(let [parent-copy (ctn/get-shape container-copy (:parent-id shape-copy))
|
||||
parent-main (if (= (:id parent-copy) (:id head-copy))
|
||||
head-main
|
||||
(find-match-by-position parent-copy
|
||||
head-copy
|
||||
container-copy
|
||||
head-main
|
||||
container-main))
|
||||
index (cfh/get-position-on-parent (:objects container-copy)
|
||||
(:id shape-copy))
|
||||
shape-main-id (dm/get-in parent-main [:shapes index])]
|
||||
(ctn/get-shape container-main shape-main-id)))]
|
||||
|
||||
file (-> file
|
||||
(update :data process-fdata))))
|
||||
|
|
|
@ -378,11 +378,11 @@
|
|||
(defn process-file!
|
||||
"Apply a function to the file. Optionally save the changes or not.
|
||||
The function receives the decoded and migrated file data."
|
||||
[file-id update-fn & {:keys [rollback?] :or {rollback? true}}]
|
||||
[file-id update-fn & {:keys [rollback?] :or {rollback? true} :as opts}]
|
||||
(db/tx-run! (assoc main/system ::db/rollback rollback?)
|
||||
(fn [system]
|
||||
(binding [h/*system* system]
|
||||
(h/process-file! system file-id update-fn)))))
|
||||
(h/process-file! system file-id update-fn opts)))))
|
||||
|
||||
(defn process-team-files!
|
||||
"Apply a function to each file of the specified team."
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
[app.db :as db]
|
||||
[app.http.client :as http]
|
||||
[app.main :as-alias main]
|
||||
[app.setup :as-alias setup]
|
||||
[app.util.json :as json]
|
||||
[clojure.spec.alpha :as s]
|
||||
[integrant.core :as ig]
|
||||
|
@ -32,13 +33,14 @@
|
|||
(defmethod ig/pre-init-spec ::handler [_]
|
||||
(s/keys :req [::http/client
|
||||
::db/pool
|
||||
::main/props]))
|
||||
::setup/props]))
|
||||
|
||||
(defmethod ig/init-key ::handler
|
||||
[_ {:keys [::db/pool ::main/props] :as cfg}]
|
||||
[_ {:keys [::db/pool ::setup/props] :as cfg}]
|
||||
(fn [{:keys [send? enabled?] :or {send? true enabled? false}}]
|
||||
(let [subs {:newsletter-updates (get-subscriptions-newsletter-updates pool)
|
||||
:newsletter-news (get-subscriptions-newsletter-news pool)}
|
||||
|
||||
enabled? (or enabled?
|
||||
(contains? cf/flags :telemetry)
|
||||
(cf/get :telemetry-enabled))
|
||||
|
@ -77,12 +79,11 @@
|
|||
|
||||
(defn- send!
|
||||
[cfg data]
|
||||
(let [response (http/req! cfg
|
||||
{:method :post
|
||||
:uri (cf/get :telemetry-uri)
|
||||
:headers {"content-type" "application/json"}
|
||||
:body (json/encode-str data)}
|
||||
{:sync? true})]
|
||||
(let [request {:method :post
|
||||
:uri (cf/get :telemetry-uri)
|
||||
:headers {"content-type" "application/json"}
|
||||
:body (json/encode-str data)}
|
||||
response (http/req! cfg request)]
|
||||
(when (> (:status response) 206)
|
||||
(ex/raise :type :internal
|
||||
:code :invalid-response
|
||||
|
|
|
@ -102,7 +102,7 @@
|
|||
(t/deftest test-parse-bounce-report
|
||||
(let [profile (th/create-profile* 1)
|
||||
props (:app.setup/props th/*system*)
|
||||
cfg {:app.main/props props}
|
||||
cfg {:app.setup/props props}
|
||||
report (bounce-report {:token (tokens/generate props
|
||||
{:iss :profile-identity
|
||||
:profile-id (:id profile)})})
|
||||
|
@ -118,7 +118,7 @@
|
|||
(t/deftest test-parse-complaint-report
|
||||
(let [profile (th/create-profile* 1)
|
||||
props (:app.setup/props th/*system*)
|
||||
cfg {:app.main/props props}
|
||||
cfg {:app.setup/props props}
|
||||
report (complaint-report {:token (tokens/generate props
|
||||
{:iss :profile-identity
|
||||
:profile-id (:id profile)})})
|
||||
|
@ -132,7 +132,7 @@
|
|||
|
||||
(t/deftest test-parse-complaint-report-without-token
|
||||
(let [props (:app.setup/props th/*system*)
|
||||
cfg {:app.main/props props}
|
||||
cfg {:app.setup/props props}
|
||||
report (complaint-report {:token ""})
|
||||
result (#'awsns/parse-notification cfg report)]
|
||||
(t/is (= "complaint" (:type result)))
|
||||
|
@ -145,7 +145,7 @@
|
|||
(let [profile (th/create-profile* 1)
|
||||
props (:app.setup/props th/*system*)
|
||||
pool (:app.db/pool th/*system*)
|
||||
cfg {:app.main/props props :app.db/pool pool}
|
||||
cfg {:app.setup/props props :app.db/pool pool}
|
||||
report (bounce-report {:token (tokens/generate props
|
||||
{:iss :profile-identity
|
||||
:profile-id (:id profile)})})
|
||||
|
@ -172,7 +172,7 @@
|
|||
(let [profile (th/create-profile* 1)
|
||||
props (:app.setup/props th/*system*)
|
||||
pool (:app.db/pool th/*system*)
|
||||
cfg {:app.main/props props
|
||||
cfg {:app.setup/props props
|
||||
:app.db/pool pool}
|
||||
report (complaint-report {:token (tokens/generate props
|
||||
{:iss :profile-identity
|
||||
|
@ -202,7 +202,7 @@
|
|||
(let [profile (th/create-profile* 1)
|
||||
props (:app.setup/props th/*system*)
|
||||
pool (:app.db/pool th/*system*)
|
||||
cfg {:app.main/props props :app.db/pool pool}
|
||||
cfg {:app.setup/props props :app.db/pool pool}
|
||||
report (bounce-report {:email (:email profile)
|
||||
:token (tokens/generate props
|
||||
{:iss :profile-identity
|
||||
|
@ -224,7 +224,7 @@
|
|||
(let [profile (th/create-profile* 1)
|
||||
props (:app.setup/props th/*system*)
|
||||
pool (:app.db/pool th/*system*)
|
||||
cfg {:app.main/props props :app.db/pool pool}
|
||||
cfg {:app.setup/props props :app.db/pool pool}
|
||||
report (complaint-report {:email (:email profile)
|
||||
:token (tokens/generate props
|
||||
{:iss :profile-identity
|
||||
|
|
|
@ -716,20 +716,19 @@
|
|||
|
||||
(defn name
|
||||
"Improved version of name that won't fail if the input is not a keyword"
|
||||
([maybe-keyword] (name maybe-keyword nil))
|
||||
([maybe-keyword default-value]
|
||||
(cond
|
||||
(keyword? maybe-keyword)
|
||||
(c/name maybe-keyword)
|
||||
[maybe-keyword]
|
||||
(cond
|
||||
(nil? maybe-keyword)
|
||||
nil
|
||||
|
||||
(string? maybe-keyword)
|
||||
maybe-keyword
|
||||
(keyword? maybe-keyword)
|
||||
(c/name maybe-keyword)
|
||||
|
||||
(nil? maybe-keyword) default-value
|
||||
(string? maybe-keyword)
|
||||
maybe-keyword
|
||||
|
||||
:else
|
||||
(or default-value
|
||||
(str maybe-keyword)))))
|
||||
:else
|
||||
(str maybe-keyword)))
|
||||
|
||||
(defn prefix-keyword
|
||||
"Given a keyword and a prefix will return a new keyword with the prefix attached
|
||||
|
|
|
@ -507,8 +507,7 @@
|
|||
(and (:shape-ref parent)
|
||||
(#{:group :frame} (:type parent))
|
||||
(not ignore-touched))
|
||||
(-> (update :touched cfh/set-touched-group :shapes-group)
|
||||
(dissoc :remote-synced)))))
|
||||
(dissoc :remote-synced))))
|
||||
|
||||
(remove-from-old-parent [old-objects objects shape-id]
|
||||
(let [prev-parent-id (dm/get-in old-objects [shape-id :parent-id])]
|
||||
|
@ -525,9 +524,7 @@
|
|||
(-> objects
|
||||
(d/update-in-when [pid :shapes] d/without-obj sid)
|
||||
(d/update-in-when [pid :shapes] d/vec-without-nils)
|
||||
(cond-> component? (d/update-when pid #(-> %
|
||||
(update :touched cfh/set-touched-group :shapes-group)
|
||||
(dissoc :remote-synced)))))))))
|
||||
(cond-> component? (d/update-when pid #(dissoc % :remote-synced))))))))
|
||||
(update-parent-id [objects id]
|
||||
(-> objects
|
||||
(d/update-when id assoc :parent-id parent-id)))
|
||||
|
@ -612,11 +609,15 @@
|
|||
(defmethod process-change :add-recent-color
|
||||
[data {:keys [color]}]
|
||||
;; Moves the color to the top of the list and then truncates up to 15
|
||||
(update data :recent-colors (fn [rc]
|
||||
(let [rc (conj (filterv (comp not #{color}) (or rc [])) color)]
|
||||
(if (> (count rc) 15)
|
||||
(subvec rc 1)
|
||||
rc)))))
|
||||
(update
|
||||
data
|
||||
:recent-colors
|
||||
(fn [rc]
|
||||
(let [rc (->> rc (d/removev (partial ctc/eq-recent-color? color)))
|
||||
rc (-> rc (conj color))]
|
||||
(cond-> rc
|
||||
(> (count rc) 15)
|
||||
(subvec 1))))))
|
||||
|
||||
;; -- Media
|
||||
|
||||
|
|
|
@ -109,11 +109,12 @@
|
|||
[changes f]
|
||||
(update changes :redo-changes #(mapv f %)))
|
||||
|
||||
;; redo-changes is a vector and :undo-changes is a list
|
||||
(defn concat-changes
|
||||
[changes1 changes2]
|
||||
(-> changes1
|
||||
(update :redo-changes d/concat-vec (:redo-changes changes2))
|
||||
(update :undo-changes d/concat-vec (:undo-changes changes2))))
|
||||
(update :undo-changes #(concat (:undo-changes changes2) %))))
|
||||
|
||||
; TODO: remove this when not needed
|
||||
(defn- assert-page-id!
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
[app.common.schema :as sm]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.uuid :as uuid]
|
||||
[clojure.set :as set]
|
||||
[cuerdas.core :as str]))
|
||||
|
@ -361,7 +360,8 @@
|
|||
|
||||
(defn set-touched-group
|
||||
[touched group]
|
||||
(conj (or touched #{}) group))
|
||||
(when group
|
||||
(conj (or touched #{}) group)))
|
||||
|
||||
(defn touched-group?
|
||||
[shape group]
|
||||
|
@ -741,22 +741,6 @@
|
|||
(d/seek root-frame?)
|
||||
:id))
|
||||
|
||||
(defn comparator-layout-z-index
|
||||
[[idx-a child-a] [idx-b child-b]]
|
||||
(cond
|
||||
(> (ctl/layout-z-index child-a) (ctl/layout-z-index child-b)) 1
|
||||
(< (ctl/layout-z-index child-a) (ctl/layout-z-index child-b)) -1
|
||||
(< idx-a idx-b) 1
|
||||
(> idx-a idx-b) -1
|
||||
:else 0))
|
||||
|
||||
(defn sort-layout-children-z-index
|
||||
[children]
|
||||
(->> children
|
||||
(d/enumerate)
|
||||
(sort comparator-layout-z-index)
|
||||
(mapv second)))
|
||||
|
||||
(defn common-parent-frame
|
||||
"Search for the common frame for the selected shapes. Otherwise returns the root frame"
|
||||
[objects selected]
|
||||
|
@ -779,6 +763,13 @@
|
|||
|
||||
(recur frame-id frame-parents (rest selected))))))
|
||||
|
||||
(defn fixed-scroll?
|
||||
[shape]
|
||||
^boolean
|
||||
(and (:fixed-scroll shape)
|
||||
(= (:parent-id shape) (:frame-id shape))
|
||||
(not= (:frame-id shape) uuid/zero)))
|
||||
|
||||
(defn fixed?
|
||||
[objects shape-id]
|
||||
(let [ids-to-check
|
||||
|
@ -789,4 +780,4 @@
|
|||
(take-while #(and (not= % uuid/zero) (not (root-frame? objects %))))))]
|
||||
(boolean
|
||||
(->> ids-to-check
|
||||
(d/seek (fn [id] (dm/get-in objects [id :fixed-scroll])))))))
|
||||
(d/seek (fn [id] () (fixed-scroll? (get objects id))))))))
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
[cuerdas.core :as str]))
|
||||
|
||||
;; We have added ".ttf" as string to solve a problem with chrome input selector
|
||||
(def valid-font-types #{"font/ttf", ".ttf", "font/woff", "application/font-woff", "font/otf"})
|
||||
(def valid-font-types #{"font/ttf" ".ttf" "font/woff", "application/font-woff" "woff" "font/otf" ".otf" "font/opentype"})
|
||||
(def valid-image-types #{"image/jpeg", "image/png", "image/webp", "image/gif", "image/svg+xml"})
|
||||
(def str-image-types (str/join "," valid-image-types))
|
||||
(def str-font-types (str/join "," valid-font-types))
|
||||
|
|
|
@ -358,3 +358,9 @@
|
|||
|
||||
(process-shape-colors shape sync-color)))
|
||||
|
||||
(defn eq-recent-color?
|
||||
[c1 c2]
|
||||
(or (= c1 c2)
|
||||
(and (some? (:color c1))
|
||||
(some? (:color c2))
|
||||
(= (:color c1) (:color c2)))))
|
||||
|
|
|
@ -4,7 +4,11 @@
|
|||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.common.types.component)
|
||||
(ns app.common.types.component
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.uuid :as uuid]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
;; Attributes that may be synced in components, and the group they belong to.
|
||||
;; When one attribute is modified in a shape inside a component, the corresponding
|
||||
|
@ -170,6 +174,29 @@
|
|||
(and (= shape-id (:main-instance-id component))
|
||||
(= page-id (:main-instance-page component))))
|
||||
|
||||
(defn build-swap-slot-group
|
||||
"Convert a swap-slot into a :touched group"
|
||||
[swap-slot]
|
||||
(when swap-slot
|
||||
(keyword (str "swap-slot-" swap-slot))))
|
||||
|
||||
(defn get-swap-slot
|
||||
"If the shape has a :touched group in the form :swap-slot-<uuid>, get the id."
|
||||
[shape]
|
||||
(let [group (->> (:touched shape)
|
||||
(map name)
|
||||
(d/seek #(str/starts-with? % "swap-slot-")))]
|
||||
(when group
|
||||
(uuid/uuid (subs group 10)))))
|
||||
|
||||
(defn match-swap-slot?
|
||||
[shape-main shape-inst]
|
||||
(let [slot-main (get-swap-slot shape-main)
|
||||
slot-inst (get-swap-slot shape-inst)]
|
||||
(when (some? slot-inst)
|
||||
(or (= slot-main slot-inst)
|
||||
(= (:id shape-main) slot-inst)))))
|
||||
|
||||
(defn get-component-root
|
||||
[component]
|
||||
(if (true? (:main-instance-id component))
|
||||
|
@ -213,3 +240,13 @@
|
|||
(distinct)
|
||||
(filter #(not (eq % (get comp1 %) (get comp2 %))))
|
||||
set)))
|
||||
|
||||
(defn allow-duplicate?
|
||||
[objects shape]
|
||||
|
||||
(let [parent (get objects (:parent-id shape))]
|
||||
;; We don't want to change the structure of component copies
|
||||
(and (not (in-component-copy-not-head? shape))
|
||||
;; Non instance, non copy. We allow
|
||||
(or (not (instance-head? shape))
|
||||
(not (in-component-copy? parent))))))
|
||||
|
|
|
@ -90,6 +90,10 @@
|
|||
[container shape-id f]
|
||||
(update-in container [:objects shape-id] f))
|
||||
|
||||
(defn get-container-root
|
||||
[container]
|
||||
(d/seek #(or (nil? (:parent-id %)) (= (:parent-id %) uuid/zero)) (shapes-seq container)))
|
||||
|
||||
(defn get-direct-children
|
||||
[container shape]
|
||||
(map #(get-shape container %) (:shapes shape)))
|
||||
|
@ -107,7 +111,7 @@
|
|||
(get-children-rec [] id)))
|
||||
|
||||
(defn get-component-shape
|
||||
"Get the parent top shape linked to a component for this shape, if any"
|
||||
"Get the parent top shape linked to a component main for this shape, if any"
|
||||
([objects shape] (get-component-shape objects shape nil))
|
||||
([objects shape {:keys [allow-main?] :or {allow-main? false} :as options}]
|
||||
(let [parent (get objects (:parent-id shape))]
|
||||
|
@ -416,12 +420,6 @@
|
|||
(some ctk/main-instance? children)
|
||||
(some ctk/main-instance? parents))))
|
||||
|
||||
(defn has-any-main-children?
|
||||
"Check if the shape is a main component or has any children that is a main component."
|
||||
[objects shape]
|
||||
(let [children (cfh/get-children-with-self objects (:id shape))]
|
||||
(some ctk/main-instance? children)))
|
||||
|
||||
(defn valid-shape-for-component?
|
||||
"Check if a main component can be generated from this shape in terms of nested components:
|
||||
- A main can't be the ancestor of another main
|
||||
|
@ -431,10 +429,29 @@
|
|||
(not (has-any-main? objects shape))
|
||||
(not (has-any-copy-parent? objects shape))))
|
||||
|
||||
|
||||
(defn collect-main-shapes [shape objects]
|
||||
(if (ctk/main-instance? shape)
|
||||
[shape]
|
||||
(if-let [children (cfh/get-children objects (:id shape))]
|
||||
(mapcat collect-main-shapes children objects)
|
||||
[])))
|
||||
|
||||
(defn- invalid-structure-for-component?
|
||||
"Check if the structure generated nesting children in parent is invalid in terms of nested components"
|
||||
[objects parent children]
|
||||
(let [selected-main-instance? (some true? (map #(has-any-main-children? objects %) children))
|
||||
[objects parent children pasting? libraries]
|
||||
(let [; When we are pasting, the main shapes will be pasted as copies, unless the
|
||||
; original component doesn't exist or is deleted. So for this function purposes, they
|
||||
; are removed from the list
|
||||
remove? (fn [shape]
|
||||
(let [component (get-in libraries [(:component-file shape) :data :components (:component-id shape)])]
|
||||
(and component (not (:deleted component)))))
|
||||
|
||||
selected-components (cond->> (mapcat collect-main-shapes children objects)
|
||||
pasting?
|
||||
(remove #(remove? %)))
|
||||
|
||||
selected-main-instance? (seq selected-components)
|
||||
parent-in-component? (in-any-component? objects parent)
|
||||
comps-nesting-loop? (not (->> children
|
||||
(map #(cfh/components-nesting-loop? objects (:id %) (:id parent)))
|
||||
|
@ -450,13 +467,15 @@
|
|||
|
||||
(defn find-valid-parent-and-frame-ids
|
||||
"Navigate trough the ancestors until find one that is valid. Returns [ parent-id frame-id ]"
|
||||
[parent-id objects children]
|
||||
(letfn [(get-frame [parent-id]
|
||||
(if (cfh/frame-shape? objects parent-id) parent-id (get-in objects [parent-id :frame-id])))]
|
||||
(let [parent (get objects parent-id)
|
||||
([parent-id objects children]
|
||||
(find-valid-parent-and-frame-ids parent-id objects children false nil))
|
||||
([parent-id objects children pasting? libraries]
|
||||
(letfn [(get-frame [parent-id]
|
||||
(if (cfh/frame-shape? objects parent-id) parent-id (get-in objects [parent-id :frame-id])))]
|
||||
(let [parent (get objects parent-id)
|
||||
;; We can always move the children to the parent they already have
|
||||
no-changes?
|
||||
(->> children (every? #(= parent-id (:parent-id %))))]
|
||||
(if (or no-changes? (not (invalid-structure-for-component? objects parent children)))
|
||||
[parent-id (get-frame parent-id)]
|
||||
(recur (:parent-id parent) objects children)))))
|
||||
no-changes?
|
||||
(->> children (every? #(= parent-id (:parent-id %))))]
|
||||
(if (or no-changes? (not (invalid-structure-for-component? objects parent children pasting? libraries)))
|
||||
[parent-id (get-frame parent-id)]
|
||||
(recur (:parent-id parent) objects children pasting? libraries))))))
|
||||
|
|
|
@ -117,12 +117,6 @@
|
|||
(ctkl/update-component file-data (:id container) f)))
|
||||
|
||||
;; Asset helpers
|
||||
|
||||
(defn find-component
|
||||
"Retrieve a component from libraries, iterating over all of them."
|
||||
[libraries component-id & {:keys [include-deleted?] :or {include-deleted? false}}]
|
||||
(some #(ctkl/get-component (:data %) component-id include-deleted?) (vals libraries)))
|
||||
|
||||
(defn find-component-file
|
||||
[file libraries component-file]
|
||||
(if (and (some? file) (= component-file (:id file)))
|
||||
|
@ -153,7 +147,7 @@
|
|||
|
||||
(defn get-component-container
|
||||
"Retrieve the container that holds the component shapes (the page in components-v2
|
||||
or the component itself in v1)"
|
||||
or the component itself in v1 or deleted component)."
|
||||
[file-data component]
|
||||
(let [components-v2 (dm/get-in file-data [:options :components-v2])]
|
||||
(if (and components-v2 (not (:deleted component)))
|
||||
|
@ -172,22 +166,34 @@
|
|||
(ctk/get-component-root component))))
|
||||
|
||||
(defn get-component-shape
|
||||
"Retrieve one shape in the component by id."
|
||||
[file-data component shape-id]
|
||||
"Retrieve one shape in the component by id. If with-context? is true, add the
|
||||
file and container where the shape resides in its metadata."
|
||||
[file-data component shape-id & {:keys [with-context?] :or {with-context? false}}]
|
||||
(let [components-v2 (dm/get-in file-data [:options :components-v2])]
|
||||
(if (and components-v2 (not (:deleted component)))
|
||||
(let [component-page (get-component-page file-data component)]
|
||||
(when component-page
|
||||
(cfh/get-child (:objects component-page)
|
||||
(:main-instance-id component)
|
||||
shape-id)))
|
||||
(dm/get-in component [:objects shape-id]))))
|
||||
(let [child (cfh/get-child (:objects component-page)
|
||||
(:main-instance-id component)
|
||||
shape-id)]
|
||||
(cond-> child
|
||||
(and child with-context?)
|
||||
(with-meta {:file {:id (:id file-data)
|
||||
:data file-data}
|
||||
:container (ctn/make-container component-page :page)})))))
|
||||
|
||||
(let [shape (dm/get-in component [:objects shape-id])]
|
||||
(cond-> shape
|
||||
(and shape with-context?)
|
||||
(with-meta {:file {:id (:id file-data)
|
||||
:data file-data}
|
||||
:container (ctn/make-container component :component)}))))))
|
||||
|
||||
(defn get-ref-shape
|
||||
"Retrieve the shape in the component that is referenced by the instance shape."
|
||||
[file-data component shape]
|
||||
[file-data component shape & {:keys [with-context?] :or {with-context? false}}]
|
||||
(when (:shape-ref shape)
|
||||
(get-component-shape file-data component (:shape-ref shape))))
|
||||
(get-component-shape file-data component (:shape-ref shape) :with-context? with-context?)))
|
||||
|
||||
(defn get-shape-in-copy
|
||||
"Given a shape in the main component and the root of the copy component returns the equivalent
|
||||
|
@ -199,16 +205,25 @@
|
|||
(defn find-ref-shape
|
||||
"Locate the nearest component in the local file or libraries, and retrieve the shape
|
||||
referenced by the instance shape."
|
||||
[file page libraries shape & {:keys [include-deleted?] :or {include-deleted? false}}]
|
||||
[file container libraries shape & {:keys [include-deleted? with-context?] :or {include-deleted? false with-context? false}}]
|
||||
(let [find-ref-shape-in-head
|
||||
(fn [head-shape]
|
||||
(let [head-file (find-component-file file libraries (:component-file head-shape))
|
||||
head-component (when (some? head-file)
|
||||
(ctkl/get-component (:data head-file) (:component-id head-shape) include-deleted?))]
|
||||
(when (some? head-component)
|
||||
(get-ref-shape (:data head-file) head-component shape))))]
|
||||
(let [component-file (find-component-file file libraries (:component-file head-shape))
|
||||
component (when (some? component-file)
|
||||
(ctkl/get-component (:data component-file) (:component-id head-shape) include-deleted?))]
|
||||
(when (some? component)
|
||||
(get-ref-shape (:data component-file) component shape :with-context? with-context?))))]
|
||||
|
||||
(some find-ref-shape-in-head (ctn/get-parent-heads (:objects container) shape))))
|
||||
|
||||
(defn find-original-ref-shape
|
||||
"Recursively call to find-ref-shape until find the original shape of the original component"
|
||||
[file container libraries shape & options]
|
||||
(let [ref-shape (find-ref-shape file container libraries shape options)]
|
||||
(if (nil? (:shape-ref ref-shape))
|
||||
ref-shape
|
||||
(find-original-ref-shape file container libraries ref-shape options))))
|
||||
|
||||
(some find-ref-shape-in-head (ctn/get-parent-heads (:objects page) shape))))
|
||||
|
||||
(defn find-ref-component
|
||||
"Locate the nearest component in the local file or libraries that is referenced by the
|
||||
|
@ -216,12 +231,14 @@
|
|||
[file page libraries shape & {:keys [include-deleted?] :or {include-deleted? false}}]
|
||||
(let [find-ref-component-in-head
|
||||
(fn [head-shape]
|
||||
(let [head-file (find-component-file file libraries (:component-file head-shape))
|
||||
head-component (when (some? head-file)
|
||||
(ctkl/get-component (:data head-file) (:component-id head-shape) include-deleted?))]
|
||||
(when (some? head-component)
|
||||
(when (get-ref-shape (:data head-file) head-component shape)
|
||||
head-component))))]
|
||||
(let [component-file (find-component-file file libraries (:component-file head-shape))
|
||||
component (when (some? component-file)
|
||||
(ctkl/get-component (:data component-file)
|
||||
(:component-id head-shape)
|
||||
include-deleted?))]
|
||||
(when (some? component)
|
||||
(when (get-ref-shape (:data component-file) component shape)
|
||||
component))))]
|
||||
|
||||
(some find-ref-component-in-head (ctn/get-parent-copy-heads (:objects page) shape))))
|
||||
|
||||
|
@ -257,6 +274,34 @@
|
|||
(let [ref-component (find-ref-component file page libraries shape :include-deleted? true)]
|
||||
(true? (= (:id component) (:id ref-component)))))
|
||||
|
||||
(defn find-swap-slot
|
||||
[shape container file libraries]
|
||||
(if-let [swap-slot (ctk/get-swap-slot shape)]
|
||||
swap-slot
|
||||
(let [ref-shape (find-ref-shape file
|
||||
container
|
||||
libraries
|
||||
shape
|
||||
:include-deleted? true
|
||||
:with-context? true)
|
||||
shape-meta (meta ref-shape)
|
||||
ref-file (:file shape-meta)
|
||||
ref-container (:container shape-meta)]
|
||||
(when ref-shape
|
||||
(if-let [swap-slot (ctk/get-swap-slot ref-shape)]
|
||||
swap-slot
|
||||
(if (ctk/main-instance? ref-shape)
|
||||
(:id shape)
|
||||
(find-swap-slot ref-shape ref-container ref-file libraries)))))))
|
||||
|
||||
(defn match-swap-slot?
|
||||
[shape-main shape-inst container-inst container-main file libraries]
|
||||
(let [slot-main (find-swap-slot shape-main container-main file libraries)
|
||||
slot-inst (find-swap-slot shape-inst container-inst file libraries)]
|
||||
(when (some? slot-inst)
|
||||
(or (= slot-main slot-inst)
|
||||
(= (:id shape-main) slot-inst)))))
|
||||
|
||||
(defn get-component-shapes
|
||||
"Retrieve all shapes of the component"
|
||||
[file-data component]
|
||||
|
@ -268,7 +313,7 @@
|
|||
(vals (:objects component)))))
|
||||
|
||||
;; Return true if the object is a component that exists on the file or its libraries (even a deleted one)
|
||||
(defn is-known-component?
|
||||
(defn is-main-of-known-component?
|
||||
[shape libraries]
|
||||
(let [main-instance? (ctk/main-instance? shape)
|
||||
component-id (:component-id shape)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.shapes.grid-layout.areas :as sga]
|
||||
[app.common.math :as mth]
|
||||
[app.common.schema :as sm]
|
||||
|
@ -47,7 +48,8 @@
|
|||
#{:flex :grid})
|
||||
|
||||
(def flex-direction-types
|
||||
#{:row :reverse-row :row-reverse :column :reverse-column :column-reverse}) ;;TODO remove reverse-column and reverse-row after script
|
||||
;;TODO remove reverse-column and reverse-row after script
|
||||
#{:row :reverse-row :row-reverse :column :reverse-column :column-reverse})
|
||||
|
||||
(def grid-direction-types
|
||||
#{:row :column})
|
||||
|
@ -128,7 +130,7 @@
|
|||
(def grid-cell-justify-self-types
|
||||
#{:auto :start :center :end :stretch})
|
||||
|
||||
(sm/define! ::grid-cell
|
||||
(sm/def! ::grid-cell
|
||||
[:map {:title "GridCell"}
|
||||
[:id ::sm/uuid]
|
||||
[:area-name {:optional true} :string]
|
||||
|
@ -142,7 +144,7 @@
|
|||
[:shapes
|
||||
[:vector {:gen/max 1} ::sm/uuid]]])
|
||||
|
||||
(sm/define! ::grid-track
|
||||
(sm/def! ::grid-track
|
||||
[:map {:title "GridTrack"}
|
||||
[:type [::sm/one-of grid-track-types]]
|
||||
[:value {:optional true} [:maybe ::sm/safe-number]]])
|
||||
|
@ -197,14 +199,14 @@
|
|||
([objects id]
|
||||
(flex-layout? (get objects id)))
|
||||
([shape]
|
||||
(and (= :frame (:type shape))
|
||||
(and (cfh/frame-shape? shape)
|
||||
(= :flex (:layout shape)))))
|
||||
|
||||
(defn grid-layout?
|
||||
([objects id]
|
||||
(grid-layout? (get objects id)))
|
||||
([shape]
|
||||
(and (= :frame (:type shape))
|
||||
(and (cfh/frame-shape? shape)
|
||||
(= :grid (:layout shape)))))
|
||||
|
||||
(defn any-layout?
|
||||
|
@ -212,7 +214,10 @@
|
|||
(any-layout? (get objects id)))
|
||||
|
||||
([shape]
|
||||
(or (flex-layout? shape) (grid-layout? shape))))
|
||||
(and (cfh/frame-shape? shape)
|
||||
(let [layout (:layout shape)]
|
||||
(or (= :flex layout)
|
||||
(= :grid layout))))))
|
||||
|
||||
(defn flex-layout-immediate-child? [objects shape]
|
||||
(let [parent-id (:parent-id shape)
|
||||
|
@ -262,20 +267,21 @@
|
|||
(defn inside-layout?
|
||||
"Check if the shape is inside a layout"
|
||||
[objects shape]
|
||||
|
||||
(loop [current-id (:id shape)]
|
||||
(let [current (get objects current-id)]
|
||||
(loop [current-id (dm/get-prop shape :id)]
|
||||
(let [current (get objects current-id)
|
||||
parent-id (dm/get-prop current :parent-id)]
|
||||
(cond
|
||||
(or (nil? current) (= current-id (:parent-id current)))
|
||||
(or (nil? current) (= current-id parent-id))
|
||||
false
|
||||
|
||||
(= :frame (:type current))
|
||||
(cfh/frame-shape? current-id)
|
||||
(:layout current)
|
||||
|
||||
:else
|
||||
(recur (:parent-id current))))))
|
||||
(recur parent-id)))))
|
||||
|
||||
(defn wrap? [{:keys [layout-wrap-type]}]
|
||||
(defn wrap?
|
||||
[{:keys [layout-wrap-type]}]
|
||||
(= layout-wrap-type :wrap))
|
||||
|
||||
(defn fill-width?
|
||||
|
@ -536,6 +542,22 @@
|
|||
([shape]
|
||||
(or (:layout-item-z-index shape) 0)))
|
||||
|
||||
(defn- comparator-layout-z-index
|
||||
[[idx-a child-a] [idx-b child-b]]
|
||||
(cond
|
||||
(> (layout-z-index child-a) (layout-z-index child-b)) 1
|
||||
(< (layout-z-index child-a) (layout-z-index child-b)) -1
|
||||
(< idx-a idx-b) 1
|
||||
(> idx-a idx-b) -1
|
||||
:else 0))
|
||||
|
||||
(defn sort-layout-children-z-index
|
||||
[children]
|
||||
(->> children
|
||||
(d/enumerate)
|
||||
(sort comparator-layout-z-index)
|
||||
(mapv second)))
|
||||
|
||||
(defn change-h-sizing?
|
||||
[frame-id objects children-ids]
|
||||
(and (flex-layout? objects frame-id)
|
||||
|
|
|
@ -40,8 +40,7 @@
|
|||
(update :shapes update-parent-shapes)
|
||||
(update :shapes d/vec-without-nils)
|
||||
(cond-> (and (ctk/in-component-copy? parent) (not ignore-touched))
|
||||
(-> (update :touched cfh/set-touched-group :shapes-group)
|
||||
(dissoc :remote-synced)))))
|
||||
(dissoc :remote-synced))))
|
||||
|
||||
update-objects
|
||||
(fn [objects parent-id]
|
||||
|
@ -85,8 +84,7 @@
|
|||
(let [parent (update parent :shapes d/without-obj shape-id)]
|
||||
(cond-> parent
|
||||
(and (:shape-ref parent) (not ignore-touched))
|
||||
(-> (update :touched cfh/set-touched-group :shapes-group)
|
||||
(dissoc :remote-synced)))))
|
||||
(dissoc :remote-synced))))
|
||||
|
||||
(delete-from-objects [objects]
|
||||
(if-let [target (get objects shape-id)]
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
[page root-inst-id libraries]
|
||||
(let [root-inst (ctn/get-shape page root-inst-id)
|
||||
|
||||
component (ctf/find-component libraries (:component-id root-inst))
|
||||
component (ctf/get-component libraries (:component-file root-inst) (:component-id root-inst))
|
||||
|
||||
shapes-inst (cfh/get-children-with-self (:objects page) root-inst-id)
|
||||
shapes-main (cfh/get-children-with-self (:objects component) (:shape-ref root-inst))
|
||||
|
@ -94,7 +94,7 @@
|
|||
(ctn/get-component-shape (:objects page) shape)
|
||||
|
||||
component
|
||||
(ctf/find-component libraries (:component-id component-shape))
|
||||
(ctf/get-component libraries (:component-file component-shape) (:component-id component-shape))
|
||||
|
||||
main-shape
|
||||
(ctn/get-shape component (:shape-ref shape))]
|
||||
|
@ -118,7 +118,7 @@
|
|||
[page root-inst-id libraries]
|
||||
(let [root-inst (ctn/get-shape page root-inst-id)
|
||||
|
||||
component (ctf/find-component libraries (:component-id root-inst))
|
||||
component (ctf/get-component libraries (:component-file root-inst) (:component-id root-inst))
|
||||
|
||||
shapes-inst (cfh/get-children-with-self (:objects page) root-inst-id)
|
||||
shapes-main (cfh/get-children-with-self (:objects component) (:shape-ref root-inst))
|
||||
|
@ -130,7 +130,7 @@
|
|||
(ctn/get-component-shape (:objects page) shape)
|
||||
|
||||
component
|
||||
(ctf/find-component libraries (:component-id component-shape))
|
||||
(ctf/get-component libraries (:component-file component-shape) (:component-id component-shape))
|
||||
|
||||
main-shape
|
||||
(ctn/get-shape component (:shape-ref shape))]
|
||||
|
@ -142,15 +142,5 @@
|
|||
|
||||
[shapes-inst shapes-main component]))
|
||||
|
||||
(defn resolve-component
|
||||
"Get the component with the given id and all its shapes."
|
||||
[page component-id libraries]
|
||||
(let [component (ctf/find-component libraries component-id)
|
||||
root-main (ctk/get-component-root component)
|
||||
shapes-main (cfh/get-children-with-self (:objects component) (:id root-main))]
|
||||
|
||||
;; Validate that the component tree is well constructed
|
||||
(run! check-noninstance shapes-main)
|
||||
|
||||
[shapes-main component]))
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
funcool/okulary {:mvn/version "2022.04.11-16"}
|
||||
|
||||
funcool/potok2
|
||||
{:git/tag "v2.0"
|
||||
:git/sha "2bb377b"
|
||||
{:git/tag "v2.1"
|
||||
:git/sha "84c97b9"
|
||||
:git/url "https://github.com/funcool/potok.git"}
|
||||
|
||||
funcool/beicon2
|
||||
|
|
BIN
frontend/resources/images/features/2.0-html.gif
Normal file
After Width: | Height: | Size: 318 KiB |
Before Width: | Height: | Size: 295 B After Width: | Height: | Size: 295 B |
|
@ -1 +0,0 @@
|
|||
<svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-317.143 -552.362)"><circle cx="327.143" cy="562.362" fill="#78dbbe" r="10"/><path d="m325.238 570.484c-.254-.07-.48-.196-.67-.377-.29-.274-.434-.578-.485-1.023-.017-.15-.06-.326-.094-.395-.036-.07-.87-1.335-1.855-2.812s-1.826-2.765-1.87-2.862c-.213-.485-.312-1.09-.236-1.454.147-.71.793-1.236 1.514-1.236.38 0 .935.18 1.283.418.085.057.392.338.682.625.29.285.538.51.55.498.01-.01.02-1.437.02-3.167 0-2.684.008-3.17.05-3.327.143-.553.566-.978 1.117-1.12.262-.07 1.485-.07 1.746-.002.507.133.873.463 1.086.982.065.16.068.226.083 1.602l.016 1.436.414.02c.437.02.603.062.885.23.19.112.414.353.54.58l.107.19.462.02c.486.02.637.056.93.23.19.112.416.354.542.58l.107.19.46.02c.487.02.635.056.932.23.316.185.614.613.693.996.024.112.03.918.025 2.49l-.01 2.325-.086.276c-.048.152-.12.353-.162.447-.09.205-1.66 2.574-1.842 2.78-.174.198-.53.43-.842.547l-.256.097-2.84.006c-2.372.006-2.865 0-3.004-.04zm5.86-1.075c.097-.048.225-.134.284-.192.135-.132 1.613-2.342 1.715-2.566.163-.355.168-.438.17-2.747 0-2.076-.002-2.15-.064-2.27-.034-.068-.11-.157-.167-.198-.093-.066-.14-.074-.44-.074h-.334l-.016.847-.016.848-.086.113c-.223.293-.61.284-.837-.017-.063-.085-.066-.14-.082-1.293l-.015-1.204-.086-.113c-.135-.177-.263-.22-.607-.21l-.296.008-.015.852c-.015.796-.02.856-.082.94-.125.166-.227.218-.428.218-.202 0-.304-.052-.43-.22-.062-.084-.065-.138-.08-1.292l-.017-1.204-.085-.112c-.135-.177-.263-.222-.608-.21l-.295.007-.016.847-.016.848-.086.112c-.116.153-.284.23-.46.21-.148-.017-.333-.135-.402-.257-.032-.055-.044-.683-.057-2.797l-.016-2.727-.074-.105c-.04-.056-.132-.132-.202-.168-.116-.06-.174-.064-.772-.055-.646.01-.646.01-.76.096-.233.178-.216-.168-.216 4.49 0 4.66.017 4.313-.217 4.49-.092.07-.147.087-.293.087-.15 0-.2-.015-.3-.092-.168-.127-.21-.25-.21-.6v-.297l-.917-.913c-.55-.548-.968-.94-1.045-.977-.18-.09-.453-.166-.588-.165-.26 0-.51.26-.512.528 0 .17.104.576.192.75.038.073.87 1.335 1.85 2.804.978 1.468 1.808 2.726 1.843 2.794.092.182.163.448.194.725.03.276.103.404.284.5.113.06.194.062 2.828.055l2.71-.007.177-.086z" fill="#fff"/></g></svg>
|
Before Width: | Height: | Size: 2.1 KiB |
|
@ -1 +0,0 @@
|
|||
<svg height="500" viewBox="0 0 500.00001 500.00001" width="500" xmlns="http://www.w3.org/2000/svg"><path d="m191.64785 498.75262c-7.77969-2.11857-14.67898-5.99402-20.54139-11.53843-8.86314-8.38239-13.27097-17.70166-14.81986-31.33296-.52235-4.59701-1.80728-9.96843-2.89433-12.09923-1.07523-2.10761-26.63047-40.84608-56.789439-86.0855-30.158969-45.23941-55.913166-84.69256-57.231546-87.67366-6.563748-14.84179-9.586791-33.37935-7.262342-44.53328 4.526246-21.71931 24.327108-37.85973 46.414415-37.83411 11.641878.0135 28.640132 5.54001 39.296402 12.77611 2.58564 1.75579 11.98611 10.37261 20.88992 19.14853 8.90381 8.7759 16.48667 15.65827 16.8508 15.29414.36413-.36414.66206-44.01547.66206-97.00296 0-82.245655.21318-97.159375 1.45714-101.935253 4.41235-16.940112 17.39069-29.9600167 34.23876-34.3483807 8.05009-2.09678105 45.49218-2.12380205 53.49777-.0386 15.5359 4.046588 26.73695 14.1690707 33.25353 30.0515047 2.01608 4.913664 2.12219 6.923979 2.59061 49.08212l.48843 43.958619 12.69916.58638c13.37443.61757 18.47109 1.94455 27.10282 7.05653 5.81486 3.44375 12.72951 10.84436 16.58951 17.75539l3.27361 5.86115 14.12606.57445c14.94455.60774 19.54533 1.74762 28.52973 7.06847 5.81486 3.44374 12.72951 10.84435 16.58951 17.75539l3.27361 5.86115 14.12606.57445c14.92207.60682 19.46078 1.72797 28.54342 7.05074 9.68996 5.6787 18.81066 18.78004 21.24824 30.52183.7106 3.42294.95264 28.1032.74786 76.25841l-.30276 71.19758-2.63402 8.43865c-1.4487 4.64126-3.6785 10.79546-4.9551 13.67601-2.79164 6.29914-50.84038 78.83494-56.42111 85.17498-5.31576 6.03902-16.27188 13.15029-25.79263 16.74118l-7.84989 2.96071-86.94036.19531c-72.67254.16326-87.77967-.0332-92.05465-1.19741zm179.50355-32.90592c2.96605-1.45671 6.87807-4.09423 8.69336-5.86115 4.13916-4.02886 49.391-71.71439 52.53142-78.57398 4.99063-10.90096 5.14624-13.43644 5.16449-84.14958.0164-63.57187-.0465-65.85708-1.91464-69.51886-1.06239-2.08243-3.37021-4.81234-5.12851-6.06645-2.86192-2.04126-4.27166-2.28019-13.45391-2.28019h-10.25701l-.48843 25.9654-.48843 25.96541-2.63121 3.44708c-6.83226 8.9507-18.72512 8.69119-25.63731-.55944-1.92902-2.58161-2.03471-4.25321-2.5025-39.58056l-.48843-36.88512-2.63122-3.44757c-4.13845-5.42243-8.03678-6.77363-18.59664-6.44578l-9.05474.28112-.48843 26.06201c-.45694 24.3818-.61827 26.23574-2.5025 28.75695-3.83003 5.12479-6.95081 6.72309-13.12722 6.72309-6.17669 0-9.29773-1.59856-13.12723-6.72359-1.92902-2.58161-2.0347-4.25321-2.5025-39.58057l-.48843-36.88512-2.63122-3.44756c-4.13845-5.42243-8.03678-6.77363-18.59664-6.44578l-9.05474.28112-.48843 25.9654-.48843 25.96541-2.63121 3.44708c-3.56365 4.66861-8.71479 7.00414-14.10743 6.39631-4.51077-.50843-10.18186-4.12146-12.30976-7.84251-.95705-1.67358-1.34387-20.91329-1.72262-85.67957l-.48843-83.521362-2.28019-3.196904c-1.25411-1.758296-4.03275-4.090984-6.17476-5.183755-3.60332-1.838271-5.37457-1.964462-23.68558-1.687386-19.78025.299309-19.79289.300902-23.23772 2.930691-7.16446 5.46935-6.65223-5.122027-6.65223 137.547896 0 142.67538.51262 132.08072-6.65522 137.5479-2.80603 2.14025-4.48058 2.63121-8.97451 2.63121-4.58326 0-6.15379-.47975-9.21563-2.81513-5.11203-3.89914-6.41409-7.63565-6.41409-18.40647v-9.07362l-28.08467-27.98737c-16.84145-16.78309-29.648931-28.76278-31.992091-29.9243-5.491904-2.72239-13.890533-5.08594-18.004958-5.06697-7.975943.0367-15.64746 7.95753-15.680572 16.19004-.02076 5.15985 3.17886 17.64199 5.878954 22.9346 1.159376 2.27258 26.640125 40.92627 56.623877 85.89711 29.98376 44.97083 55.39705 83.49229 56.47397 85.60323 2.81991 5.52749 5.01244 13.67096 5.96313 22.14824.95039 8.47465 3.16631 12.37269 8.70794 15.31822 3.48262 1.85112 5.94661 1.89927 86.61752 1.6925l83.03293-.2128z"/></svg>
|
Before Width: | Height: | Size: 3.6 KiB |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M55.563 0v21.167h21.166V0H55.563zm0 55.563v21.166h21.166V55.563H55.563zm0 55.562v21.167h21.166v-21.167H55.563z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 249 B |
Before Width: | Height: | Size: 172 B After Width: | Height: | Size: 172 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m14.667 14.667h-13.334m7.334-14c1.104 0 2 .896 2 2v6.666c0 1.104-.896 2-2 2h-1.334c-1.103 0-2-.896-2-2v-6.666c0-1.104.897-2 2-2z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 259 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
|
||||
<path d="M361.11144 277.77792h-83.33332V0h-55.55584v277.77792h-83.33336l111.1113 111.11083zM472.22229 500v-55.55541H27.777705V500z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m14.667 14.667h-13.334m7.334-14c1.104 0 2 .896 2 2v6.666c0 1.104-.896 2-2 2h-1.334c-1.103 0-2-.896-2-2v-6.666c0-1.104.897-2 2-2z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 259 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M.667 14.667V1.333m14.666 13.334V1.333m-3 8c.828 0 1.5.673 1.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1c0-.827.672-1.5 1.5-1.5h1zm-7.666 0c.828 0 1.5.673 1.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1c0-.827.672-1.5 1.5-1.5h1zm7.666-6.666a1.5 1.5 0 011.5 1.5v1c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-7.666 0a1.5 1.5 0 011.5 1.5v1c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 602 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 0v132.292h11.207V0H0zm121.085 0v132.292h11.207V0h-11.207zM36.023 38.842c-6.487 0-11.745 5.258-11.745 11.744 0 6.487 5.258 11.745 11.745 11.745 6.486 0 11.744-5.259 11.744-11.745 0-6.486-5.258-11.744-11.744-11.744zm30.04 0c-6.486 0-11.744 5.258-11.744 11.744 0 6.487 5.258 11.745 11.744 11.745 6.487 0 11.745-5.259 11.745-11.745 0-6.486-5.259-11.744-11.745-11.744zm30.496 0c-6.487 0-11.745 5.258-11.745 11.744 0 6.487 5.258 11.745 11.745 11.745 6.486 0 11.744-5.259 11.744-11.745 0-6.486-5.258-11.744-11.744-11.744zm-60.536 31.12c-6.487 0-11.745 5.259-11.745 11.745 0 6.486 5.258 11.745 11.745 11.745 6.486 0 11.744-5.259 11.744-11.745 0-6.486-5.258-11.744-11.744-11.744zm30.04 0c-6.486 0-11.744 5.259-11.744 11.745 0 6.486 5.258 11.745 11.744 11.745 6.487 0 11.745-5.259 11.745-11.745 0-6.486-5.259-11.744-11.745-11.744z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M.667 14.667V1.333m14.666 13.334V1.333m-3 8c.828 0 1.5.673 1.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1c0-.827.672-1.5 1.5-1.5h1zm-7.666 0c.828 0 1.5.673 1.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1c0-.827.672-1.5 1.5-1.5h1zm7.666-6.666a1.5 1.5 0 011.5 1.5v1c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-7.666 0a1.5 1.5 0 011.5 1.5v1c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 941 B After Width: | Height: | Size: 602 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M.667 14v-2.167m0 0V5.167m0 6.666a1.5 1.5 0 001.5 1.5h1a1.5 1.5 0 001.5-1.5v-1a1.5 1.5 0 00-1.5-1.5h-1a1.5 1.5 0 00-1.5 1.5m0-5.666V2m0 3.167a1.5 1.5 0 001.5 1.5h1a1.5 1.5 0 001.5-1.5v-1a1.5 1.5 0 00-1.5-1.5h-1a1.5 1.5 0 00-1.5 1.5m14.666 7.666a1.5 1.5 0 01-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1a1.5 1.5 0 011.5 1.5m0 0V14m0-3.167V4.167m0 1a1.5 1.5 0 01-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1a1.5 1.5 0 011.5 1.5m0 0V2"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 600 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 0v132.292h11.207V0H0zm121.085 0v132.292h11.207V0h-11.207zM30.731 28.258c-6.486 0-11.744 5.259-11.745 11.745 0 6.486 5.259 11.744 11.745 11.744 6.486 0 11.745-5.258 11.745-11.744S37.217 28.258 30.73 28.258zm35.332 0c-6.486 0-11.744 5.259-11.744 11.745 0 6.486 5.258 11.744 11.744 11.744 6.487 0 11.745-5.258 11.745-11.744s-5.259-11.745-11.745-11.745zm35.787 0c-6.486 0-11.744 5.259-11.744 11.745 0 6.486 5.258 11.744 11.744 11.744 6.487 0 11.745-5.258 11.745-11.744s-5.258-11.745-11.745-11.745zM30.731 80.546c-6.486 0-11.744 5.258-11.745 11.744 0 6.487 5.259 11.745 11.745 11.745 6.486 0 11.745-5.258 11.745-11.745 0-6.486-5.259-11.744-11.745-11.744zm35.332 0c-6.486 0-11.744 5.258-11.744 11.744 0 6.487 5.258 11.745 11.744 11.745 6.487 0 11.745-5.258 11.745-11.745 0-6.486-5.259-11.744-11.745-11.744z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M.667 14v-2.167m0 0V5.167m0 6.666a1.5 1.5 0 001.5 1.5h1a1.5 1.5 0 001.5-1.5v-1a1.5 1.5 0 00-1.5-1.5h-1a1.5 1.5 0 00-1.5 1.5m0-5.666V2m0 3.167a1.5 1.5 0 001.5 1.5h1a1.5 1.5 0 001.5-1.5v-1a1.5 1.5 0 00-1.5-1.5h-1a1.5 1.5 0 00-1.5 1.5m14.666 7.666a1.5 1.5 0 01-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1a1.5 1.5 0 011.5 1.5m0 0V14m0-3.167V4.167m0 1a1.5 1.5 0 01-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1a1.5 1.5 0 011.5 1.5m0 0V2"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 921 B After Width: | Height: | Size: 600 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M8 14V2m5.167 7.333c.827 0 1.5.672 1.5 1.5v1c0 .828-.673 1.5-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-9.334 0a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm9.334-6.666c.827 0 1.5.672 1.5 1.5v1c0 .827-.673 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-9.334 0a1.5 1.5 0 011.5 1.5v1c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 575 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 0v132.292h11.207V0H0zm121.085 0v132.292h11.207V0h-11.207zM20.724 29.578v30.218H44.09V29.578H20.724zm33.276 0v30.218h23.366V29.578H54zm33.276 0v30.218h23.367V29.578H87.276zM20.724 71.003v31.71H44.09v-31.71H20.724zm33.276 0v31.71h23.366v-31.71H54z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M8 14V2m5.167 7.333c.827 0 1.5.672 1.5 1.5v1c0 .828-.673 1.5-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-9.334 0a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm9.334-6.666c.827 0 1.5.672 1.5 1.5v1c0 .827-.673 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-9.334 0a1.5 1.5 0 011.5 1.5v1c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 366 B After Width: | Height: | Size: 575 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M14.667 14V2M10.5 9.333a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-6.667 0a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zM10.5 2.667a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-6.667 0a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 555 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M121.085 0v132.292h11.207V0h-11.207zM20.724 29.578v30.218H44.09V29.578H20.724zm33.276 0v30.218h23.366V29.578H54zm33.276 0v30.218h23.367V29.578H87.276zM20.724 71.003v31.71H44.09v-31.71H20.724zm33.276 0v31.71h23.366v-31.71H54z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M14.667 14V2M10.5 9.333a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-6.667 0a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zM10.5 2.667a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-6.667 0a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 342 B After Width: | Height: | Size: 555 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M.667 14.667V1.333m14.666 13.334V1.333m-4 8c.828 0 1.5.673 1.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1c0-.827.672-1.5 1.5-1.5h1zm-5.666 0c.828 0 1.5.673 1.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1c0-.827.672-1.5 1.5-1.5h1zm5.666-6.666a1.5 1.5 0 011.5 1.5v1c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-5.666 0a1.5 1.5 0 011.5 1.5v1c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 602 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 0v132.292h11.207V0Zm121.085 0v132.292h11.207V0ZM36.023 28.259c-6.487 0-11.745 5.258-11.745 11.744 0 6.487 5.258 11.745 11.745 11.745 6.486 0 11.744-5.26 11.744-11.745 0-6.486-5.258-11.744-11.744-11.744zm30.04 0c-6.486 0-11.744 5.258-11.744 11.744 0 6.487 5.258 11.745 11.744 11.745 6.487 0 11.745-5.26 11.745-11.745 0-6.486-5.259-11.744-11.745-11.744zm30.496 0c-6.487 0-11.745 5.258-11.745 11.744 0 6.487 5.258 11.745 11.745 11.745 6.486 0 11.744-5.26 11.744-11.745 0-6.486-5.258-11.744-11.744-11.744zM36.023 80.545c-6.487 0-11.745 5.26-11.745 11.745 0 6.486 5.258 11.745 11.745 11.745 6.486 0 11.744-5.259 11.744-11.745 0-6.486-5.258-11.744-11.744-11.744zm30.04 0c-6.486 0-11.744 5.26-11.744 11.745 0 6.486 5.258 11.745 11.744 11.745 6.487 0 11.745-5.259 11.745-11.745 0-6.486-5.259-11.744-11.745-11.744z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M.667 14.667V1.333m14.666 13.334V1.333m-4 8c.828 0 1.5.673 1.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1c0-.827.672-1.5 1.5-1.5h1zm-5.666 0c.828 0 1.5.673 1.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1c0-.827.672-1.5 1.5-1.5h1zm5.666-6.666a1.5 1.5 0 011.5 1.5v1c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-5.666 0a1.5 1.5 0 011.5 1.5v1c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 926 B After Width: | Height: | Size: 602 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M1.333 14V2m11.834 7.333c.827 0 1.5.672 1.5 1.5v1c0 .828-.673 1.5-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-6.667 0a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm6.667-6.666c.827 0 1.5.672 1.5 1.5v1c0 .827-.673 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-6.667 0a1.5 1.5 0 011.5 1.5v1c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 580 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 0v132.292h11.207V0H0zm21.65 29.578v30.218h23.365V29.578H21.65zm33.275 0v30.218h23.367V29.578H54.925zm33.277 0v30.218h23.366V29.578H88.202zM21.649 71.003v31.71h23.366v-31.71H21.65zm33.276 0v31.71h23.367v-31.71H54.925z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M1.333 14V2m11.834 7.333c.827 0 1.5.672 1.5 1.5v1c0 .828-.673 1.5-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-6.667 0a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5h-1a1.5 1.5 0 01-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm6.667-6.666c.827 0 1.5.672 1.5 1.5v1c0 .827-.673 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1zm-6.667 0a1.5 1.5 0 011.5 1.5v1c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1a1.5 1.5 0 011.5-1.5h1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 337 B After Width: | Height: | Size: 580 B |
Before Width: | Height: | Size: 399 B After Width: | Height: | Size: 399 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m1.333.667h13.334m-13.334 14.666h13.334m-8-3c0 .828-.673 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.827 0 1.5.672 1.5 1.5zm0-7.666c0 .828-.673 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.827 0 1.5.672 1.5 1.5zm6.666 7.666c0 .828-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-7.666c0 .828-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 619 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 0v11.207h132.292V0Zm25.961 33.039c-7.54 0-13.654 6.113-13.654 13.654 0 7.541 6.113 13.654 13.654 13.654 7.541 0 13.654-6.113 13.654-13.654 0-7.54-6.113-13.654-13.654-13.654zm40.217 0c-7.541 0-13.654 6.113-13.654 13.654 0 7.541 6.113 13.654 13.654 13.654 7.541 0 13.654-6.113 13.654-13.654 0-7.54-6.113-13.654-13.654-13.654zm40.217 0c-7.541 0-13.655 6.113-13.655 13.654 0 7.541 6.114 13.654 13.655 13.654 7.54 0 13.654-6.113 13.654-13.654 0-7.54-6.113-13.654-13.654-13.654zm-80.434 38.1c-7.54 0-13.654 6.113-13.654 13.654 0 7.541 6.113 13.655 13.654 13.654 7.541 0 13.654-6.113 13.654-13.654 0-7.54-6.113-13.654-13.654-13.654zm40.217 0c-7.541 0-13.654 6.113-13.654 13.654 0 7.541 6.113 13.655 13.654 13.654 7.541 0 13.654-6.113 13.654-13.654 0-7.54-6.113-13.654-13.654-13.654ZM0 121.085v11.207h132.292v-11.207z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m1.333.667h13.334m-13.334 14.666h13.334m-8-3c0 .828-.673 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.827 0 1.5.672 1.5 1.5zm0-7.666c0 .828-.673 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.827 0 1.5.672 1.5 1.5zm6.666 7.666c0 .828-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-7.666c0 .828-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 930 B After Width: | Height: | Size: 619 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m2 .667h2.167 6.666 3.167m-9.833 14.666c-.828 0-1.5-.672-1.5-1.5v-1c0-.827.672-1.5 1.5-1.5h1c.828 0 1.5.673 1.5 1.5v1c0 .828-.672 1.5-1.5 1.5m0-14.666c.828 0 1.5.672 1.5 1.5v1c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5m6.666 14.666c-.828 0-1.5-.672-1.5-1.5v-1c0-.827.672-1.5 1.5-1.5h1c.828 0 1.5.673 1.5 1.5v1c0 .828-.672 1.5-1.5 1.5m0-14.666c.828 0 1.5.672 1.5 1.5v1c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5m-8.833 14.666h3.167 6.666 2.167"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 643 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 0v11.207h132.292V0H0zm23.845 20.868A13.654 13.654 0 0 0 10.19 34.522a13.654 13.654 0 0 0 13.655 13.655 13.654 13.654 0 0 0 13.654-13.655 13.654 13.654 0 0 0-13.654-13.654zm42.333 0a13.654 13.654 0 0 0-13.654 13.654 13.654 13.654 0 0 0 13.654 13.655 13.654 13.654 0 0 0 13.654-13.655 13.654 13.654 0 0 0-13.654-13.654zm42.333 0a13.654 13.654 0 0 0-13.654 13.654 13.654 13.654 0 0 0 13.654 13.655 13.654 13.654 0 0 0 13.654-13.655 13.654 13.654 0 0 0-13.654-13.654zM23.845 83.31A13.654 13.654 0 0 0 10.19 96.964a13.654 13.654 0 0 0 13.655 13.654 13.654 13.654 0 0 0 13.654-13.654A13.654 13.654 0 0 0 23.845 83.31zm42.333 0a13.654 13.654 0 0 0-13.654 13.654 13.654 13.654 0 0 0 13.654 13.654 13.654 13.654 0 0 0 13.654-13.654A13.654 13.654 0 0 0 66.178 83.31zM0 121.085v11.207h132.292v-11.207H0z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m2 .667h2.167 6.666 3.167m-9.833 14.666c-.828 0-1.5-.672-1.5-1.5v-1c0-.827.672-1.5 1.5-1.5h1c.828 0 1.5.673 1.5 1.5v1c0 .828-.672 1.5-1.5 1.5m0-14.666c.828 0 1.5.672 1.5 1.5v1c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5m6.666 14.666c-.828 0-1.5-.672-1.5-1.5v-1c0-.827.672-1.5 1.5-1.5h1c.828 0 1.5.673 1.5 1.5v1c0 .828-.672 1.5-1.5 1.5m0-14.666c.828 0 1.5.672 1.5 1.5v1c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5m-8.833 14.666h3.167 6.666 2.167"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 913 B After Width: | Height: | Size: 643 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m2 8h12m-7.333 5.167c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-9.334c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm6.666 9.334c0 .827-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.673-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-9.334c0 .828-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 595 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 0v11.207h132.292V0H0zm8.95 29.578v30.218h29.725V29.578H8.95zm42.333 0v30.218h29.726V29.578H51.283zm42.333 0v30.218h29.727V29.578H93.616zM8.95 71.003v31.71h29.726v-31.71H8.95zm42.334 0v31.71H81.01v-31.71H51.283zM0 121.085v11.207h132.292v-11.207H0z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m2 8h12m-7.333 5.167c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-9.334c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm6.666 9.334c0 .827-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.673-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-9.334c0 .828-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 595 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m2 14.667h12m-7.333-4.167c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-6.667c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm6.666 6.667c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-6.667c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 600 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M8.95 36.986v30.218h29.725V36.986H8.95zm42.333 0v30.218h29.726V36.986H51.283zm42.333 0v30.218h29.727V36.986H93.616zM8.95 78.411v31.711h29.726V78.411H8.95zm42.334 0v31.711H81.01V78.411H51.283zM0 121.085v11.207h132.292v-11.207H0z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m2 14.667h12m-7.333-4.167c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-6.667c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm6.666 6.667c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-6.667c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 345 B After Width: | Height: | Size: 600 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m1.333.667h13.334m-13.334 14.666h13.334m-8-4c0 .828-.673 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.827 0 1.5.672 1.5 1.5zm0-5.666c0 .828-.673 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.827 0 1.5.672 1.5 1.5zm6.666 5.666c0 .828-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-5.666c0 .828-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 619 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 0v11.207h132.292V0H0zm36.567 29.029c-5.96.092-12.09 4.407-12.289 10.974 0 6.487 5.258 11.745 11.745 11.745 6.486 0 11.744-5.26 11.744-11.745-.81-7.848-5.94-11.055-11.2-10.974zm60.536 0c-5.96.092-12.09 4.407-12.289 10.974 0 6.487 5.258 11.745 11.745 11.745 6.486 0 11.744-5.26 11.744-11.745-.81-7.848-5.94-11.055-11.2-10.974zm-30.495 0c-5.96.092-12.09 4.407-12.29 10.974 0 6.487 5.259 11.745 11.745 11.745 6.487 0 11.745-5.26 11.745-11.745-.811-7.848-5.94-11.055-11.2-10.974zM36.023 80.545c-6.487 0-11.745 5.26-11.745 11.745 0 6.486 5.258 11.745 11.745 11.745 6.486 0 11.744-5.259 11.744-11.745 0-6.486-5.258-11.744-11.744-11.744zm30.04 0c-6.486 0-11.744 5.26-11.744 11.745 0 6.486 5.258 11.745 11.744 11.745 6.487 0 11.745-5.259 11.745-11.745 0-6.486-5.26-11.744-11.745-11.744zM0 121.085v11.207h132.292v-11.207H0z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m1.333.667h13.334m-13.334 14.666h13.334m-8-4c0 .828-.673 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.827 0 1.5.672 1.5 1.5zm0-5.666c0 .828-.673 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.827 0 1.5.672 1.5 1.5zm6.666 5.666c0 .828-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-5.666c0 .828-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 934 B After Width: | Height: | Size: 619 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m2 1.333h12m-7.333 11.834c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-6.667c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm6.666 6.667c0 .827-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.673-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-6.667c0 .828-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 600 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 0v11.207h132.292V0H0zm8.95 23.228v30.218h29.725V23.228H8.95zm42.333 0v30.218h29.726V23.228H51.283zm42.333 0v30.218h29.727V23.228H93.616zM8.95 64.653v31.71h29.726v-31.71H8.95zm42.334 0v31.71H81.01v-31.71H51.283z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m2 1.333h12m-7.333 11.834c0 .827-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.673-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-6.667c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-1c0-.828.672-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm6.666 6.667c0 .827-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.673-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5zm0-6.667c0 .828-.672 1.5-1.5 1.5h-1c-.827 0-1.5-.672-1.5-1.5v-1c0-.828.673-1.5 1.5-1.5h1c.828 0 1.5.672 1.5 1.5z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 331 B After Width: | Height: | Size: 600 B |
Before Width: | Height: | Size: 400 B After Width: | Height: | Size: 400 B |
Before Width: | Height: | Size: 275 B After Width: | Height: | Size: 275 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M25.345 29.008h35.198V0h11.206v29.008h35.198v29.726H71.75v14.724h25.673v29.726H71.75v29.108H60.543v-29.108H34.87V73.458h25.673V58.734H25.345Zm46.176 9.139v11.736h25.781V38.147Zm0 44.45v11.737h16.338V82.597Z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 324 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M8 2.666h3.167c.827 0 1.5.673 1.5 1.5v1c0 .828-.673 1.5-1.5 1.5H8m0-4H4.833c-.828 0-1.5.673-1.5 1.5v1a1.5 1.5 0 001.5 1.5H8m0-4V.667m0 5.999v2.667m0 0h1.833a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5H8m0-4H6.167a1.5 1.5 0 00-1.5 1.5v1a1.5 1.5 0 001.5 1.5H8m0 0v2"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 393 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M60.543 0v29.008H25.345v29.726h35.198v14.724H34.87v29.726h25.673v29.108h11.206v-29.108h25.673V73.458H71.75V58.734h35.198V29.008H71.75V0Z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M8 2.666h3.167c.827 0 1.5.673 1.5 1.5v1c0 .828-.673 1.5-1.5 1.5H8m0-4H4.833c-.828 0-1.5.673-1.5 1.5v1a1.5 1.5 0 001.5 1.5H8m0-4V.667m0 5.999v2.667m0 0h1.833a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5H8m0-4H6.167a1.5 1.5 0 00-1.5 1.5v1a1.5 1.5 0 001.5 1.5H8m0 0v2"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 254 B After Width: | Height: | Size: 393 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M14 14.667V1.333M2 4.166c0-.827.672-1.5 1.5-1.5h6.333c.828 0 1.5.673 1.5 1.5v1a1.5 1.5 0 01-1.5 1.5H3.5a1.5 1.5 0 01-1.5-1.5v-1zm2.667 6.667a1.5 1.5 0 011.5-1.5h3.666a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5H6.167a1.5 1.5 0 01-1.5-1.5v-1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 371 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M132.292 132.292h-11.207V0h11.207Zm-23.228-29.108h-57.26V73.458h57.26zm0-44.45H35.928V29.008h73.136Z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M14 14.667V1.333M2 4.166c0-.827.672-1.5 1.5-1.5h6.333c.828 0 1.5.673 1.5 1.5v1a1.5 1.5 0 01-1.5 1.5H3.5a1.5 1.5 0 01-1.5-1.5v-1zm2.667 6.667a1.5 1.5 0 011.5-1.5h3.666a1.5 1.5 0 011.5 1.5v1a1.5 1.5 0 01-1.5 1.5H6.167a1.5 1.5 0 01-1.5-1.5v-1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 371 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2 14.7V1.4m12 2.8c0-.8-.7-1.5-1.5-1.5H6.2c-.8 0-1.5.7-1.5 1.5v1c0 .8.7 1.5 1.5 1.5h6.3c.8 0 1.5-.7 1.5-1.5v-1zm-2.7 6.6c0-.8-.7-1.5-1.5-1.5H6.2c-.8 0-1.5.7-1.5 1.5v1c0 .8.7 1.5 1.5 1.5h3.7c.8 0 1.5-.7 1.5-1.5v-1h-.1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 348 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 132.292h11.207V0H0Zm23.228-29.108h57.26V73.458h-57.26Zm0-44.45h73.136V29.008H23.228Z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2 14.7V1.4m12 2.8c0-.8-.7-1.5-1.5-1.5H6.2c-.8 0-1.5.7-1.5 1.5v1c0 .8.7 1.5 1.5 1.5h6.3c.8 0 1.5-.7 1.5-1.5v-1zm-2.7 6.6c0-.8-.7-1.5-1.5-1.5H6.2c-.8 0-1.5.7-1.5 1.5v1c0 .8.7 1.5 1.5 1.5h3.7c.8 0 1.5-.7 1.5-1.5v-1h-.1z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 205 B After Width: | Height: | Size: 348 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M132.292 0h-11.207v132.292h11.207Zm-22.699 29.008H23.228v29.726h86.365zm0 44.45H23.228v29.726h86.365zM11.207 0H0v132.292h11.207z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 246 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M29.008 25.345v35.198H0v11.206h29.008v35.198h29.726V71.75h14.724v25.673h29.726V71.75h29.108V60.543h-29.108V34.87H73.458v25.673H58.734V25.345Zm9.139 46.176h11.736v25.781H38.147Zm44.45 0h11.736v16.338H82.597Z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 324 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m11.834 12.667c.827 0 1.5-.673 1.5-1.5v-3.167-3.167c0-.828-.673-1.5-1.5-1.5h-1c-.828 0-1.5.672-1.5 1.5v3.167 3.167c0 .827.672 1.5 1.5 1.5zm-6.667-1.334c.828 0 1.5-.672 1.5-1.5v-1.833-1.833c0-.828-.672-1.5-1.5-1.5h-1c-.828 0-1.5.672-1.5 1.5v1.833 1.833c0 .828.672 1.5 1.5 1.5zm-4.5-3.333h2m10.667 0h1.999m-8.666 0h2.667"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 449 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 71.75h29.008v35.197h29.726V71.75h14.724v25.673h29.726V71.75h29.108V60.543h-29.108V34.87H73.458v25.673H58.734V25.345H29.008v35.198H0Z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m11.834 12.667c.827 0 1.5-.673 1.5-1.5v-3.167-3.167c0-.828-.673-1.5-1.5-1.5h-1c-.828 0-1.5.672-1.5 1.5v3.167 3.167c0 .827.672 1.5 1.5 1.5zm-6.667-1.334c.828 0 1.5-.672 1.5-1.5v-1.833-1.833c0-.828-.672-1.5-1.5-1.5h-1c-.828 0-1.5.672-1.5 1.5v1.833 1.833c0 .828.672 1.5 1.5 1.5zm-4.5-3.333h2m10.667 0h1.999m-8.666 0h2.667"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 253 B After Width: | Height: | Size: 449 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m11.834 2c.827 0 1.5.672 1.5 1.5v6.333c0 .828-.673 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-6.333c0-.828.672-1.5 1.5-1.5zm-6.667 2.667c.828 0 1.5.672 1.5 1.5v3.666c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-3.666c0-.828.672-1.5 1.5-1.5zm-3.834 9.333h13.334"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 397 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M132.292 132.292v-11.207H0v11.207Zm-29.108-23.228v-57.26H73.458v57.26Zm-44.45 0V35.928H29.008v73.136Z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m11.834 2c.827 0 1.5.672 1.5 1.5v6.333c0 .828-.673 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-6.333c0-.828.672-1.5 1.5-1.5zm-6.667 2.667c.828 0 1.5.672 1.5 1.5v3.666c0 .828-.672 1.5-1.5 1.5h-1c-.828 0-1.5-.672-1.5-1.5v-3.666c0-.828.672-1.5 1.5-1.5zm-3.834 9.333h13.334"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 219 B After Width: | Height: | Size: 397 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m11.8 14c.8 0 1.5-.7 1.5-1.5v-6.3c0-.8-.7-1.5-1.5-1.5h-1c-.8 0-1.5.7-1.5 1.5v6.3c0 .8.7 1.5 1.5 1.5zm-6.6-2.7c.8 0 1.5-.7 1.5-1.5v-3.6c0-.8-.7-1.5-1.5-1.5h-1c-.8 0-1.5.7-1.5 1.5v3.7c0 .8.7 1.5 1.5 1.5h1zm-3.9-9.3h13.3"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 348 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 0v11.207h132.292V0Zm29.108 23.228v57.26h29.726v-57.26Zm44.45 0v73.136h29.726V23.228Z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="m11.8 14c.8 0 1.5-.7 1.5-1.5v-6.3c0-.8-.7-1.5-1.5-1.5h-1c-.8 0-1.5.7-1.5 1.5v6.3c0 .8.7 1.5 1.5 1.5zm-6.6-2.7c.8 0 1.5-.7 1.5-1.5v-3.6c0-.8-.7-1.5-1.5-1.5h-1c-.8 0-1.5.7-1.5 1.5v3.7c0 .8.7 1.5 1.5 1.5h1zm-3.9-9.3h13.3"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 205 B After Width: | Height: | Size: 348 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 0v11.207h132.292V0H0zm29.008 22.699v86.365h29.726V22.699H29.008zm44.45 0v86.365h29.726V22.699H73.458zM0 121.085v11.207h132.292v-11.207H0z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 258 B |
Before Width: | Height: | Size: 258 B After Width: | Height: | Size: 258 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 500 500">
|
||||
<path d="M159.08979 409.09297h68.18196V500h45.45488v-90.90703h68.18198l-90.90942-90.91044zM340.90861 90.909169h-68.18198V-7.8e-7h-45.45488V90.909169h-68.18196l90.9094 90.909421zM68.180615 227.27312V272.728H431.81938v-45.45488z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 327 B |
Before Width: | Height: | Size: 257 B After Width: | Height: | Size: 257 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M50.704 22.964V60.59H0v11.206h50.704v37.532H80.43V71.796h51.862V60.59H80.43V22.964H50.704zm8.794 48.9h12.688v28.855H59.498V71.865z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 248 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M14.667 14.667H1.333m7.334-14a2 2 0 012 2v6.666a2 2 0 01-2 2H7.333c-1.103 0-2-.896-2-2V2.667c0-1.104.897-2 2-2h1.334z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 248 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M132.292 132.292v-11.207H0v11.207Zm-50.704-22.699V23.228H51.862v86.365z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M14.667 14.667H1.333m7.334-14a2 2 0 012 2v6.666a2 2 0 01-2 2H7.333c-1.103 0-2-.896-2-2V2.667c0-1.104.897-2 2-2h1.334z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 189 B After Width: | Height: | Size: 248 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M15.333 8h-4.666m0 0V4.667c0-1.104-.897-2-2-2H7.333a2 2 0 00-2 2V8m5.334 0v3.333c0 1.104-.897 2-2 2H7.333a2 2 0 01-2-2V8m0 0H.667"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 260 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M0 60.59v11.206h132.292V60.59Zm50.704-37.626v86.364H80.43V22.964Z"/>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M15.333 8h-4.666m0 0V4.667c0-1.104-.897-2-2-2H7.333a2 2 0 00-2 2V8m5.334 0v3.333c0 1.104-.897 2-2 2H7.333a2 2 0 01-2-2V8m0 0H.667"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 183 B After Width: | Height: | Size: 260 B |
|
@ -1,3 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||
<path d="M132.292 132.292v-11.207H0v11.207Zm-50.704-22.699V23.228H51.862v86.365zm50.704-98.386V0H0v11.207z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 215 B |
Before Width: | Height: | Size: 254 B After Width: | Height: | Size: 254 B |