19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:31:39 +01:00
parent 5df8c07b59
commit daa394e8b0
2114 changed files with 564841 additions and 299642 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Before After
Before After

View file

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="70" height="70" viewBox="0 0 70 70"><defs><path id="a" d="M4 0h61c4 0 5 1 5 5v60c0 4-1 5-5 5H4c-3 0-4-1-4-5V5c0-4 1-5 4-5z"/><linearGradient id="c" x1="100%" x2="0%" y1="0%" y2="98.616%"><stop offset="0%" stop-color="#797C79"/><stop offset="100%" stop-color="#545554"/></linearGradient><path id="d" d="M16.995 35.708c-2.743 1.538-2.48 5.47.455 6.638L26.564 46c.611 7.72 1.423 11.72 2.436 12 .948.262 3.602-2.35 7.962-7.835l8.923 3.57c.47.185.965.278 1.46.278.653 0 1.299-.163 1.881-.48a3.736 3.736 0 0 0 1.906-2.665C54.969 28.136 56.548 16.513 55.868 16c-.77-.582-13.728 5.987-38.873 19.708zm13.397 16.813v-4.99l2.918 1.166-2.918 3.824zm16.952-2.217L35.08 45.398l11.18-15.631c.853-1.198-.758-2.589-1.89-1.638l-16.865 14.24-8.596-3.446 33.172-18.544-4.737 29.925z"/><path id="e" d="M16.995 33.708c-2.743 1.538-2.48 5.47.455 6.638L26.564 44c.611 7.72 1.423 11.72 2.436 12 .948.262 3.602-2.35 7.962-7.835l8.923 3.57c.47.185.965.278 1.46.278.653 0 1.299-.163 1.881-.48a3.736 3.736 0 0 0 1.906-2.665C54.969 26.136 56.548 14.513 55.868 14c-.77-.582-13.728 5.987-38.873 19.708zm13.397 16.813v-4.99l2.918 1.166-2.918 3.824zm16.952-2.217L35.08 43.398l11.18-15.631c.853-1.198-.758-2.589-1.89-1.638l-16.865 14.24-8.596-3.446 33.172-18.544-4.737 29.925z"/></defs><g fill="none" fill-rule="evenodd"><mask id="b" fill="#fff"><use xlink:href="#a"/></mask><g mask="url(#b)"><path fill="url(#c)" d="M0 0H70V70H0z"/><path fill="#FFF" fill-opacity=".383" d="M4 1h61c2.667 0 4.333.667 5 2V0H0v3c.667-1.333 2-2 4-2z"/><path fill="#393939" d="M40.1 69H4c-2 0-4-.146-4-4.078V47.679L15.8 35 54 17l-3.062 32.732L40.1 69z" opacity=".324"/><path fill="#000" fill-opacity=".383" d="M4 69h61c2.667 0 4.333-1 5-3v4H0v-4c.667 2 2 3 4 3z"/><use fill="#000" fill-rule="nonzero" opacity=".3" xlink:href="#d"/><use fill="#FFF" fill-rule="nonzero" xlink:href="#e"/></g></g></svg>
<svg width="50" height="50" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg"><path d="M41.845 4.447 5.18 28.487c-1.844 1.21-1.455 3.961.655 4.638L42.5 44.878c1.725.553 3.5-.702 3.5-2.475V6.61c0-2.084-2.383-3.324-4.155-2.162Z" fill="#2EBCFA"/><path d="m44.671 4.348-18.15 35.408 17.73 5.684c.862.276 1.75-.351 1.75-1.238L46 6.281s-.12-.688-.469-1.175c-.318-.445-.86-.758-.86-.758Z" fill="#985184"/><path d="M13.885 35.634 44.67 4.342 23.322 46l-9.437-10.366Z" fill="#144496"/></svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 488 B

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -1,12 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800" height="600">
<defs>
<clipPath id="clip-path" clipPathUnits="objectBoundingBox">
<use xlink:href="#filterPath" fill="none"></use>
</clipPath>
<path id="filterPath" d="M0.5,1C-0.1667,0.9795-0.1667,0.0203,0.5,0C1.1667,0.0205,1.1667,0.9797,0.5,1z"></path>
</defs>
<svg viewBox="0 0 1 1" id="preview" preserveAspectRatio="none">
<use xlink:href="#filterPath" fill="darkgrey"></use>
</svg>
<image xlink:href="" clip-path="url(#clip-path)"></image>
</svg>

Before

Width:  |  Height:  |  Size: 561 B

View file

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="800" height="600">
<defs><clipPath id="clip-path" clipPathUnits="objectBoundingBox"><use xlink:href="#filterPath" fill="none"></use></clipPath><path id="filterPath" d="M0.4128,0h0.5872L0.5872,1H0L0.4128,0z"></path></defs><svg viewBox="0 0 1 1" id="preview" preserveAspectRatio="none"><use xlink:href="#filterPath" fill="darkgrey"></use></svg><image xlink:href="" clip-path="url(#clip-path)"></image></svg>

Before

Width:  |  Height:  |  Size: 511 B

View file

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="800" height="600">
<defs><clipPath id="clip-path" clipPathUnits="objectBoundingBox"><use xlink:href="#filterPath" fill="none"></use></clipPath><path id="filterPath" d="M1,1L0,0h1V1z"></path></defs><svg viewBox="0 0 1 1" id="preview" preserveAspectRatio="none"><use xlink:href="#filterPath" fill="darkgrey"></use></svg><image xlink:href="" clip-path="url(#clip-path)"></image></svg>

Before

Width:  |  Height:  |  Size: 487 B

View file

@ -0,0 +1,7 @@
<svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M59 16.5V47L31.5 63L5 47.5V17L32.5 1L59 16.5Z" fill="#FFFFFF"/>
<path d="M46.9997 9.49988L50.9997 11.9999L23.6344 28.037L31.2458 32.4774V62.5331L5.31119 47.4052V17.3485L16.0993 23.6415L43.1598 7.52332L46.9997 9.49988Z" fill="#3AADAA"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M46.9481 9.61765C47.0126 9.72617 46.9769 9.86642 46.8684 9.93091L20.0541 25.8636C19.9456 25.9281 19.8054 25.8924 19.7409 25.7839C19.6764 25.6753 19.7121 25.5351 19.8206 25.4706L46.6348 9.5379C46.7434 9.47342 46.8836 9.50912 46.9481 9.61765Z" fill="#383E45"/>
<path d="M20.5908 37.6041L12.7501 33.1309C11.8956 32.6283 11.3427 31.7236 11.3427 30.7184C11.3427 29.6126 12.549 28.909 13.504 29.4619L21.797 34.2367C22.5007 34.6387 22.953 35.4429 22.953 36.2471C23.0033 37.4534 21.6462 38.2073 20.5908 37.6041Z" fill="#383E45"/>
<path d="M32.7539 1.46647L58.6886 16.595V46.6511L31.2461 62.5335L5.31144 47.405V17.3489L32.7539 1.46647ZM32.7557 0.409058L4.39716 16.8217V47.9301L31.2443 63.591L59.6029 47.1783V16.0699L32.7557 0.409058Z" fill="#383E45"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -0,0 +1,14 @@
<svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M46.1574 46.4595L42.8079 44.513L36.2025 37.3103L39.552 39.2568L46.1574 46.4595Z" fill="#FBDBD0"/>
<path d="M46.1575 46.6881C46.0945 46.6881 46.0329 46.662 45.989 46.614L39.3836 39.4113C39.3031 39.3234 39.3037 39.1883 39.385 39.1011C42.4569 35.804 45.0001 31.7863 46.7403 27.4821C46.7696 27.4093 46.8343 27.3569 46.9115 27.3428C46.9249 27.3404 46.9385 27.3392 46.9521 27.3392C47.0155 27.3392 47.0769 27.3656 47.1207 27.4133L54.3577 35.3033C54.4093 35.3596 54.4294 35.4379 54.4113 35.512C54.3932 35.5861 54.3392 35.6464 54.2673 35.6725L47.6041 38.0993L46.3836 46.4924C46.3709 46.5799 46.3091 46.6519 46.2249 46.6781C46.2026 46.6848 46.18 46.6881 46.1575 46.6881Z" fill="white"/>
<path d="M46.9521 27.5679L54.1892 35.4577L47.3975 37.9313L46.1574 46.4595L39.552 39.2568C42.6392 35.9434 45.2241 31.8423 46.9521 27.5679ZM46.9521 27.1107C46.9251 27.1107 46.8978 27.1131 46.8707 27.118C46.7163 27.146 46.5871 27.2511 46.5283 27.3965C44.8234 31.6137 42.227 35.7151 39.2175 38.9452C39.0549 39.1197 39.0538 39.39 39.2151 39.5658L45.8205 46.7685C45.9084 46.8644 46.0313 46.9166 46.1574 46.9166C46.2023 46.9166 46.2477 46.9101 46.292 46.8964C46.4607 46.8444 46.5843 46.7 46.6098 46.5253L47.8106 38.2673L54.3457 35.8872C54.4891 35.835 54.5971 35.7146 54.6333 35.5662C54.6695 35.4179 54.6293 35.2613 54.5261 35.1487L47.289 27.2588C47.2016 27.1636 47.079 27.1107 46.9521 27.1107Z" fill="#374874"/>
<path d="M21.228 60.8524L17.8786 58.9059L16.5942 51.8352L19.9437 53.7817L21.228 60.8524Z" fill="#FBDBD0"/>
<path d="M13.1603 59.1457L9.81079 57.1993L16.476 42.1309L19.8254 44.0774L13.1603 59.1457Z" fill="#FBDBD0"/>
<path d="M21.2009 61.0794C21.1011 61.0676 21.021 60.9919 21.0029 60.8932L19.7869 54.197L13.3018 59.3249C13.2603 59.3578 13.2103 59.3743 13.1601 59.3743C13.1107 59.3743 13.0614 59.3584 13.0201 59.3265C12.9371 59.262 12.9085 59.1493 12.9511 59.0533L19.6163 43.985C19.6473 43.9144 19.7121 43.8645 19.7882 43.8519C19.8005 43.8497 19.813 43.8488 19.8253 43.8488C19.8886 43.8488 19.95 43.8751 19.9936 43.9227C21.502 45.5658 23.5525 46.4341 25.9235 46.4341C26.4424 46.4341 26.9815 46.3923 27.5257 46.3098C27.5373 46.308 27.5487 46.3071 27.5601 46.3071C27.6306 46.3071 27.698 46.3399 27.7418 46.3968C27.7925 46.4631 27.803 46.5517 27.769 46.6281L21.4369 60.9448C21.4 61.0283 21.3177 61.081 21.2279 61.081C21.219 61.081 21.2101 61.0805 21.2009 61.0794Z" fill="white"/>
<path d="M19.8253 44.0774C21.3733 45.7635 23.4719 46.6626 25.9234 46.6626C26.4533 46.6626 26.9992 46.6207 27.5601 46.5356L21.228 60.8525L19.9437 53.7818L13.1602 59.1458L19.8253 44.0774ZM19.8253 43.6203C19.8007 43.6203 19.7758 43.6223 19.7511 43.6263C19.5989 43.6514 19.4696 43.7515 19.4072 43.8925L12.7421 58.9608C12.6571 59.153 12.7141 59.3785 12.8802 59.5071C12.9626 59.571 13.0614 59.6029 13.1602 59.6029C13.2604 59.6029 13.3606 59.57 13.4437 59.5043L19.6299 54.6126L20.7782 60.9341C20.8141 61.1317 20.9746 61.2827 21.174 61.3064C21.1921 61.3085 21.2103 61.3096 21.2282 61.3096C21.4074 61.3096 21.5722 61.2042 21.6461 61.0374L27.9781 46.7204C28.0456 46.5678 28.0246 46.3905 27.9233 46.258C27.836 46.1438 27.7012 46.0784 27.5601 46.0784C27.5373 46.0784 27.5144 46.0801 27.4915 46.0836C26.9584 46.1644 26.4309 46.2055 25.9234 46.2055C23.6182 46.2055 21.626 45.3626 20.1621 43.7682C20.0747 43.6732 19.9522 43.6203 19.8253 43.6203Z" fill="#374874"/>
<path d="M41.2172 4.23825C38.279 2.53078 34.2101 2.77128 29.7196 5.36388C20.7944 10.5168 13.5843 23.0069 13.6134 33.2609C13.6244 37.1606 14.6804 40.1751 16.476 42.1309C17.0262 42.7302 17.6459 43.2301 18.3264 43.6255L21.6758 45.572C20.9954 45.1766 20.3757 44.6767 19.8254 44.0774C18.0298 42.1216 16.9739 39.1071 16.9628 35.2074C16.9338 24.9533 24.1438 12.4633 33.069 7.31037C37.5596 4.71773 41.6285 4.4772 44.5667 6.18474L41.2172 4.23825Z" fill="#FBDBD0"/>
<path d="M25.9231 46.8912C23.4208 46.891 21.2541 45.9716 19.657 44.2321C17.7556 42.1609 16.7449 39.0406 16.7342 35.208C16.705 24.8966 23.9815 12.293 32.9547 7.11242C35.5371 5.62156 38.0148 4.86554 40.319 4.86554C43.032 4.86554 45.3269 5.93406 46.9554 7.95528C48.6159 10.0164 49.499 12.9876 49.509 16.5481C49.5188 19.9946 48.7079 23.8345 47.1639 27.6535C45.4032 32.0089 42.8289 36.0751 39.7193 39.4126C37.688 41.593 35.5244 43.3531 33.2885 44.6439C31.3338 45.7725 29.4179 46.4847 27.5945 46.7613C27.0273 46.8475 26.4648 46.8912 25.9231 46.8912Z" fill="white"/>
<path d="M40.3189 5.09411C45.6134 5.09411 49.2598 9.28819 49.2804 16.5487C49.2905 20.0866 48.4384 23.8912 46.9521 27.5678C45.2241 31.8422 42.6391 35.9434 39.552 39.2568C37.5971 41.355 35.4406 43.1374 33.1742 44.4458C31.2011 45.585 29.31 46.27 27.5601 46.5355C26.9994 46.6206 26.4531 46.6626 25.9234 46.6626C23.4718 46.6626 21.3735 45.7635 19.8253 44.0773C18.0297 42.1216 16.9738 39.1071 16.9627 35.2073C16.9337 24.9533 24.1438 12.4633 33.0689 7.31033C35.674 5.80627 38.1361 5.09411 40.3189 5.09411ZM40.3189 4.63696C37.974 4.63696 35.4579 5.4032 32.8403 6.91447C28.4555 9.44606 24.3436 13.7798 21.2621 19.1174C18.1805 24.455 16.4913 30.1697 16.5056 35.2086C16.5166 39.0994 17.5481 42.273 19.4886 44.3865C21.1302 46.1746 23.3554 47.1197 25.9234 47.1197C26.4767 47.1197 27.0504 47.0752 27.6286 46.9875C29.4807 46.7065 31.4234 45.9846 33.4028 44.8418C35.658 43.5397 37.8394 41.7655 39.8864 39.5684C43.0149 36.2106 45.6048 32.1201 47.3759 27.7392C48.9308 23.893 49.7474 20.0229 49.7375 16.5475C49.7273 12.9345 48.8268 9.91376 47.1333 7.81193C45.4599 5.73486 43.1035 4.63696 40.3189 4.63696Z" fill="#374874"/>
<path d="M33.0825 12.0887C39.7092 8.26271 45.1004 11.335 45.122 18.9496C45.1436 26.5661 39.7874 35.8415 33.1607 39.6675C26.5324 43.4943 21.1428 40.423 21.1212 32.8065C21.0996 25.1919 26.4542 15.9156 33.0825 12.0887ZM39.8434 32.5422L38.5402 24.7193L43.9376 15.5282L36.4516 18.6L33.0843 12.7407L29.7597 22.4636L22.2823 28.031L27.7125 30.9706L26.4594 40.2694L33.14 32.3631L39.8434 32.5422Z" fill="#C1DBF6"/>
<path d="M36.9695 3.14758C38.5496 3.14763 39.9833 3.52119 41.2172 4.23821L44.5666 6.18475C44.558 6.17972 44.5492 6.17527 44.5405 6.17031C47.4563 7.84982 49.266 11.4397 49.2804 16.5488C49.2905 20.0867 48.4384 23.8913 46.9521 27.5679L54.1892 35.4576L47.3975 37.9312L46.1574 46.4595L42.8079 44.5131L38.7492 40.0873C37.0124 41.8262 35.1348 43.3139 33.1742 44.4459C31.2011 45.585 29.31 46.27 27.5601 46.5355L21.2281 60.8524L17.8786 58.9059L17.3241 55.8532L13.1602 59.1457L9.81075 57.1992L16.4759 42.1308C14.6803 40.1751 13.6244 37.1606 13.6133 33.2608C13.5843 23.0068 20.7943 10.5168 29.7195 5.36386C32.3244 3.85991 34.7868 3.14742 36.9695 3.14758ZM36.9696 2.23328C34.5436 2.23312 31.9506 3.02 29.2624 4.57207C24.8091 7.14315 20.6378 11.5364 17.5168 16.9423C14.3955 22.3487 12.6846 28.145 12.6991 33.2634C12.7097 36.9994 13.6435 40.1037 15.4063 42.2889L8.97464 56.8294C8.78609 57.2557 8.94842 57.7555 9.35141 57.9898L12.7009 59.9363C12.8436 60.0192 13.0022 60.06 13.1601 60.06C13.3617 60.06 13.5622 59.9935 13.7273 59.8629L16.6967 57.5149L16.9791 59.0693C17.0269 59.3327 17.1878 59.5619 17.4193 59.6965L20.7687 61.6429C20.9097 61.7249 21.0684 61.7667 21.2281 61.7667C21.323 61.7667 21.4183 61.7519 21.5105 61.722C21.7577 61.6417 21.9591 61.46 22.0643 61.2222L28.1981 47.3536C29.9541 47.0174 31.7793 46.3069 33.6314 45.2376C35.3715 44.233 37.077 42.9441 38.7118 41.3992L42.1341 45.131C42.1965 45.199 42.2688 45.2572 42.3486 45.3036L45.698 47.2501C45.8397 47.3324 45.9984 47.3738 46.1574 47.3738C46.2932 47.3738 46.4292 47.3436 46.555 47.2828C46.8285 47.1508 47.0185 46.8916 47.0622 46.5911L48.2237 38.6034L54.5021 36.3167C54.7891 36.2122 55.0049 35.9713 55.0774 35.6747C55.1499 35.3779 55.0694 35.0647 54.863 34.8396L48.0128 27.3717C49.4511 23.6489 50.2043 19.9177 50.1948 16.5462C50.1798 11.2815 48.3446 7.32297 45.0258 5.39474L45.026 5.39424L41.6766 3.4477C40.2901 2.64201 38.7064 2.23334 36.9696 2.23328Z" fill="#374874"/>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

View file

@ -0,0 +1,13 @@
<svg viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M51.64 2.91429C51.8917 2.91429 52.1434 2.97943 52.369 3.10971L53.9691 4.03422C54.4196 4.29449 54.6971 4.77518 54.6973 5.29543L54.7081 36.4299C54.7083 36.9499 54.4314 37.4305 53.9816 37.6912L12.7133 61.6054C12.4873 61.7363 12.235 61.8017 11.9826 61.8017C11.7309 61.8017 11.4792 61.7366 11.2537 61.6063L9.65342 60.6817C9.20295 60.4214 8.92539 59.9407 8.92521 59.4205L8.91426 28.2923C8.91408 27.7725 9.1909 27.2918 9.64071 27.0311L50.9093 3.11074C51.1352 2.97977 51.3876 2.91429 51.64 2.91429ZM51.64 2C51.2229 2 50.8117 2.11054 50.4508 2.3197L9.18222 26.2401C8.45271 26.663 7.9997 27.4495 8 28.2927L8.01095 59.4209C8.01125 60.2647 8.46535 61.0512 9.19605 61.4733L10.7963 62.3979C11.1565 62.606 11.5667 62.716 11.9827 62.716C12.3997 62.716 12.8108 62.6055 13.1717 62.3964L54.44 38.4823C55.1696 38.0595 55.6227 37.2729 55.6224 36.4296L55.6117 5.29513C55.6114 4.45125 55.1573 3.66475 54.4265 3.24256L52.8264 2.31806C52.4662 2.10997 52.0559 2 51.64 2Z" fill="#374874"/>
<path d="M54.6971 4.45477L51.6389 2.68787L8.91406 27.4524L11.9723 29.2193L54.6971 4.45477Z" fill="white"/>
<path d="M11.9838 62.0281L8.92561 60.2612L8.91406 27.4524L11.9723 29.2193L11.9838 62.0281Z" fill="#FBDBD0"/>
<path d="M11.9837 62.0281L54.7084 37.2701L54.6968 4.4613L11.9722 29.2193L11.9837 62.0281Z" fill="white"/>
<path d="M19.403 30.8112L20.6012 33.2991L23.5904 31.9066L21.3418 35.5034L21.991 38.5143L19.403 38.2493L16.815 41.5026L17.4642 37.7421L15.2155 36.7419L18.2047 34.6828L19.403 30.8112Z" fill="#374874"/>
<path d="M28.796 25.3882L29.9943 27.8762L32.9835 26.4836L30.7348 30.0804L31.384 33.0913L28.796 32.8263L26.208 36.0797L26.8572 32.3191L24.6086 31.3189L27.5978 29.2598L28.796 25.3882Z" fill="#374874"/>
<path d="M38.1891 19.9651L39.3873 22.4531L42.3766 21.0605L40.1279 24.6573L40.7771 27.6682L38.1891 27.4032L35.6011 30.6566L36.2503 26.896L34.0016 25.8958L36.9909 23.8367L38.1891 19.9651Z" fill="#374874"/>
<path d="M47.5822 14.5421L48.7804 17.03L51.7696 15.6374L49.521 19.2342L50.1702 22.2451L47.5822 21.9801L44.9942 25.2335L45.6434 21.4729L43.3947 20.4727L46.3839 18.4136L47.5822 14.5421Z" fill="#374874"/>
<path d="M19.403 43.0131L20.6012 45.501L23.5904 44.1085L21.3418 47.7053L21.991 50.7162L19.403 50.4512L16.815 53.7045L17.4642 49.944L15.2155 48.9438L18.2047 46.8847L19.403 43.0131Z" fill="#374874"/>
<path d="M28.796 37.59L29.9943 40.0779L32.9835 38.6854L30.7348 42.2822L31.384 45.2931L28.796 45.0281L26.208 48.2815L26.8572 44.5209L24.6086 43.5207L27.5978 41.4616L28.796 37.59Z" fill="#374874"/>
<path d="M38.776 31.8281L39.9743 34.316L42.9635 32.9235L40.7148 36.5202L41.364 39.5311L38.776 39.2661L36.188 42.5195L36.8372 38.7589L34.5885 37.7587L37.5778 35.6996L38.776 31.8281Z" fill="#374874"/>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -0,0 +1,243 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 585 555" style="enable-background:new 0 0 585 555;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.15;}
.st1{fill:#2D3142;}
.st2{fill:#FCB7A0;}
.st3{fill:#DC8173;}
.st4{fill:#1A4E66;}
.st5{fill:#FFFFFF;}
.st6{fill:#0D323F;}
.st7{fill:#714B67;}
.st8{fill:#3B3B3B;}
.st9{fill:#EAF3F3;}
.st10{fill:#CCC9C6;}
</style>
<g id="Master_x2F_Spot_Illustrations_x2F_Phone">
<g id="Background" transform="scale(1 1)">
<g id="Background_x2F_Boom" class="st0">
<g id="Group" transform="translate(13.000000, 46.000000)">
<path id="Shape" class="st1" d="M488.1,338.7c-5.5-13.7-10.4-27.5-15.1-40.7c-4.8-13.5-9.7-27.5-15.3-41.4L440.6,214
c4.5-1.4,15.3-4.9,22.6-7.7c4.9-1.9,10.1-3.8,15.1-5.6c10.5-3.7,21.3-7.5,31.2-12.7c0.7-0.4,1.1-1.1,1.1-1.9
c-0.1-0.8-0.6-1.5-1.3-1.7c-13.7-4.8-27-9.8-39.9-14.6c-13.6-5-27.5-10.3-41.8-15.2c18.1-19.2,38.4-36.9,58.1-54.1
c16.7-14.6,33.9-29.6,49.8-45.6c0.6-0.6,0.8-1.5,0.4-2.3s-1.2-1.2-2.1-1.1c-0.9,0.2-93,14.3-115.1,18.5
c-9.1,1.7-17.8,3.3-26.2,4.8c-23.8,4.3-46.3,8.3-75.7,15.4c3.7-22.7,4.6-49.2,5-72.3c0-0.8-0.5-1.5-1.2-1.9
c-0.7-0.3-1.6-0.2-2.2,0.4C304.7,29.7,268.9,63.5,262,70c-6.7-4.8-22-21.8-34.5-35.6c-8-8.8-14.8-16.4-19-20.4
c-12.1-11.8-22.2-23.3-33.8-36.7c-5.2-5.9-10.5-12.1-16.4-18.7c-0.6-0.6-1.5-0.8-2.3-0.5c-0.8,0.4-1.3,1.2-1.2,2
c1.4,12.1,2.8,24.4,4.3,36.9c3.8,31.6,7.6,64.3,11,97c-7.9-5.5-17.4-13.5-17.5-13.6c-0.7-0.5-1.6-0.6-2.3-0.2
c-0.7,0.5-1.1,1.3-0.9,2.2c0.3,1.3,7.7,28.6,12.7,43.2c-5.2-1.4-10.5-3-16-4.6c-15.7-4.7-31.9-9.5-47.5-11.4
c-0.6-0.1-1.2,0.1-1.6,0.5c-0.4,0.4-0.7,1-0.6,1.6c0.7,11.3,3.4,23,6.1,34.3c0.8,3.2,1.6,6.5,2.3,9.8c1.9,8.6,3.7,17.7,5.6,27.3
c2,10.3,4.1,21,6.6,32c-7,0.5-15.7,0.7-24.2,0.9c-4.9,0.1-9.5,0.2-13.5,0.4c-13.8,0.6-30,1.7-46.7,5.9c-0.7,0.2-1.3,0.7-1.4,1.4
c-0.2,0.7,0,1.4,0.5,1.9c7.5,7.4,17.5,14.9,27.1,22c7.9,5.9,16,11.9,22.7,17.9c8.3,7.5,35,35.1,40.6,41
c-9.6,16-21.8,30.9-33.6,45.4c-6.2,7.6-12.5,15.4-18.5,23.2l-1.1,1.5c-12.4,16.6-25.2,33.6-37.1,50.9
c-5.4,7.8-16.4,25.3-16.5,25.4c-0.5,0.7-0.4,1.7,0.2,2.4c0.6,0.7,1.5,0.9,2.3,0.6c11.1-4.6,22.3-9.9,33.1-15.1
c5.6-2.6,11.3-5.4,16.9-7.9c13.5-6.2,70.1-28.5,86.5-35l-19.9,45.5c-0.3,0.8-0.2,1.7,0.5,2.3c0.6,0.6,1.5,0.7,2.3,0.3
c19.3-9.7,36.9-22.2,54-34.2c5.8-4.1,11.2-7.9,16.6-11.6c19.8-13.4,55-46.4,62.9-53.9c15.8,20.4,28.9,35.5,41.1,47.3
c4.6,4.4,9.3,9.7,14.3,15.2c9.2,10.2,19.7,21.8,31.9,31.1c0.5,0.4,1.3,0.5,1.9,0.3c0.6-0.2,1.1-0.8,1.3-1.4
c1.1-4.8,2.2-9.6,3.2-14.2c6.9-30.2,12.9-56.5,13-85.3c15.5,9,45.3,30.6,67.4,46.7c13.1,9.5,23.4,17,28,19.9
c11.3,7.2,36.5,21.2,36.8,21.3c0.7,0.4,1.5,0.3,2.1-0.1c0.6-0.5,0.9-1.2,0.8-2C507,395.3,497.9,363,488.1,338.7z M398.4,305
c-0.7,0.7-1.7,0.8-2.5,0.3c-12.5-8-26.1-14.9-39.3-21.7c-10.9-5.6-22.1-11.3-32.6-17.6c-1.4,23.7-3,50.4-6,73.4
c-0.1,0.8-0.7,1.4-1.4,1.7c-0.2,0.1-0.4,0.1-0.6,0.1c-0.6,0-1.2-0.3-1.5-0.7c-6.1-7.3-11.1-15.2-16-22.7c-1.5-2.3-3-4.6-4.5-6.9
c-3.4-5.1-14.8-25.1-18.2-31c-9.1,4.5-52.7,25.6-65,31.2c-5.9,2.7-12.4,5.3-18.7,7.8c-9.1,3.7-18.6,7.5-26.7,11.7
c-0.8,0.4-1.8,0.2-2.4-0.5c-0.6-0.7-0.6-1.7-0.1-2.5c0.2-0.2,17.8-21.6,26.8-31.1c6.2-6.5,22.4-26,26.2-30.6
c-2.5-5.1-12.4-25.2-16.2-34.9c-1.2-3.1-2.5-6.2-3.8-9.4c-3.3-8.1-6.7-16.4-9.5-24.6c-0.2-0.7-0.1-1.5,0.4-2
c0.5-0.6,1.3-0.8,2-0.6c12.6,3.1,33.7,11.4,42,14.7c-0.8-4.1-1.6-8.2-2.4-12.3c-3.7-19.3-7.2-37.5-11.3-54.3
c-2.3-9.4-4.9-20.7-7.3-31.5c-1.9-8.3-3.7-16.2-5.3-23.1c-0.2-0.9,0.1-1.7,0.9-2.2c0.7-0.5,1.7-0.4,2.4,0.2
c23,20,44.6,43,59.7,63.7c3.9-6.7,7.8-12.2,11.5-17.7c4.1-5.8,7.9-11.8,11.4-18c0.4-0.7,1.2-1.1,2-1c0.8,0.1,1.5,0.7,1.7,1.5
c1,4.4,1.9,9.2,2.8,13.9c1.2,7.3,2.8,14.5,4.8,21.7c24.7-11.3,52.4-16.7,79.2-21.9c4.6-0.9,9.2-1.8,13.7-2.7
c0.8-0.2,1.6,0.2,2.1,0.9c0.4,0.7,0.4,1.6-0.1,2.3c-9.7,13-20.7,25.3-31.3,37.2c-10.2,11.4-20.7,23.2-29.8,35.3
c14.6,17,27.9,36.2,36.6,52.9c1.4,2.6,2.8,5.3,4.2,8c7.2,13.9,14.7,28.3,22.5,40.8C399.2,303.3,399.1,304.3,398.4,305z"/>
<path id="Path" class="st1" d="M562.8,316.7c-0.4-0.2-10.3-5-18.5-6.6c-2.3-0.5-4.6,0.3-6.2,2c-1.5,1.7-2,4.2-1.3,6.4
c0.7,2.2,2.6,3.9,4.9,4.3c6.6,1.4,15.4,5.6,15.5,5.6c2.1,1.1,4.6,0.9,6.6-0.4c2-1.3,3.1-3.6,2.9-5.9
C566.4,319.7,564.9,317.7,562.8,316.7L562.8,316.7z"/>
<path id="Path_1_" class="st1" d="M526.6,126.1c0.5,3.2,3.2,5.5,6.4,5.5c0.3,0,0.7,0,1-0.1l18.5-2.9c3.5-0.6,6-3.9,5.4-7.4
c-0.6-3.5-3.9-6-7.4-5.4l-18.6,2.9C528.4,119.2,526,122.5,526.6,126.1z"/>
<path id="Path_2_" class="st1" d="M352-16.9c0.3,0.1,0.7,0.1,1,0.1c3.2,0,6-2.4,6.4-5.6l2.1-14.8c0.4-2.3-0.5-4.7-2.4-6.1
c-1.8-1.5-4.3-1.8-6.5-1c-2.2,0.9-3.7,2.9-4,5.2l-2.1,14.8c-0.3,1.7,0.2,3.4,1.2,4.8C348.8-18.1,350.3-17.2,352-16.9z"/>
<path id="Path_3_" class="st1" d="M387.8,14.4c3.1,1.9,7.1,0.9,8.9-2.2l7.6-12.4c1.9-3.1,0.9-7.1-2.1-9
c-3.1-1.9-7.1-0.9-8.9,2.1l-7.6,12.4c-0.9,1.5-1.2,3.3-0.8,4.9S386.3,13.5,387.8,14.4L387.8,14.4z"/>
<path id="Path_4_" class="st1" d="M118.1,30.7c1.6,3.2,5.5,4.5,8.7,2.8c3.2-1.6,4.5-5.5,2.9-8.7l-5.5-10.9
c-1.6-3.2-5.5-4.5-8.8-2.9c-3.2,1.6-4.5,5.5-2.9,8.8L118.1,30.7z"/>
<path id="Path_5_" class="st1" d="M19.3,364c-0.6-1.6-1.9-2.9-3.5-3.6c-1.6-0.7-3.4-0.7-5-0.1L-3.4,366c-2.9,1.2-4.5,4.2-4,7.3
s3.3,5.3,6.4,5.3c0.8,0,1.6-0.2,2.4-0.5l14.3-5.7C19,371,20.6,367.3,19.3,364L19.3,364z"/>
<path id="Path_6_" class="st1" d="M9,288.6h11.5c3.6,0,6.5-2.9,6.5-6.5s-2.9-6.5-6.5-6.5H9c-3.6,0-6.5,2.9-6.5,6.5
S5.4,288.6,9,288.6L9,288.6z"/>
<path id="Path_7_" class="st1" d="M39.8,136.4l8.6,2.9c2.2,0.7,4.6,0.2,6.4-1.3c1.7-1.5,2.5-3.9,2.1-6.2
c-0.5-2.3-2.1-4.1-4.3-4.9l-8.6-2.9c-2.2-0.8-4.7-0.3-6.5,1.2c-1.8,1.6-2.6,3.9-2.1,6.2S37.6,135.7,39.8,136.4L39.8,136.4z"/>
<path id="Path_8_" class="st1" d="M16.1,164.6h0.4l8.7-0.6c3.6-0.2,6.3-3.3,6.1-6.9c-0.2-3.6-3.3-6.3-6.9-6.1l-8.7,0.6
c-2.3,0.1-4.4,1.4-5.5,3.4c-1.1,2-1,4.5,0.2,6.5C11.6,163.5,13.8,164.7,16.1,164.6L16.1,164.6z"/>
<path id="Path_9_" class="st1" d="M269.6,430.1c-0.3-3.6-3.4-6.3-7-6c-3.6,0.3-6.3,3.4-6,7l1.4,20c0.3,3.4,3.1,6,6.5,6h0.5
c1.7-0.1,3.3-0.9,4.5-2.3c1.1-1.3,1.7-3,1.5-4.7L269.6,430.1z"/>
<path id="Path_10_" class="st1" d="M223.1,428.5c-1.7-0.4-3.5,0-4.9,0.9s-2.5,2.4-2.8,4.1l-2.5,11.4c-0.4,1.7-0.1,3.5,0.9,4.9
s2.4,2.5,4.1,2.8c0.5,0.1,0.9,0.1,1.4,0.1c3.1,0,5.7-2.1,6.3-5.1l2.5-11.4c0.4-1.7,0.1-3.5-0.9-4.9
C226.3,429.9,224.8,428.9,223.1,428.5L223.1,428.5z"/>
<path id="Path_11_" class="st1" d="M544.7,374c-3.3-3.6-6.7-7.4-9.9-10.7c-2.5-2.6-6.6-2.6-9.2-0.1c-2.6,2.5-2.6,6.6-0.1,9.2
c3.1,3.2,6.4,6.9,9.6,10.4c2.4,2.7,5,5.5,7.4,8.1c1.6,1.8,4,2.5,6.3,2c2.3-0.5,4.1-2.2,4.8-4.5c0.7-2.3,0-4.7-1.6-6.4
C549.6,379.4,547.1,376.6,544.7,374z"/>
</g>
</g>
</g>
<g id="Master_x2F_Hands_x2F_Phone_1_" transform="scale(1 1)">
<g id="Master_x2F_Hands_x2F_Phone">
<g id="base" transform="translate(170.000000, 85.000000)">
<path id="Path_12_" class="st2" d="M190.8,77.3c0.1-0.7,0.6-1.3,1.3-1.5c5-1.8,10.1-3.3,15.2-4.4c0.2-0.1,0.5-0.1,0.8-0.2
c4.2-1,5.7-1.3,7.9-1.1c3,0.2,5.6,1.5,7.8,4.2c3.1,3.8,5.1,8.9,6.2,14.6c0.6,3.4,0,8.2-1.7,10.9c-1.9,3.1-5,5.8-9.5,8.8
c-0.8,0.5-1.6,1.1-2.6,1.7c-0.4,0.2-0.8,0.5-1.2,0.8c-0.2,0.1-1,0.6-1.2,0.7c-1.8,1.1-3.3,2.1-6.2,4.1c-0.3,0.2-0.3,0.2-0.6,0.4
c-4.5,3.1-6.9,4.6-9.8,6.2c-4.7,2.4-9.1,5.3-13.3,8.6c-1.5,1.2-3.6-0.1-3.2-2L190.8,77.3z"/>
<path id="Path_13_" class="st2" d="M203.7,195.8c13.1-2.3,37.7-9.8,42.4-14.7c4.6-4.7,6.3-11.2,6.2-19.9c0-2.5-0.2-4.8-0.5-8.7
l-0.1-1.3c-0.8-8.3-2.3-16.5-4.7-24.4c-2.7-9.6-7-11.8-18.8-11.2c-12.2,0.8-24.3,2.5-36.2,5c-1,0.2-1.7,1.2-1.6,2.3l10.9,71.2
C201.5,195.2,202.6,195.9,203.7,195.8z"/>
<path id="Path_14_" class="st3" d="M247.1,148.2c-3,0.4-6.5,0.8-10.7,1.3c-3.1,0.4-6.3,0.7-11.1,1.2
c-13.5,1.4-16.2,1.7-21.2,2.4c-1.1,0.1-1.9,1.1-1.7,2.2c0.1,1.1,1.1,1.9,2.2,1.7c5-0.6,7.7-0.9,21.2-2.4c4.8-0.5,8-0.9,11.1-1.2
c4.2-0.5,7.7-0.9,10.8-1.3c1.1-0.1,1.9-1.1,1.7-2.2C249.2,148.8,248.2,148.1,247.1,148.2z"/>
<path id="Path_15_" class="st2" d="M176.1,171.3c-7.4-9.2-14.8-15.9-22.5-19.9c-10.8-5.6-23.2-9.2-34.7-9.6
c-13.6-0.5-25.3,3.5-33.6,12.5c-1.8,2-3.3,4.4-4.6,7.8L75,143.1c-0.4-1.4-2.1-1.9-3.2-0.9c-3.8,3.2-9.4,11-16.2,22.2
c-4.6,7.6-9,15.3-13.5,23.4c-1.1,2.1-2.3,4.4-3.5,7c-3,6.3-6.1,14-9.5,23.2c-1.6,4.4-3.3,8.9-5.2,14.4
c-0.8,2.3-3.8,10.8-4.5,12.8c-9.6,27.2-15.4,57-21.8,104.3c-1.3,9.3-2.3,23.1-3.1,40.2c-0.5,11.5-1,48.9-1.3,61.3
c-0.1,4.3-0.2,8.3-0.3,12c0,1.3,0,2.4-0.1,3.4c0,0.3,0,0.5,0,0.9c0,0.3,0,0.3,0,0.3c0,1.1,0.9,2,2,2l158.9,0.2c1.1,0,2-0.9,2-2
c0-42.6,2.3-123,6.3-141.8c3.2-15,9.1-33.5,15.7-50c3.1-7.8,6.8-16.2,11.8-27c1.5-0.2,3-0.5,4.5-0.9c7.1-1.8,9.2-2.3,12.9-3.5
c14.2-4.6,22.7-11.1,24.2-21.7c1.2-8.6-2.7-20.2-8.8-26.1c-4.4-4.2-10.5-5.3-18.6-4.3c-2.4,0.3-4.8,0.7-8.2,1.4
c-0.5,0.1-2.2,0.5-2.5,0.5c-0.3,0.1-0.7,0.1-0.9,0.2C185.9,184.5,181.4,177.8,176.1,171.3z"/>
<path id="Path_16_" class="st3" d="M178.6,211.9c-12.2,1.3-19.3,11.3-15.7,22.6c0,0.1,1.3,4.5,1.8,6c1.3,4,2.7,6.7,4.6,8.4
c5.3,4.5,10.5,5.4,17.8,3.6c1.1-0.3,1.7-1.3,1.5-2.4c-0.3-1.1-1.3-1.7-2.4-1.5c-6.1,1.5-10,0.9-14.2-2.7c-1.2-1-2.3-3.2-3.4-6.6
c-0.5-1.4-1.7-5.7-1.8-5.9c-2.8-8.9,2.5-16.4,12.3-17.4c1.1-0.1,1.9-1.1,1.8-2.2C180.7,212.6,179.7,211.8,178.6,211.9z"/>
<path id="Path_17_" class="st4" d="M168.7,217.8L168.7,217.8c-10.3,1.8-40.5,3.3-53.9,3c-1.4,0-2.8,0-4.7-0.1
c-0.3,0-0.6,0-1.2,0c-13.1-0.1-18.7-0.5-24.8-2.8c-8.3-3.1-13.6-9.3-15.9-19.5c-2.5-10.9-4.2-22.7-5.8-37.6
c-0.6-5.6-0.9-8.8-2-20.4c-0.2-2.4-0.4-4-0.5-5.7c-1.4-14.8-2.7-31.2-4.5-56.9c0.2,2.4-1.7-24.5-2.2-31.5
c-0.7-9.7-1.3-17.7-1.9-24.9c-1.5-18.1-1.7-36.2,0.8-43.4c2.9-9.1,10.9-15.6,20.3-16.8c23.9-3.6,53.9-6.3,69.8-6
c1.4,0,2.7,0,5.4,0.1c8.1,0.1,11.8,0.1,16.6,0.5c15,1.2,25.5,5.1,31.6,13.4c3.3,4.5,5.2,11.1,6.5,19.9c0.3,2.2,0.6,4.5,0.8,7.2
c0.1,1,0.2,2.1,0.3,3.4c0-0.2,0.2,2.5,0.3,3.2c0.1,0.9,0.1,1.6,0.2,2.3c0,0.5,0,0.5,0.1,1.1c2,22,2.1,22.6,2.9,30.8
c0.6,5.6,1.1,10.8,1.7,15.7c5.2,44.2,8.4,81.5,9.5,117.7c0.5,16.3-1.9,27.4-10.4,34.7c-4,3.4-10.6,6.2-19.1,8.5
c-3.5,1-7.3,1.8-11.3,2.6c-1.5,0.3-3,0.6-4.7,0.9C171.6,217.3,169.2,217.7,168.7,217.8z"/>
<path id="Path_18_" class="st5" d="M164.3,209.4c-11.9,1.3-23.8,1.9-35.7,1.7c-17.4-0.4-32.1,1.9-36.8-19
c-4.2-18.6-5.8-42.7-7.6-61.8c-2.9-31-5.3-74-7.8-105.2C75.7,16.9,73.7-12,77-19.5s11.2-9.9,17-11c13.8-2.7,30.6-4.7,46.3-4.4
c14.3,0.3,37.8-1.2,47.3,12c5.6,7.7,6.1,26.6,7,35.8c1.4,14.2,2.6,28.9,4.3,43.3c4.2,35.5,7.5,76,8.7,112
c0.3,10-0.3,22.9-8.8,30.2C190.8,205.2,171.2,208.6,164.3,209.4z"/>
<path id="Path_19_" class="st6" d="M69.3-32.7C64.4-29.4,62.8-21,63-7.9c0.1,3.3,0.2,6.6,0.5,11.2c0,0.7,0.2,3.4,0.3,4
c0.1,1.4,0.2,2.5,0.2,3.4c0.4,8.5,1,18.5,1.9,32.1c0.1,1.9,0.3,3.9,0.4,6.2c0.1,1.5,0.7,10.5,0.9,13c0.3,4.9,0.6,8.7,0.8,12.1
c2.1,32.7,5.2,67.6,9.3,106.3c1.1,10.7,3.5,20.7,7.1,27.7c0.5,1,1.7,1.4,2.7,0.9s1.4-1.7,0.9-2.7c-3.3-6.5-5.6-16.1-6.7-26.3
C77.2,141.6,74,106.8,72,74.1c-0.2-3.5-0.5-7.3-0.8-12.2c-0.2-2.5-0.8-11.5-0.9-13c-0.2-2.3-0.3-4.3-0.4-6.2
c-0.9-13.6-1.5-23.5-1.9-32c0-1-0.1-2-0.2-3.5c0-0.7-0.2-3.4-0.3-4C67.3-1.4,67.1-4.7,67-7.9c-0.2-11.7,1.2-19.2,4.5-21.4
c0.9-0.6,1.2-1.9,0.6-2.8C71.4-33,70.2-33.3,69.3-32.7z"/>
<path id="Path_20_" class="st2" d="M43.7,251.4c-1.5,0-2.4-1.7-1.7-3c2.6-4.5,5.5-9.3,9.2-15c1.5-2.3,3.1-4.7,5.1-7.9
c0.7-1,3.1-4.7,2.9-4.4c1.2-1.8,2-3.1,2.9-4.4c2.1-3.3,3.9-6,5.5-8.6c12.5-20,25.6-35.9,39.7-46.9c8.1-6.3,17.6-4.7,23.7,3.9
c3.2,4.5,3.3,9.5,1.2,15.6c-0.8,2.4-1.8,4.6-3.6,8.1c-2.3,4.6-2.3,4.6-3,6.1c-2.4,5.5-4,14.9-4.3,23.7
c-0.1,3.8,0.3,8.1,1.3,12.9c0.7,3.8,1.7,7.7,3.1,12.6c0.3,1,0.6,2.1,1,3.4c0.1,0.3,0.8,2.6,0.9,3.2c0.4,1.3-0.6,2.6-2,2.6
L43.7,251.4z"/>
<path id="Path_21_" class="st6" d="M60.7,36.4c-0.4-5.6-0.7-11.2-0.9-16.6c0-1.1-1-2-2.1-1.9c-1.1,0-2,1-1.9,2.1
c0.2,5.5,0.5,11.1,0.9,16.7c0.1,1.1,1,1.9,2.1,1.9C59.9,38.5,60.8,37.5,60.7,36.4z"/>
<path id="Path_22_" class="st6" d="M62.7,63.9c-0.5-5.4-0.9-11-1.2-17.1c-0.1-1.1-1-2-2.1-1.9c-1.1,0.1-2,1-1.9,2.1
c0.3,6.1,0.7,11.9,1.2,17.3c0.1,1.1,1.1,1.9,2.2,1.8C62,66,62.8,65,62.7,63.9z"/>
<path id="Path_23_" class="st3" d="M120.8,222.8c0.7,6.9,2.3,12.2,5.5,20c0.2,0.4,0.4,0.9,0.6,1.4c0.1,0.4,0.1,0.4,0.3,0.7
c0.1,0.4,0.2,0.5,0.3,0.7c0.5,1.1,0.8,1.9,1.1,2.8c0.4,1,1.6,1.5,2.6,1.1c1-0.4,1.5-1.6,1.1-2.6c-0.3-0.8-0.7-1.7-1.2-2.8
c-0.1-0.2-0.1-0.4-0.3-0.7c-0.1-0.4-0.1-0.4-0.3-0.7c-0.2-0.6-0.4-1-0.6-1.4c-3.1-7.4-4.6-12.5-5.2-18.9
c-0.1-1.1-1.1-1.9-2.2-1.8C121.5,220.7,120.7,221.7,120.8,222.8z"/>
<path id="Path_24_" class="st3" d="M43.8,245.4c2.5-4.4,5.4-9.2,9-14.8c1.5-2.3,3.1-4.7,5.1-7.9c0.7-1,3.1-4.7,2.9-4.4
c1.2-1.8,2-3.1,2.9-4.4c2.2-3.3,3.9-6.1,5.6-8.7c0.6-0.9,0.3-2.2-0.6-2.8c-0.9-0.6-2.2-0.3-2.8,0.6c-1.6,2.6-3.4,5.3-5.5,8.6
c-0.8,1.3-1.7,2.6-2.9,4.4c0.2-0.3-2.2,3.4-2.9,4.4c-2.1,3.2-3.6,5.6-5.2,7.9c-3.6,5.7-6.6,10.4-9.1,14.9
c-0.5,1-0.2,2.2,0.7,2.7C42,246.7,43.3,246.4,43.8,245.4z"/>
<path id="Path_25_" class="st3" d="M126.9,303.9c2,0.5,4.1,1.1,6,1.9c1,0.4,2.2-0.1,2.6-1.1c0.4-1-0.1-2.2-1.1-2.6
c-2.1-0.9-4.4-1.6-6.6-2.1c-1.1-0.2-2.1,0.4-2.4,1.5C125.1,302.5,125.8,303.6,126.9,303.9z"/>
</g>
<g id="Phone_x2F_Wear" transform="scale(1 1)">
<g id="Phone_x2F_Wear_x2F_Hoodie_1">
<g id="clothing" transform="translate(95.000000, 448.000000)">
<path id="Path_26_" class="st7" d="M309.7,68.9c-3.8-7.6-11.3-12.7-19.7-13.5c-4.2-0.4-8.3,0.6-11.9,2.8
c1.9-10.7-2-23-9.6-27.6c-7.9-4.7-16.8-8.4-28.6-4.1c0-5.1-0.1-15.6,0-20.7c0.1-5.1,0.1-10,0.1-14.9c0-5.9,0-12,0.2-18.1
c0-0.7-0.3-1.4-0.9-1.7c-0.6-0.4-1.4-0.5-2-0.1c-20.8,9.8-50.6,13.1-79.6,8.8c-11.1-1.7-22.2-4.7-33.1-7.6
c-5.8-1.5-11.7-3.2-17.7-4.6c-9.1-2.2-19-5.8-31.2-11.5c-0.5-0.3-1.2-0.3-1.7,0c-0.5,0.3-0.9,0.7-1.1,1.3
c-1.6,6.5-6,25.8-6.9,32.7c-0.1,1-0.3,2.7-0.6,4.7C64.1,4.9,62.8,14.9,62.2,23c-9.1-1.2-18.4,2.1-26.3,9.5
c-6,5.7-10.4,13.1-11.6,19.3c-2.5-2.3-5.6-3.8-9-4.1c-4.2-0.3-8.4,1.5-12.4,5.4c-8.8,8.6-12.2,26.6-7.3,38.4
c3,7.3,8.8,15.4,16.2,15.4h273c13.9,0,20.6-10.1,23.8-15.2C312.8,84.9,313.2,76.3,309.7,68.9z"/>
<path id="Combined-Shape" d="M137.3-2.6c0.2-1.1,1.3-1.8,2.4-1.5c1.1,0.2,1.8,1.3,1.5,2.4c-1.6,7.5-2.9,16.7-3.9,28.2
c-0.4,4.3-0.7,8.9-1.1,14.2c-0.2,2.5-0.7,10-0.8,12.5c15.7,1.8,30.6,2,44.6,0.3c0-6.4,0.4-11.7,1.5-23.7
c0.2-1.6,0.2-2.4,0.3-3.3c0.6-6.7,1-11.2,1.1-15.7c0-1.1,1-2,2.1-1.9s2,1,1.9,2.1c-0.1,4.6-0.5,9.2-1.1,16
c-0.1,0.9-0.2,1.7-0.3,3.3C184.4,41.7,184,46.9,184,53c2.9-0.4,5.8-0.9,8.7-1.5c2.1-8.4,2.9-17,2.4-25.6
c-0.1-1.1,0.8-2,1.9-2.1c1.1-0.1,2,0.8,2.1,1.9c0.5,8.4-0.2,16.7-2.1,24.9c4.4-1,8.6-2.3,12.8-3.7c9.3-3.1,18.3-7.1,26.8-12.1
c0.1-2.6,0.3-5.2,0.7-7.8c0.2-1.1,1.2-1.8,2.3-1.7c1.1,0.2,1.8,1.2,1.7,2.3c-0.4,2.8-0.7,5.6-0.7,8.4c0,0.7-0.4,1.3-1,1.7
c-9,5.4-18.6,9.7-28.5,13c-5.1,1.8-10.3,3.2-15.7,4.4c-0.4,0.3-0.9,0.4-1.5,0.3c-21.5,4.5-45,4.4-70.5,0.3
c-13.6-2.2-26.5-6.2-45.7-13.5c-0.6-0.2-1.2-0.5-2-0.7c-0.2-0.1-1.6-0.6-2-0.7c-4.7-1.7-7.2-2.9-9.3-4.9
c-2.7-2.6-3.9-6.1-3.3-10.7c0.1-1.1,1.1-1.9,2.2-1.7s1.9,1.1,1.7,2.2c-0.8,6.1,1.5,8.3,9.9,11.3c0.4,0.1,1.7,0.6,2,0.7
c0.8,0.3,1.4,0.5,2.1,0.8c5.2,2,10,3.7,14.4,5.3c0.8-11.5,3.2-26.7,6.9-46.1c0.2-1.1,1.3-1.8,2.3-1.6c1.1,0.2,1.8,1.3,1.6,2.3
c-3.8,19.8-6.3,35.2-6.9,46.7c9.2,3,17,5.1,25,6.5c0.4-12.4,2-27.3,4.1-35.2c0.3-1.1,1.4-1.7,2.4-1.4c1.1,0.3,1.7,1.4,1.4,2.4
c-2.1,7.7-3.6,22.7-4,34.9l0-0.1c1.7,0.3,3.3,0.5,5,0.7c0.2-2.6,0.6-9.8,0.8-12.3c0.4-5.4,0.7-10,1.1-14.3
C134.4,14.5,135.6,5.1,137.3-2.6z M221.2-22.9c1.1,0,2,1,1.9,2.1c-0.1,3.7-0.1,6.6,0.1,13.2c0.1,4.6,0.1,6.6,0.1,9.2
c0,4.2-0.2,7.9-0.5,11.4c-0.8,8-1.2,14.8-1.2,19.3c0,1.1-0.9,2-2,2c-1.1,0-2-0.9-2-2c-0.1-4.7,0.4-11.6,1.2-19.7
c0.3-3.4,0.5-6.9,0.5-11c0-2.5,0-4.5-0.1-9.1c-0.1-6.7-0.2-9.7-0.1-13.4C219.2-22.1,220.1-23,221.2-22.9z M82.5-38.3
c0.2-1.1,1.3-1.8,2.4-1.6c1.1,0.2,1.8,1.3,1.6,2.4c-5.2,25.6-8.7,47-9,60.5c0,1.1-0.9,2-2,2c-1.1,0-2-0.9-2-2
C73.8,9.1,77.3-12.5,82.5-38.3z M159.3-17.1c0.2-1.1,1.2-1.8,2.3-1.6c1.1,0.2,1.8,1.2,1.6,2.3c-1,5.3-1.7,10.8-2.4,18.2
c-0.2,2-0.3,3.3-0.6,7.3c-0.6,6.5-0.9,9.6-1.3,13.3c-0.1,1.1-1.1,1.9-2.2,1.8c-1.1-0.1-1.9-1.1-1.8-2.2
c0.4-3.6,0.7-6.7,1.3-13.2c0.3-4,0.5-5.3,0.6-7.3C157.6-6,158.3-11.7,159.3-17.1z M91.9-34.9c0.2-1.1,1.3-1.8,2.4-1.5
c1.1,0.2,1.8,1.3,1.5,2.4c-3.2,14.8-6.1,32.8-8.5,50.9c-0.1,1.1-1.1,1.9-2.2,1.7c-1.1-0.1-1.9-1.1-1.7-2.2
C85.7-1.9,88.7-20,91.9-34.9z M229.2-24.2c1.1-0.1,2.1,0.7,2.2,1.8c0.5,5.6,0.5,11.5,0.3,20.3c0,1.3-0.1,2.3-0.1,4.5
c-0.2,6.3-0.2,8.9-0.2,12.2c0,1.1-0.9,2-2,2s-2-0.9-2-2c0-3.3,0.1-5.9,0.2-12.3c0.1-2.2,0.1-3.2,0.1-4.5
c0.2-8.6,0.1-14.4-0.3-19.8C227.3-23.2,228.1-24.1,229.2-24.2z"/>
</g>
</g>
</g>
<g id="Phone_x2F_Item" transform="scale(1 1)">
<g id="Phone_x2F_Item_x2F_Alarm">
<g id="items" transform="translate(264.000000, 162.000000)">
<path id="Path_27_" class="st8" d="M31.2,41.4c0,0.1-0.1,0.3-0.3,0.6c-0.2,0.5-0.4,1-0.7,1.5c-0.7,1.6-1.4,3.1-2.1,4.5
L28,48.3c-1.5,3.1-2.5,5.3-2.9,6c-0.6,1-0.2,2.2,0.7,2.7c1,0.6,2.2,0.2,2.7-0.7c0.5-0.8,1.5-3,3.1-6.3l0.1-0.3
c0.7-1.5,1.4-3,2.1-4.6c0.3-0.5,0.5-1.1,0.7-1.5c0.1-0.3,0.2-0.5,0.3-0.6c0.5-1,0-2.2-1-2.7C32.9,40,31.7,40.4,31.2,41.4z"/>
<path id="Path_28_" class="st8" d="M67.9,40.9c2.7,3.5,5.1,7.1,7.4,10.9c0.6,1,1.8,1.3,2.7,0.7c1-0.6,1.3-1.8,0.7-2.7
c-2.3-3.9-4.9-7.7-7.6-11.3c-0.7-0.9-1.9-1-2.8-0.4S67.2,40.1,67.9,40.9z"/>
<path id="Path_29_" class="st8" d="M12-14.9c1.6,1.3,3.2,2.8,5.6,5.1c0.3,0.3,0.6,0.6,1.2,1.1c3.4,3.3,4.9,4.7,6.7,6.3
c0.8,0.7,2.1,0.6,2.8-0.2s0.6-2.1-0.2-2.8c-1.8-1.5-3.2-2.8-6.5-6.1c-0.5-0.5-0.8-0.8-1.2-1.1c-2.4-2.4-4.1-3.9-5.8-5.3
c-0.8-0.7-2.1-0.6-2.8,0.3C11-16.9,11.1-15.6,12-14.9z"/>
<path id="Path_30_" class="st8" d="M67.1-6.5c0,0,0,0,0.1-0.3c0.1-0.2,0.2-0.5,0.3-0.7c0.4-0.8,0.7-1.7,1.2-2.6
c1.2-2.7,2.5-5.4,3.7-8c0.3-0.7,0.7-1.4,1-2c1.9-3.9,3.5-6.8,4.6-8.2c0.7-0.9,0.5-2.1-0.4-2.8c-0.9-0.7-2.1-0.5-2.8,0.4
c-1.2,1.6-2.9,4.7-4.9,8.8c-0.3,0.7-0.7,1.4-1,2.1c-1.2,2.6-2.5,5.3-3.8,8.1c-0.4,1-0.8,1.9-1.2,2.7c-0.1,0.3-0.2,0.5-0.3,0.7
c-0.1,0.2-0.1,0.2-0.1,0.3c-0.4,1,0,2.2,1,2.6S66.7-5.5,67.1-6.5z"/>
<path id="Path_31_" class="st5" d="M40-17.1C32.1-15,25.5-9.6,21.6-2.4c-3.8,6.9-4.9,12.6-4.3,20.3c0.6,7.4,3.3,14.6,9.4,19.5
c12.7,10.2,31.7,10.2,45.1,0.1C84,28.3,85.6,8.9,78.9-3.9C74.2-13,65.1-18.2,55-18.6c-4.6-0.4-9.3,0-13.8,1.1
C40.8-17.3,40.4-17.2,40-17.1z"/>
<path id="Path_32_" class="st8" d="M19.9-3.3c-3.9,7-5.1,13.1-4.5,21.4C16,26.7,19.3,34,25.5,39C38.8,49.8,58.9,49.8,73,39.1
c12.4-9.4,15.2-29.4,7.7-44c-5-9.5-14.5-15.3-25.6-15.7c-4.8-0.4-9.6,0-14.4,1.2c-0.5,0.1-0.9,0.2-1.3,0.4
C31.1-16.7,24-11,19.9-3.3z M40.6-15.2c0.3-0.1,0.7-0.2,1.1-0.3c4.3-1,8.7-1.4,13.2-1.1c9.7,0.4,18,5.4,22.3,13.6
c6.7,12.9,4.1,30.8-6.6,38.9c-12.7,9.6-30.7,9.6-42.6,0c-5.2-4.2-8-10.5-8.6-18.1c-0.6-7.6,0.5-12.9,4-19.2
C27-8.2,33.2-13.2,40.6-15.2L40.6-15.2z"/>
<path id="Path_33_" class="st8" d="M41.9,6.1c-0.5-1-1.8-1.3-2.7-0.8c-1,0.5-1.3,1.8-0.8,2.7c2.5,4.4,5.3,8.6,8.5,12.5
c1,1.2,2.8,0.9,3.4-0.5c2.4-5.8,4.4-11.8,6.1-17.9c0.2-0.7,0.4-1.5,0.7-2.4c0.1-0.2,0.1-0.2,0.1-0.4c0.4-1.6,0.9-3.2,1.4-4.8
C58.8-6,58.9-6.6,59.1-7c0.1-0.3,0.1-0.5,0.2-0.6c0.3-1.1-0.3-2.2-1.4-2.5c-1.1-0.3-2.2,0.3-2.5,1.4c0,0.1-0.1,0.3-0.2,0.6
c-0.1,0.5-0.3,1-0.5,1.6c-0.5,1.6-1,3.3-1.4,4.9c-0.1,0.2-0.1,0.2-0.1,0.4c-0.3,0.9-0.5,1.7-0.7,2.5
c-1.3,4.8-2.9,9.6-4.6,14.2C45.7,12.4,43.7,9.3,41.9,6.1z"/>
<path id="Path_34_" class="st9" d="M3.4,12.8c-1.9,4.8-2,11.2-0.3,17.7c1.3,5.1,4.2,9.6,8.4,13c0.9,0.7,2.1,0.6,2.8-0.3
s0.6-2.1-0.3-2.8c-3.4-2.8-5.9-6.6-7-10.8c-1.6-5.8-1.5-11.3,0.1-15.2c0.4-1-0.1-2.2-1.1-2.6S3.8,11.8,3.4,12.8z"/>
<path id="Path_35_" class="st9" d="M-7.3,25.7c0.1,7.7,2.5,14.6,7.2,19.4c0.8,0.8,2,0.8,2.8,0c0.8-0.8,0.8-2,0-2.8
c-3.9-4-6-9.9-6.1-16.6c0-1.1-0.9-2-2-2C-6.4,23.6-7.3,24.6-7.3,25.7z"/>
<path id="Path_36_" class="st9" d="M90.5,4.2c2,3.6,2.5,9.7,1.8,16.3c-0.5,5-3.2,12-6,15.3c-0.7,0.9-0.6,2.1,0.3,2.8
s2.1,0.6,2.8-0.3c3.3-4,6.3-11.7,6.9-17.5c0.8-7.4,0.2-14.2-2.3-18.7c-0.5-1-1.8-1.3-2.7-0.8S89.9,3.2,90.5,4.2z"/>
<path id="Path_37_" class="st9" d="M100.8,15.2c1,4.8,0.1,10.6-2.1,15.4c-0.5,1,0,2.2,1,2.7c1,0.5,2.2,0,2.7-1
c2.6-5.5,3.7-12.1,2.4-17.9c-0.2-1.1-1.3-1.8-2.4-1.5S100.6,14.2,100.8,15.2z"/>
<path id="Path_38_" class="st9" d="M31.6-26.5c0.5,0.8,0.5,1.8-0.2,2.5c-2,2.2-4.3,4.7-5.7,6.1c-0.2,0.2-0.4,0.4-0.8,0.8
c-2.6,2.7-3.8,3.9-5.3,5.4C15-7.2,10.8-2.2,7.2,3.2C6.4,4.3,4.8,4.4,4,3.3C3.8,3.1,3.7,3,3.6,2.8c-0.7-0.9-3.4-4.2-4.1-5
c-3.6-4.6-5.1-8.5-4.6-14c0.6-4.9,2.9-9.5,6.4-13.1c3.5-3.4,9.1-5.9,13.5-5.7c3.3,0.2,6.5,0.9,9.5,2.2l0.1,0
C27.3-31.3,29.8-29.2,31.6-26.5z"/>
<path id="Path_39_" class="st9" d="M55.1-27.1c0.1,0.1,0.4,0.2,0.8,0.4c0.6,0.3,1.3,0.6,2.1,0.9c2.1,1,4.3,1.9,6.3,2.8
l0.2,0.1c2.6,1.2,4.7,2.2,6.3,2.9c0.5,0.2,2.1,1,2,0.9c0.8,0.4,1.3,0.6,1.9,0.9c1.4,0.6,2.5,1.2,3.6,1.7
c0.6,0.3,1.2,0.6,1.8,0.9c2.5,1.2,4.9,2.4,7.4,3.8c0.9,0.5,2,0.2,2.6-0.6c5.9-8.3,7.3-18.7,1.7-25.3
c-3.5-3.8-8.1-6.2-13.1-6.9c-7.2-1-12.3,0.2-17.5,4.3c-2,1.5-3.6,3.8-5.3,7.1c-0.3,0.5-0.6,1.1-0.9,1.8
c-0.1,0.2-0.7,1.4-0.8,1.7C53.6-28.7,54.1-27.5,55.1-27.1z"/>
</g>
</g>
</g>
<g id="Phone_x2F_Effect" transform="scale(1 1)">
<g id="Phone_x2F_Effect_x2F_Pop">
<g id="addons" transform="translate(371.000000, 45.000000)">
<path id="Path_40_" class="st10" d="M-2.1-18.7l10.3-22c0.6-1.3,0-2.7-1.2-3.3c-1.3-0.6-2.7,0-3.3,1.2l-10.3,22
c-0.6,1.3,0,2.7,1.2,3.3S-2.7-17.4-2.1-18.7z"/>
<path id="Path_41_" class="st10" d="M38.6-29.2l-22,15.7c-1.1,0.8-1.4,2.4-0.6,3.5s2.4,1.4,3.5,0.6l22-15.8
c1.1-0.8,1.4-2.4,0.6-3.5C41.2-29.8,39.7-30,38.6-29.2z"/>
<path id="Path_42_" class="st10" d="M26.2,16.7l20-0.4c1.4,0,2.5-1.2,2.5-2.5s-1.2-2.5-2.5-2.5l-20,0.4
c-1.4,0-2.5,1.2-2.5,2.5S24.8,16.7,26.2,16.7z"/>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -0,0 +1,316 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 825 550.5" style="enable-background:new 0 0 825 550.5;" xml:space="preserve">
<style type="text/css">
.st0{opacity:0.15;}
.st1{fill:#7C6576;}
.st2{fill:#FCB7A0;}
.st3{fill:#DC8173;}
.st4{fill:#1A4E66;}
.st5{fill:#FFFFFF;}
.st6{fill:#0D323F;}
.st7{fill:#EBE8E5;}
.st8{fill:#CCC9C6;}
.st9{fill:#FC6E47;}
.st10{fill:#3AADAA;}
.st11{fill:#A02E28;}
.st12{fill:#EAF3F3;}
.st13{fill:#3B3B3B;}
</style>
<g id="Master_x2F_Horizontal_Scenes_x2F_Procrastinating">
<g id="Background" transform="translate(250.000000, 0.000000) scale(1 1)" class="st0">
<g id="Background_x2F_Wall">
<path id="Shape" class="st1" d="M388.9,41.1c-2.7-2.6-6.4-4-10.2-3.9c-8.3,0.3-31.7,0.1-56.5-0.1c-34.7-0.3-74.1-0.6-91,0.2
c-16.3,0.8-32.9,0.6-48.9,0.3c-15.4-0.2-31.3-0.4-47.2,0.2c-24.6,1-50-0.2-74.4-1.4c-18.5-0.9-37.6-1.9-56.5-1.9l0,0
c-24.5,0-103.1,1.5-106.4,1.5c-7.4,0.1-13.4,6-13.7,13.3c0,1-4.8,103.6-6.8,154.8c-0.9,22.7,0.4,45.7,1.6,68
c1.4,24.8,2.8,50.5,1.1,75c-1.7,23.4-2.7,53.2-2.7,81.7c0,7.7,6.3,14,14,14c18.5,0,35.6,1.1,52.2,2.1c16.4,1,33.3,2.1,51.4,2.1
c5.3,0,10.8-0.1,16.4-0.3l28.5-1.1c41.3-1.6,84-3.3,125.8-4.2c17.6-0.3,35.2-1.3,52.2-2.1c11.8-0.6,24-1.2,36-1.7
c19-0.7,37.9,1.1,57.8,3c16.1,1.6,32.7,3.2,49.4,3.3c6.7,0.1,12.5-4.6,13.8-11.2c7.1-34.3,7-71,6.8-106.6
c0-10.2-0.1-19.8,0.1-29.3c0.5-38.4,3.2-77.6,5.7-115.4c2.9-42.6,5.9-86.7,5.9-130.4C393.2,47.4,391.7,43.7,388.9,41.1
L388.9,41.1z M322.9,294.5c-8.7,0.8-17,1.6-25,1.8c-11.1,0.3-22.3,0.4-33.5,0.3c0.7-7.7,1.4-15.5,2-23.2
c2.6-28.3,5.2-57.5,5.4-86.3c5.3-0.3,10.6-0.5,16-0.5H359c-2.3,34.7-4.6,70.4-5.2,105.8C343.4,292.5,333,293.5,322.9,294.5
L322.9,294.5z M60.3,286.3c-5.9-0.4-12-0.8-18.3-1c4.4-24,3.3-50.2,2.2-75.7c-0.3-7.2-0.6-14-0.8-20.7c48.5,1.3,95.2,3,133.3,4.4
c3.1,0.1,6.2,0.2,9.3,0.2c17.8,0,35.2-1.8,52.2-3.5l5.6-0.6c-0.4,26.9-2.9,54.6-5.3,81.4c-0.8,8.3-1.5,16.8-2.2,25.2
c-20.7-0.6-41.3-1.5-61.5-2.4l-6-0.3C131.6,291.6,94.8,288.9,60.3,286.3L60.3,286.3z M-93.3,270.6c-1.2-21.6-2.5-43.9-1.6-65.3
c0.2-5.7,0.5-12.1,0.8-18.8c34.9,0.1,72.3,0.8,109.5,1.7c0.2,7.5,0.5,15.2,0.8,22.6c1.1,25.7,2.2,52.2-2.8,74.3
c-20,0.2-41,1.1-61.5,2c-15.5,0.7-30.4,1.3-44.2,1.6C-92.7,282.7-93,276.7-93.3,270.6z M232.6,65.2c16.1-0.8,55-0.5,89.4-0.2
c16.7,0.2,32,0.3,43.1,0.3c-0.4,31.1-2.3,62.5-4.3,93.3h-73c-17.8,0-35.4,1.8-52.4,3.5c-19.9,2-38.7,3.9-57.7,3.2l-20.5-0.8
c0.2-21.1,1.4-42.3,2.6-62.9c0.7-11.9,1.4-24.1,1.9-36.3c6.8,0,13.5,0.1,20.2,0.2C198.4,65.8,215.4,66.1,232.6,65.2z M4.1,62.5
L4.1,62.5c18.3,0,37,0.9,55.2,1.8c24.3,1.2,49.3,2.4,74.4,1.5c-0.5,11.4-1.1,22.9-1.8,34.2c-1.2,20.7-2.4,42.1-2.7,63.5
c-68-2.4-150.5-4.7-222.1-5c1.6-35.8,3.4-74.9,4.3-94.8C-64.6,63.4-14.2,62.5,4.1,62.5z M38.5,417.7L10,418.8
c-23.1,0.9-43.4-0.4-64.9-1.8c-12.8-0.8-25.9-1.7-39.9-2c0.2-23.4,1.1-46.8,2.5-65.8c0.8-10.8,1-21.6,0.9-32.4
c14-0.3,29-1,44.6-1.7c36.6-1.6,74.4-3.2,105.1-0.9c25,1.9,51.2,3.8,78,5.4c0.8,28.5-2.6,64.4-9.1,94.9
C97.3,415.4,67.6,416.6,38.5,417.7z M349.4,415.7c-11.5-0.6-23.1-1.7-35.2-2.8c-20-1.9-40.6-3.9-61.5-3.2
c-12.2,0.4-24.5,1.1-36.5,1.7c-16.8,0.9-34.2,1.8-51.3,2.1l-9.1,0.2c5.9-30.4,8.9-64.2,8.4-92.6l3.3,0.2l6,0.3
c32.7,1.5,66.4,3,100,3c8.4,0,16.8-0.1,25.2-0.3c9-0.2,18.1-1.1,26.9-2c9.8-0.9,19.1-1.8,28-1.9c0,2,0,4,0,6
C353.7,356.5,353.8,387.4,349.4,415.7L349.4,415.7z"/>
</g>
</g>
<g id="Master_x2F_Hands_x2F_Point_1_" transform="translate(800.000000, 300.000000) scale(-1, 1) translate(-800.000000, -300.000000) translate(500.000000, -0.000000) scale(1 1)">
<g id="Master_x2F_Hands_x2F_Point">
<g id="base" transform="translate(177.000000, 189.000000)">
<path id="Path" class="st2" d="M288.1-1.3c-0.8-0.9-0.7-2.4,0.4-3c0.1-0.1,0.1-0.1,0.6-0.4c0.5-0.3,1.1-0.7,1.7-1.1
c1.8-1.2,3.8-2.5,6-3.9c6.2-4.1,12.5-8.1,18.4-11.9l0.4-0.3c11.4-7.4,19.8-12.8,24.1-15.4c1.6-1,3.4-2.1,5.6-3.6
c0.9-0.6,4.8-3.2,5.8-3.9c8.9-5.8,14.7-9.2,20.8-11.5c2.7-1.1,5.3-1.8,7.9-2.3c14.3-2.6,23.6,13.5,18.2,26.3
c-1.4,3.3-3.6,6.7-6.5,10.5c-3.2,4.1-7.1,8.4-11.8,13c-3.8,3.7-6.5,6.1-13.1,12c-3.8,3.4-9.4,8-16.3,13.6
c-0.5,0.4-0.9,0.7-1.4,1.1c-5.1,4.1-10.5,8.4-15.9,12.6c-1.9,1.5-3.7,2.9-5.2,4.1c-0.6,0.4-1,0.8-1.5,1.1
c-0.3,0.2-0.4,0.3-0.5,0.4c-0.8,0.6-2,0.5-2.7-0.2L288.1-1.3z"/>
<path id="Path_1_" class="st2" d="M331.2,48.2c-0.8-5.8-2-11.7-4-19.5c-0.4-1.4-0.4-1.7-1.3-5.2c-5.7-22-15.8-30.3-36.5-28.2
c-15.8,1.6-29.5,5.1-55.5,13.2c-2,0.6-3.8,1.2-7.3,2.2c-0.6,0.2-0.6,0.2-1.3,0.4c-18.3,5.5-26.9,8.7-35.4,14.3
C178.3,32.9,171.3,43,168.8,57c-2.1,11.9-2.9,24.2-3,40.9c0,3.7,0,6.6,0,13.2c0,6,0,8.6,0,11.9c0,4.5-0.1,10.6-0.2,27.2l0,0.4
c-0.2,16.1-0.2,23-0.2,27.6v171.3c0,1.1,0.9,2,2,2h184.3c1.1,0,2-0.9,2-2V101.1c0-0.6,0-1,0-2.1c0-8.4-0.1-12.9-0.7-18.2
c-1.5-14.5-6-24.5-15.1-29.2c-2-1.1-4.3-1.9-6.7-2.1C331.3,49,331.3,48.6,331.2,48.2z"/>
<path id="Path_2_" class="st3" d="M196.4,66.1c2.1,1.3,3.9,2.7,6.2,4.9c0.5,0.4,0.9,0.9,1.5,1.5c0.2,0.2,1.3,1.3,1.6,1.6
c0.8,0.8,2.1,0.8,2.8,0c0.8-0.8,0.8-2.1,0-2.8c-0.3-0.3-1.4-1.4-1.6-1.6c-0.6-0.6-1.1-1.1-1.6-1.6c-2.4-2.3-4.4-3.9-6.9-5.4
c-0.9-0.6-2.2-0.3-2.7,0.7C195.2,64.3,195.5,65.5,196.4,66.1z"/>
<path id="Path_3_" class="st3" d="M261.1,5.4c5.8,0.9,14.8,8.3,17.9,14.3c4.7,9,8.6,21.9,12,37.2c0.2,0.9,0.4,1.7,0.7,3.3
c0.3,1.8,0.5,2.5,0.7,3.4c0.1,0.5,0.2,1.1,0.4,1.6c0.3,1.1,1.3,1.7,2.4,1.5s1.7-1.3,1.5-2.4c-0.1-0.5-0.2-0.9-0.3-1.5
c-0.2-0.9-0.3-1.5-0.7-3.3c-0.3-1.6-0.5-2.5-0.7-3.4c-3.4-15.6-7.5-28.8-12.3-38.2c-3.6-7-13.7-15.2-20.9-16.4
c-1.1-0.2-2.1,0.6-2.3,1.7C259.2,4.2,260,5.3,261.1,5.4z"/>
<path id="Path_4_" class="st3" d="M255.4,116.6c8.5-7.6,8.6-37.5,0.1-68.4c-4.1-14.9-16.9-30.7-30.3-35.4
c-1-0.4-2.2,0.2-2.5,1.2c-0.4,1,0.2,2.2,1.2,2.5c12,4.2,24,18.9,27.7,32.6c8.1,29.5,8,58.2,1.1,64.4c-0.8,0.7-0.9,2-0.2,2.8
C253.3,117.3,254.6,117.3,255.4,116.6z"/>
<path id="Path_5_" class="st3" d="M265.3,200.3c-5.6-1.4-10.7-1.3-15.1,0.8c-1,0.5-1.4,1.7-0.9,2.7c0.5,1,1.7,1.4,2.7,0.9
c3.4-1.7,7.6-1.7,12.4-0.5c1.1,0.3,2.2-0.4,2.4-1.4C267.1,201.7,266.4,200.6,265.3,200.3z"/>
<path id="Path_6_" class="st3" d="M310.7,107.3c2.4-0.8,1.4-4.4-1.1-3.8c-2.5,0.6-4.5,1.2-7.9,2.5c-2.7,0.9-4.7,1.6-6.6,2.3
c-2.4,0.9-4.4,1.7-6.2,2.5c-2.1,0.6-3.9,1-5.8,1.1c-5.7,0.5-7.9-1.8-11.1-9.6c-0.1-0.2-0.8-2-1-2.5c-2.7-6.6-2-11.7,1.5-16.4
c2.8-3.8,6.5-6.5,14.8-11.8l1.1-0.7c0.5-0.3,0.9-0.6,1.3-0.8c3.8-2.4,8-4.9,13.3-7.9c1.5-0.8,2.9-1.7,4.9-2.8
c0.2-0.1,3.8-2.1,4.8-2.7c6.7-3.8,13.8-6,17.7-6.1c1.1,0,2-0.9,2-2c0-1.1-0.9-2-2-2c-4.7,0.1-12.4,2.5-19.6,6.6
c-1,0.6-4.6,2.6-4.8,2.7c-1.9,1.1-3.4,1.9-4.9,2.8c-5.3,3-9.6,5.5-13.5,8c-0.4,0.2-0.8,0.5-1.3,0.8l-1.1,0.7
c-8.8,5.5-12.6,8.5-15.9,12.8c-4.4,5.8-5.2,12.5-2,20.3c0.2,0.5,0.9,2.3,1,2.5c1.8,4.4,3,6.7,4.9,8.7c1.7,1.8,3.8,2.9,6.3,3.3
c-1.1,0.8-2.3,1.6-3.5,2.5c-11.7,9.1-17.8,18.7-25.6,37.3c-0.4,1,0,2.2,1.1,2.6c1,0.4,2.2,0,2.6-1.1c7.6-18,13.4-27.2,24.4-35.7
c3.8-2.9,7-4.8,11.8-6.9c2.4-0.7,5.3-1.8,9.2-3.4c1.4-0.6,2.6-1,3.7-1.5C303.8,109.6,309.2,107.8,310.7,107.3z"/>
<path id="Path_7_" class="st3" d="M272.3,107.4c-15.7,6.3-28.5,8.6-40.9,6.2c-10-2-16.4-10.3-19.9-23.9
c-2.6-10.3-3.2-22.6-2.5-34.9c0.1-1.1-0.8-2-1.9-2.1c-1.1-0.1-2,0.8-2.1,1.9c-0.8,12.7-0.1,25.4,2.6,36.2
c3.7,14.9,11.1,24.6,23,26.9c13.2,2.6,26.7,0.2,43.1-6.4c1-0.4,1.5-1.6,1.1-2.6S273.3,106.9,272.3,107.4z"/>
<path id="Path_8_" class="st3" d="M293.5-5c17.3-0.1,26.9,7,31.1,24.1c0.3,1.2,0.7,3,1.4,5.9l0,0.1c0.2,0.7,0.7,2.9,0.7,2.9
c0.3,1.1,0.4,1.8,0.6,2.4c0.3,1.1,1.3,1.7,2.4,1.5c1.1-0.3,1.7-1.3,1.5-2.4c-0.1-0.6-0.3-1.4-0.6-2.4c0,0.1-0.5-2.2-0.7-2.9
l0-0.1c-0.7-2.9-1.1-4.7-1.4-5.9c-4.7-18.9-15.9-27.2-35-27.1c-1.1,0-2,0.9-2,2C291.5-5.8,292.4-5,293.5-5z"/>
</g>
<g id="Point_x2F_Wear" transform="scale(1 1)">
<g id="Point_x2F_Wear_x2F_Phone">
<g id="clothing" transform="translate(115.000000, 466.000000)">
<path id="Path_9_" class="st4" d="M472.5-13.2c-1.1-8.3-3.3-25.5-11.2-33.6c-8.9-9.2-25.5-11-38.9-11.5l-6.6-0.2
c0,47.2,0,91.2,0,92c0,0.5-0.2,1-0.6,1.4c-0.4,0.4-0.9,0.6-1.4,0.6l-4.4,0.4c-0.1,0.1-0.1,0.2-0.1,0.4
c-0.3,1.4-0.8,2.9-1.4,4.2c-2.5,5.3-7.4,6.8-14.5,7.4c-5.4,0.4-10.9,0.5-16.4,0.2c-3.8-0.1-7.8-0.2-11.7-0.1
c-20.5,0.6-41.2,0.2-61.3-0.1l-9.7-0.2h-2.8c-2.8,0-5.7,0.1-8.5,0.1c-10.4,0.2-21.2,0.5-30.8-2.4c-0.2-0.1-0.3-0.1-0.5-0.1
c-16.8-0.3-31.1-1.5-36.5-14c-2.3-5.4-0.5-21.3,4.7-41.4c2.1-8.3,4.7-16.5,7.7-24.5v-23.2h-2.6c-11.6,0-27.5,0-36.9,4.3
c-16.7,7.7-18.8,27-20.4,41.1c-0.2,1.7-0.4,3.3-0.5,4.8c-1.9,15.2-1,42.4,0.8,61.5c0.9,8.7,7.4,15.8,17.6,19.1
c11.2,3.6,46,3.8,50,3.8c15.9,0,33.5,0.2,52.2,0.4c20.7,0.2,42,0.4,61.4,0.4c6.4,0,12.5,0,18.4-0.1l8.3-0.1
c22-0.2,44.6-0.3,66.1-2.6c25.8-2.7,27.6-19.4,29.2-34.1c0.2-1.7,0.4-3.5,0.6-5.2c1.2-9.6,2.6-36.8,1.2-47.4L472.5-13.2z"/>
<path id="Path_10_" class="st5" d="M463-9.4c-0.4-5.8-2.7-22.3-9.8-29.4c-7.7-7.6-22.5-9-34.2-9.4l-3.1-0.1
c0,26.6,0,51.2,0,66.3c-16.9,13.2-53,22-94.7,21.5c-41.4-0.5-77-10.1-93.7-23.6v-64.2c-11,0-24.8,0.3-31.7,3.3
c-16.1,7-16.4,26.6-18,38.5c-1.7,13.1-0.8,27.2,1.1,38.8c0.8,4.8,2.8,11.6,11.3,14.9c8.5,3.2,42.1,3.6,51.9,3.6
c36.3,0.1,86.3,1.1,122.5,0.8c22.2-0.2,50.3,0.2,72.2-2c24.6-2.5,23.2-14.8,25.1-29.2C463.1,10.5,463.5,0.6,463-9.4L463-9.4z"
/>
<path id="Path_11_" class="st6" d="M227.5,18.5v-39c-7.6,5.6-12,12.2-12.1,19.2c-0.1,5.4,2.3,10.6,7.1,15.5
C224,15.7,225.7,17.2,227.5,18.5L227.5,18.5z"/>
<path id="Path_12_" class="st6" d="M415.8-18.7c0,16,0,29.8,0,39.2c7.7-5.7,12.1-12.2,12.2-19.3c0.1-5.4-2.3-10.6-7.1-15.5
C419.3-15.8,417.6-17.3,415.8-18.7z"/>
<path id="Path_13_" class="st6" d="M174.5,53.4c3.3,5.3,12.9,7.6,28.3,8.4c4.6,0.2,7.9,0.3,15.9,0.4c2.7,0,4.1,0.1,5.5,0.1
c9.9,0.3,21.4,0.5,37.4,0.7c2.4,0,4.8,0.1,7.8,0.1c1.1,0,2.3,0,3.9,0c1.9,0,2.9,0,3.8,0c9.8,0.1,15.4,0.2,20.9,0.3
c38.1,0.6,78.7,0.3,124-0.8c12.4-0.3,24.2-2,32.5-5.1c1-0.4,1.6-1.5,1.2-2.6c-0.4-1-1.5-1.6-2.6-1.2c-7.9,3-19.3,4.6-31.2,4.9
c-45.2,1.1-85.8,1.4-123.8,0.8c-5.6-0.1-11.2-0.2-21-0.3c-0.9,0-1.9,0-3.8,0c-1.6,0-2.7,0-3.9,0c-2.9,0-5.4-0.1-7.8-0.1
c-16-0.2-27.5-0.4-37.4-0.7c-1.4,0-2.8-0.1-5.6-0.1c-7.9-0.1-11.2-0.2-15.7-0.4c-13.9-0.7-22.8-2.9-25.1-6.6
c-0.6-0.9-1.8-1.2-2.8-0.6C174.2,51.2,174,52.5,174.5,53.4z"/>
<path id="Path_14_" class="st6" d="M228.6,67.2c-5.5,0-12.8-0.1-15.4-0.3c-1.1-0.1-2,0.8-2.1,1.9c-0.1,1.1,0.8,2,1.9,2.1
c2.7,0.1,10.1,0.3,15.6,0.3c1.1,0,2-0.9,2-2S229.7,67.2,228.6,67.2z"/>
<path id="Path_15_" class="st6" d="M256,67c-5,0.1-9.7,0.2-16.2,0.2c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2
c6.5,0,11.3-0.1,16.3-0.2c1.1,0,2-0.9,2-2S257.1,66.9,256,67z"/>
<path id="Path_16_" class="st6" d="M420.1-9.1c2.7,3.4,4,6.9,3.9,10.4c-0.3,20.2-46.3,37-102.9,36.2
c-56.6-0.7-102.1-18.6-101.8-38.8c0.1-2.4,0.7-4.8,2-7c0.6-1,0.2-2.2-0.7-2.7c-1-0.6-2.2-0.2-2.7,0.7
c-1.6,2.7-2.4,5.8-2.5,8.9c-0.3,23.5,47.1,42.2,105.7,42.9C379.8,42.2,427.7,24.8,428,1.3c0.1-4.4-1.6-8.8-4.8-12.9
c-0.7-0.9-1.9-1-2.8-0.3C419.6-11.2,419.4-10,420.1-9.1z"/>
</g>
</g>
</g>
<g id="Point_x2F_Item" transform="scale(1 1)">
<g id="Point_x2F_Item_x2F_Email">
<g id="items" transform="translate(368.000000, 94.000000)">
<path id="Path_17_" class="st7" d="M306.1,6.4c-2.1-9.9-4.1-19.3-9.5-28.6c-7.6-13-25.5-10-38.6-7.7
c-14.2,2.4-50,10.6-63.3,14.7l-2.9,0.9c-12.2,3.7-23.7,7.3-25.7,17.6c-1.9,9.9-0.5,21,0.8,30.7c0.2,1.8,0.5,3.6,0.7,5.4
c0.1,1.2,0.3,2.4,0.4,3.7l0.2,1.8c6.6-4,13.6-7.4,20.4-8.6c5.7-1.2,11.6,1,15.2,5.6c4.6,5.9,5.7,13.8,3,20.7
c-2.5,5.8-7.3,11.9-12.7,17.7c4.7-0.2,9.3-0.8,13.9-1.7l0.8-0.1c7.8-1.3,22.6-4,34.9-6.9c4.8-1.1,10.7-2.4,16.4-3.7
c9.9-2.2,19.3-4.2,24-5.7l2-0.6c9.9-3,23.6-7.1,24.5-18.2c0.9-10.9-1.3-22.2-3.6-33C306.7,9.2,306.4,7.8,306.1,6.4z"/>
<path id="Path_18_" class="st8" d="M296.8,40.6c-0.4-0.3-10-8-14.8-11c-3.1-1.9-6.6-3.9-9.9-5.9c-4.4-2.5-8.8-5.1-12.8-7.7
c10.9-12.6,19.7-27.6,24.5-36.5c0.3-0.6,0.3-1.4-0.1-2c-0.4-0.6-1.1-1-1.8-0.9c-0.7,0-1.4,0.4-1.7,1.1
c-5.9,10.9-17.9,31.2-32.2,44.3c-6,5.5-10.2,6.5-17.8,4.1c-9.4-2.9-18.4-6.9-27.1-10.8l-2-0.9c-5.9-2.6-19.8-10.3-19.9-10.3
c-1-0.5-2.1-0.1-2.6,0.8c-0.5,0.9-0.2,2.1,0.7,2.7c0.6,0.3,14.1,7.8,20.2,10.5l2,0.9c4.4,2,8.8,3.9,13.4,5.8
c-1.3,1.8-2.7,3.6-4.1,5.5c-2.5,3.3-5.2,6.8-7.5,10.4l-0.2,0.4c0.3,0.3,0.5,0.6,0.8,0.9c0.6,0.8,1.2,1.7,1.7,2.6l1.1-1.7
c2.2-3.4,4.8-6.8,7.3-10.1c1.7-2.2,3.2-4.3,4.7-6.4c3.4,1.3,6.8,2.5,10.3,3.6c2.5,0.8,5.2,1.3,7.9,1.4c4.9,0,9.1-2,13.8-6.4
c2-1.8,3.9-3.8,5.8-5.9c4.2,2.7,8.9,5.5,13.5,8.1c3.3,1.9,6.7,3.9,9.8,5.8c4.6,2.9,14.4,10.6,14.5,10.7
c0.4,0.3,0.8,0.4,1.2,0.4c0.8,0,1.6-0.5,1.9-1.3S297.5,41.1,296.8,40.6L296.8,40.6z"/>
<path id="Path_19_" class="st9" d="M302.9-48.3c-2.5-5.5-7.8-9.3-14.4-10.4c-3.7-0.6-7.4-0.2-10.9,1.1
c-5.5,1.9-9.8,6.3-11.7,11.9c-2.4,7.5-0.4,18,7.8,23.4c3.3,2.3,7.2,3.5,11.2,3.5c4.8-0.1,9.4-1.7,13.1-4.8
c3.5-3,5.8-7.1,6.6-11.6C305.2-39.6,304.6-44.2,302.9-48.3L302.9-48.3z"/>
<path id="Path_20_" class="st5" d="M284.7-40.4c0,1.6-0.1,3.3-0.2,5c0,0.9-0.1,1.7-0.1,2.4c0,0.4,0,0.8-0.1,0.9
c-0.1,1.1,0.8,2.1,1.9,2.1c1.1,0.1,2.1-0.8,2.1-1.9c0-0.2,0-0.5,0.1-1c0-0.8,0.1-1.6,0.1-2.5c0.1-1.8,0.1-3.5,0.2-5.1
c0-2.7,0-4.9-0.1-6.4c-0.1-1.5-1.7-2.3-3-1.5c-2.5,1.4-4.8,3-7.1,4.8c-0.9,0.7-1,1.9-0.4,2.8c0.7,0.9,1.9,1,2.8,0.4
c1.2-1,2.5-1.9,3.8-2.7C284.7-42.3,284.7-41.4,284.7-40.4z"/>
</g>
</g>
</g>
</g>
</g>
<g id="Master_x2F_Hands_x2F_Phone_1_" transform="translate(0.000000, -0.000000) scale(1 1)">
<g id="Master_x2F_Hands_x2F_Phone">
<g id="base_1_" transform="translate(170.000000, 85.000000)">
<path id="Path_21_" class="st10" d="M33.3,63.1c0.1-0.7,0.6-1.3,1.3-1.5c5-1.8,10.1-3.3,15.2-4.4c0.2-0.1,0.5-0.1,0.8-0.2
c4.2-1,5.7-1.3,7.9-1.1c3,0.2,5.6,1.5,7.8,4.2c3.1,3.8,5.1,8.9,6.2,14.6c0.6,3.4,0,8.2-1.7,10.9c-1.9,3.1-5,5.8-9.5,8.8
c-0.8,0.5-1.6,1.1-2.6,1.7c-0.4,0.2-0.8,0.5-1.2,0.8c-0.2,0.1-1,0.6-1.2,0.7c-1.8,1.1-3.3,2.1-6.2,4.1c-0.3,0.2-0.3,0.2-0.6,0.4
c-4.5,3.1-6.9,4.6-9.8,6.2c-4.7,2.4-9.1,5.3-13.3,8.6c-1.5,1.2-3.6-0.1-3.2-2L33.3,63.1z"/>
<path id="Path_22_" class="st10" d="M46.2,181.6c13.1-2.3,37.7-9.8,42.4-14.7c4.6-4.7,6.3-11.2,6.2-19.9c0-2.5-0.2-4.8-0.5-8.7
l-0.1-1.3c-0.8-8.3-2.3-16.5-4.7-24.4c-2.7-9.6-7-11.8-18.8-11.2c-12.2,0.8-24.3,2.5-36.2,5c-1,0.2-1.7,1.2-1.6,2.3l10.9,71.2
C44,181,45.1,181.8,46.2,181.6z"/>
<path id="Path_23_" d="M89.6,134c-3,0.4-6.5,0.8-10.7,1.3c-3.1,0.4-6.3,0.7-11.1,1.2c-13.5,1.4-16.2,1.7-21.2,2.4
c-1.1,0.1-1.9,1.1-1.7,2.2c0.1,1.1,1.1,1.9,2.2,1.7c5-0.6,7.7-0.9,21.2-2.4c4.8-0.5,8-0.9,11.1-1.2c4.2-0.5,7.7-0.9,10.8-1.3
c1.1-0.1,1.9-1.1,1.7-2.2C91.7,134.6,90.7,133.9,89.6,134z"/>
<path id="Path_24_" class="st10" d="M18.6,157.1c-7.4-9.2-14.8-15.9-22.5-19.9c-10.8-5.6-23.2-9.2-34.7-9.6
c-13.6-0.5-25.3,3.5-33.6,12.5c-1.8,2-3.3,4.4-4.6,7.8l-5.8-18.8c-0.4-1.4-2.1-1.9-3.2-0.9c-3.8,3.2-9.4,11-16.2,22.2
c-4.6,7.6-9,15.3-13.5,23.4c-1.1,2.1-2.3,4.4-3.5,7c-3,6.3-6.1,14-9.5,23.2c-1.6,4.4-3.3,8.9-5.2,14.4
c-0.8,2.3-3.8,10.8-4.5,12.8c-9.6,27.2-15.4,57-21.8,104.3c-1.3,9.3-2.3,23.1-3.1,40.2c-0.5,11.5-1,48.9-1.3,61.3
c-0.1,4.3-0.2,8.3-0.3,12c0,1.3,0,2.4-0.1,3.4c0,0.3,0,0.5,0,0.9c0,0.3,0,0.3,0,0.3c0,1.1,0.9,2,2,2l158.9,0.2c1.1,0,2-0.9,2-2
c0-42.6,2.3-123,6.3-141.8c3.2-15,9.1-33.5,15.7-50c3.1-7.8,6.8-16.2,11.8-27c1.5-0.2,3-0.5,4.5-0.9c7.1-1.8,9.2-2.3,12.9-3.5
c14.2-4.6,22.7-11.1,24.2-21.7c1.2-8.6-2.7-20.2-8.8-26.1c-4.4-4.2-10.5-5.3-18.6-4.3c-2.4,0.3-4.8,0.7-8.2,1.4
c-0.5,0.1-2.2,0.5-2.5,0.5c-0.3,0.1-0.7,0.1-0.9,0.2C28.4,170.3,23.9,163.7,18.6,157.1z"/>
<path id="Path_25_" d="M21.1,197.8C8.9,199,1.8,209,5.4,220.4c0,0.1,1.3,4.5,1.8,6c1.3,4,2.7,6.7,4.6,8.4
c5.3,4.5,10.5,5.4,17.8,3.6c1.1-0.3,1.7-1.3,1.5-2.4c-0.3-1.1-1.3-1.7-2.4-1.5c-6.1,1.5-10,0.9-14.2-2.7c-1.2-1-2.3-3.2-3.4-6.6
c-0.5-1.4-1.7-5.7-1.8-5.9c-2.8-8.9,2.5-16.4,12.3-17.4c1.1-0.1,1.9-1.1,1.8-2.2C23.2,198.4,22.2,197.7,21.1,197.8z"/>
<path id="Path_26_" class="st4" d="M11.2,203.6L11.2,203.6c-10.3,1.8-40.5,3.3-53.9,3c-1.4,0-2.8,0-4.7-0.1c-0.3,0-0.6,0-1.2,0
c-13.1-0.1-18.7-0.5-24.8-2.8c-8.3-3.1-13.6-9.3-15.9-19.5c-2.5-10.9-4.2-22.7-5.8-37.6c-0.6-5.6-0.9-8.8-2-20.4
c-0.2-2.4-0.4-4-0.5-5.7c-1.4-14.8-2.7-31.2-4.5-56.9c0.2,2.4-1.7-24.5-2.2-31.5c-0.7-9.7-1.3-17.7-1.9-24.9
c-1.5-18.1-1.7-36.2,0.8-43.4c2.9-9.1,10.9-15.6,20.3-16.8c23.9-3.6,53.9-6.3,69.8-6c1.4,0,2.7,0,5.4,0.1
c8.1,0.1,11.8,0.1,16.6,0.5c15,1.2,25.5,5.1,31.6,13.4c3.3,4.5,5.2,11.1,6.5,19.9c0.3,2.2,0.6,4.5,0.8,7.2
c0.1,1,0.2,2.1,0.3,3.4c0-0.2,0.2,2.5,0.3,3.2c0.1,0.9,0.1,1.6,0.2,2.3c0,0.5,0,0.5,0.1,1.1c2,22,2.1,22.6,2.9,30.8
c0.6,5.6,1.1,10.8,1.7,15.7c5.2,44.2,8.4,81.5,9.5,117.7c0.5,16.3-1.9,27.4-10.4,34.7c-4,3.4-10.6,6.2-19.1,8.5
c-3.5,1-7.3,1.8-11.3,2.6c-1.5,0.3-3,0.6-4.7,0.9C14.1,203.1,11.7,203.5,11.2,203.6z"/>
<path id="Path_27_" class="st5" d="M6.8,195.3c-11.9,1.3-23.8,1.9-35.7,1.7c-17.4-0.4-32.1,1.9-36.8-19
c-4.2-18.6-5.8-42.7-7.6-61.8c-2.9-31-5.3-74-7.8-105.2c-0.7-8.4-2.7-37.3,0.6-44.8s11.2-9.9,17-11c13.8-2.7,30.6-4.7,46.3-4.4
c14.3,0.3,37.8-1.2,47.3,12c5.6,7.7,6.1,26.6,7,35.8c1.4,14.2,2.6,28.9,4.3,43.3c4.2,35.5,7.5,76,8.7,112
c0.3,10-0.3,22.9-8.8,30.2C33.3,191,13.7,194.4,6.8,195.3z"/>
<path id="Path_28_" class="st6" d="M-88.2-46.8c-4.9,3.3-6.5,11.6-6.2,24.8c0.1,3.3,0.2,6.6,0.5,11.2c0,0.7,0.2,3.4,0.3,4
c0.1,1.4,0.2,2.5,0.2,3.4c0.4,8.5,1,18.5,1.9,32.1c0.1,1.9,0.3,3.9,0.4,6.2c0.1,1.5,0.7,10.5,0.9,13c0.3,4.9,0.6,8.7,0.8,12.1
c2.1,32.7,5.2,67.6,9.3,106.3c1.1,10.7,3.5,20.7,7.1,27.7c0.5,1,1.7,1.4,2.7,0.9s1.4-1.7,0.9-2.7c-3.3-6.5-5.6-16.1-6.7-26.3
c-4.2-38.6-7.3-73.5-9.3-106.2c-0.2-3.5-0.5-7.3-0.8-12.2c-0.2-2.5-0.8-11.5-0.9-13c-0.2-2.3-0.3-4.3-0.4-6.2
c-0.9-13.6-1.5-23.5-1.9-32c0-1-0.1-2-0.2-3.5c0-0.7-0.2-3.4-0.3-4c-0.3-4.5-0.4-7.8-0.5-11.1c-0.2-11.7,1.2-19.2,4.5-21.4
c0.9-0.6,1.2-1.9,0.6-2.8S-87.3-47.5-88.2-46.8z"/>
<path id="Path_29_" class="st10" d="M-113.8,237.2c-1.5,0-2.4-1.7-1.7-3c2.6-4.5,5.5-9.3,9.2-15c1.5-2.3,3.1-4.7,5.1-7.9
c0.7-1,3.1-4.7,2.9-4.4c1.2-1.8,2-3.1,2.9-4.4c2.1-3.3,3.9-6,5.5-8.6c12.5-20,25.6-35.9,39.7-46.9c8.1-6.3,17.6-4.7,23.7,3.9
c3.2,4.5,3.3,9.5,1.2,15.6c-0.8,2.4-1.8,4.6-3.6,8.1c-2.3,4.6-2.3,4.6-3,6.1c-2.4,5.5-4,14.9-4.3,23.7
c-0.1,3.8,0.3,8.1,1.3,12.9c0.7,3.8,1.7,7.7,3.1,12.6c0.3,1,0.6,2.1,1,3.4c0.1,0.3,0.8,2.6,0.9,3.2c0.4,1.3-0.6,2.6-2,2.6
L-113.8,237.2z"/>
<path id="Path_30_" class="st6" d="M-96.8,22.2c-0.4-5.6-0.7-11.2-0.9-16.6c0-1.1-1-2-2.1-1.9c-1.1,0-2,1-1.9,2.1
c0.2,5.5,0.5,11.1,0.9,16.7c0.1,1.1,1,1.9,2.1,1.9C-97.6,24.3-96.7,23.3-96.8,22.2z"/>
<path id="Path_31_" class="st6" d="M-94.8,49.8c-0.5-5.4-0.9-11-1.2-17.1c-0.1-1.1-1-2-2.1-1.9c-1.1,0.1-2,1-1.9,2.1
c0.3,6.1,0.7,11.9,1.2,17.3c0.1,1.1,1.1,1.9,2.2,1.8C-95.5,51.8-94.7,50.9-94.8,49.8z"/>
<path id="Path_32_" d="M-36.7,208.6c0.7,6.9,2.3,12.2,5.5,20c0.2,0.4,0.4,0.9,0.6,1.4c0.1,0.4,0.1,0.4,0.3,0.7
c0.1,0.4,0.2,0.5,0.3,0.7c0.5,1.1,0.8,1.9,1.1,2.8c0.4,1,1.6,1.5,2.6,1.1c1-0.4,1.5-1.6,1.1-2.6c-0.3-0.8-0.7-1.7-1.2-2.8
c-0.1-0.2-0.1-0.4-0.3-0.7c-0.1-0.4-0.1-0.4-0.3-0.7c-0.2-0.6-0.4-1-0.6-1.4c-3.1-7.4-4.6-12.5-5.2-18.9
c-0.1-1.1-1.1-1.9-2.2-1.8C-36,206.5-36.8,207.5-36.7,208.6z"/>
<path id="Path_33_" d="M-113.7,231.2c2.5-4.4,5.4-9.2,9-14.8c1.5-2.3,3.1-4.7,5.1-7.9c0.7-1,3.1-4.7,2.9-4.4
c1.2-1.8,2-3.1,2.9-4.4c2.2-3.3,3.9-6.1,5.6-8.7c0.6-0.9,0.3-2.2-0.6-2.8c-0.9-0.6-2.2-0.3-2.8,0.6c-1.6,2.6-3.4,5.3-5.5,8.6
c-0.8,1.3-1.7,2.6-2.9,4.4c0.2-0.3-2.2,3.4-2.9,4.4c-2.1,3.2-3.6,5.6-5.2,7.9c-3.6,5.7-6.6,10.4-9.1,14.9
c-0.5,1-0.2,2.2,0.7,2.7C-115.5,232.5-114.2,232.2-113.7,231.2z"/>
<path id="Path_34_" d="M-30.6,289.7c2,0.5,4.1,1.1,6,1.9c1,0.4,2.2-0.1,2.6-1.1c0.4-1-0.1-2.2-1.1-2.6c-2.1-0.9-4.4-1.6-6.6-2.1
c-1.1-0.2-2.1,0.4-2.4,1.5C-32.4,288.4-31.7,289.4-30.6,289.7z"/>
</g>
<g id="Phone_x2F_Wear" transform="scale(1 1)">
<g id="Phone_x2F_Wear_x2F_Nails">
<g id="clothing_1_" transform="translate(277.000000, 290.000000)">
<path id="Path_35_" class="st11" d="M-152.9-58.2c4.9-1.9,10.8-0.9,13.8,4.1c2.4,4.1,0.1,9.6-2.7,12.6
c-3.7,4.1-6.9,3.6-12.2,1.5c-2.7-1-6.8-3-9.3-5.5c-0.9-0.9-1.2-2.3-0.5-3.5C-161.5-53.2-157.6-56.5-152.9-58.2z"/>
<path id="Path_36_" class="st11" d="M-85.6,1.8c-3.8,1.8-7.4,4.5-7.8,8.9c-0.3,4.1,1.4,10.5,4.9,11.9
c3.1,1.2,7.4,1.1,11.3,0.6c1.4-0.3,2.7-0.7,4-1.2c1.2-0.5,2.1-1.6,2.2-2.9c0.2-2.1,0.2-4.3-0.2-6.4c-0.8-3.8-2.5-9.1-5.4-11.6
c-0.9-0.8-2-1.1-3.2-0.9C-81.8,0.6-83.7,1.1-85.6,1.8L-85.6,1.8z"/>
</g>
</g>
</g>
<g id="Phone_x2F_Item" transform="scale(1 1)">
<g id="Phone_x2F_Item_x2F_Selfie">
<g id="items_1_" transform="translate(261.000000, 137.000000)">
<path id="Path_37_" class="st12" d="M-161.9-41.3c-1.1,0-2-0.8-2-1.9c-0.1-2-0.1-3.7-0.2-5.1c0-0.9,0.6-1.8,1.5-2
c1.5-0.4,3.2-0.8,5-1.1c1.1-0.2,2.1,0.5,2.3,1.6c0.2,1.1-0.4,2.1-1.5,2.3c-1.1,0.2-2.2,0.5-3.2,0.7c0,1,0.1,2.1,0.1,3.3
c0,0.5-0.2,1.1-0.5,1.4c-0.4,0.4-0.9,0.6-1.4,0.7L-161.9-41.3z"/>
<path id="Shape_1_" class="st12" d="M-153.4,78.6c-1,0-1.9-0.8-2-1.8c-0.3-3-0.5-6.1-0.8-9.2c-0.1-0.7,0.3-1.4,0.9-1.8
c0.6-0.4,1.4-0.5,2-0.2c0.6,0.3,1.1,0.9,1.1,1.6c0.3,3.1,0.5,6.2,0.8,9.2c0,0.5-0.1,1.1-0.5,1.5c-0.3,0.4-0.8,0.7-1.4,0.7
H-153.4z M-155.4,54.6c-1,0-1.9-0.8-2-1.8c-0.3-3.5-0.5-6.7-0.7-9.3c-0.1-1.1,0.8-2.1,1.9-2.1c1.1-0.1,2.1,0.8,2.1,1.9
c0.2,2.6,0.4,5.7,0.7,9.2c0,0.5-0.1,1.1-0.5,1.5s-0.8,0.7-1.4,0.7H-155.4z M-157,30.6c-1,0-1.9-0.8-2-1.9
c-0.2-2-0.3-3.9-0.5-5.8l-0.3-3.4c-0.1-1.1,0.7-2.1,1.9-2.2s2.1,0.7,2.1,1.8l0.3,3.4c0.2,1.9,0.3,3.9,0.5,5.8
c0,0.5-0.1,1.1-0.5,1.5s-0.8,0.7-1.4,0.7H-157z M-158.7,6.6c-1.1,0-1.9-0.8-2-1.9c-0.1-1.9-0.2-3.8-0.3-5.8
c0-1-0.1-2.1-0.2-3.4c0-0.7,0.3-1.4,0.9-1.8s1.4-0.4,2-0.1c0.6,0.3,1.1,1,1.1,1.7c0.1,1.3,0.2,2.5,0.2,3.5
c0.1,2,0.2,3.9,0.3,5.7c0.1,1.1-0.8,2-1.9,2.1L-158.7,6.6z M-162.3-19.2c-0.2-3-0.5-6.2-0.7-9.2c-0.1-0.7,0.3-1.4,0.9-1.8
c0.6-0.4,1.4-0.5,2-0.1c0.6,0.3,1.1,0.9,1.1,1.7c0.2,3.1,0.5,6.2,0.7,9.2L-162.3-19.2z"/>
<path id="Path_38_" class="st12" d="M-151.6,98.3c-1,0-1.9-0.8-2-1.8l-0.5-5c0-0.5,0.1-1.1,0.5-1.5c0.3-0.4,0.8-0.7,1.4-0.7
c1.1-0.1,2.1,0.7,2.2,1.8l0.3,3l3-0.2c0.5,0,1.1,0.1,1.5,0.5c0.4,0.3,0.6,0.8,0.7,1.4c0.1,1.1-0.8,2-1.9,2.1
C-149.4,98.1-151.5,98.3-151.6,98.3L-151.6,98.3z"/>
<path id="Path_39_" class="st12" d="M-56.9,90c-1.1,0.1-2-0.8-2.1-1.9s0.8-2,1.9-2.1l3-0.3l-0.2-3c-0.1-0.7,0.3-1.4,0.9-1.8
c0.6-0.4,1.4-0.5,2-0.2s1.1,0.9,1.1,1.6l0.4,5c0.1,1.1-0.7,2-1.8,2.2c-1.7,0.2-3.3,0.3-5,0.5L-56.9,90z"/>
<path id="Shape_2_" class="st12" d="M-53.6,69.8c-1,0-1.9-0.8-2-1.8c-0.2-3.1-0.5-6.2-0.7-9.2c-0.1-0.7,0.3-1.4,0.9-1.8
c0.6-0.4,1.4-0.5,2-0.2c0.6,0.3,1.1,0.9,1.1,1.7c0.2,3,0.5,6,0.7,9.1c0.1,1.1-0.7,2.1-1.8,2.2L-53.6,69.8z M-55.4,46
c-1,0-1.9-0.8-2-1.9c-0.2-3-0.5-6-0.7-9.2c0-0.5,0.1-1.1,0.5-1.5c0.3-0.4,0.8-0.6,1.4-0.7c0.5,0,1.1,0.1,1.5,0.5
s0.6,0.8,0.7,1.4c0.2,3.1,0.4,6.2,0.7,9.2c0,0.5-0.1,1.1-0.5,1.5c-0.3,0.4-0.8,0.7-1.4,0.7H-55.4z M-57.1,22.2
c-1.1,0-1.9-0.8-2-1.9l-0.1-1.2c-0.2-2.7-0.4-5.3-0.6-8c-0.1-1.1,0.8-2.1,1.9-2.1s2.1,0.8,2.1,1.9c0.2,2.7,0.4,5.3,0.6,8
l0.1,1.2c0.1,1.1-0.8,2.1-1.9,2.1L-57.1,22.2z M-58.9-1.6c-1,0-1.9-0.8-2-1.8c-0.2-3-0.5-6.1-0.8-9.1
c-0.1-1.1,0.7-2.1,1.8-2.2s2.1,0.7,2.2,1.8c0.3,3.1,0.5,6.1,0.8,9.2c0,0.5-0.1,1.1-0.5,1.5c-0.3,0.4-0.8,0.7-1.4,0.7H-58.9z
M-61-25.3c-1,0-1.9-0.8-2-1.8c-0.3-3-0.6-6.1-0.9-9.1c-0.1-0.7,0.2-1.4,0.8-1.8c0.6-0.4,1.3-0.5,2-0.2
c0.7,0.3,1.1,0.9,1.2,1.6c0.3,3.1,0.6,6.1,0.9,9.2c0.1,0.5-0.1,1.1-0.4,1.5c-0.3,0.4-0.8,0.7-1.4,0.7L-61-25.3z"/>
<path id="Path_40_" class="st12" d="M-63.8-49.1c-1,0-1.9-0.7-2-1.7c-0.2-1.3-0.3-2.4-0.5-3.3l-3.3-0.1c-1.1,0-2-0.9-2-2
c0-1.1,0.9-2,2-2l0,0l5,0.1c1,0,1.8,0.7,1.9,1.7c0,0,0.3,2.1,0.7,5c0.2,1.1-0.6,2.1-1.7,2.3L-63.8-49.1z"/>
<path id="Shape_3_" class="st12" d="M-142.4-49.6c-1.1,0.1-2-0.8-2.1-1.9c-0.1-1.1,0.8-2,1.9-2.1l5.4-0.6l3.9-0.4
c1.1-0.1,2.1,0.7,2.2,1.8c0.1,1.1-0.7,2.1-1.8,2.2l-3.9,0.4l-5.4,0.6L-142.4-49.6z M-118.2-52.4c-1.1,0.1-2-0.8-2.1-1.9
s0.8-2,1.9-2.1c3.1-0.3,6.3-0.6,9.4-0.8c1.1-0.1,2.1,0.7,2.2,1.8c0.1,1.1-0.7,2.1-1.9,2.2c-3.1,0.2-6.2,0.5-9.3,0.8
L-118.2-52.4z M-93.9-54c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2c3.1-0.1,6.2-0.2,9.4-0.2c1.1,0,2,0.9,2,2s-0.9,2-2,2
C-87.7-54.2-90.8-54.1-93.9-54L-93.9-54z"/>
<path id="Path_41_" class="st12" d="M-119.8,94.1c-0.1-1.1-1.1-1.9-2.2-1.8l-3.1,0.2c1.7,0.8,3.3,1.9,4.7,3.2
C-119.9,95.3-119.7,94.7-119.8,94.1L-119.8,94.1z"/>
<path id="Path_42_" class="st12" d="M-97.1,90.2l-9.5,0.8c-1.1,0-2,1-1.9,2.1s1,2,2.1,1.9h0.2c3.2-0.3,6.5-0.6,9.6-0.8
c1.1-0.1,1.9-1.1,1.8-2.2C-95,90.9-96,90.1-97.1,90.2L-97.1,90.2z"/>
<path id="Path_43_" class="st12" d="M-81.6,92.8h0.2l1.7-0.2c2.6-0.3,5.2-0.6,7.9-0.9c1.1-0.1,1.9-1.1,1.8-2.2
c-0.1-1.1-1.1-1.9-2.2-1.8c-2.7,0.3-5.3,0.6-7.9,0.9l-1.6,0.2c-1.1,0.1-2,1-1.9,2.1S-82.7,92.9-81.6,92.8L-81.6,92.8z"/>
<path id="Path_44_" class="st13" d="M-104.4-40c-1.7-1.6-4.3,0.5-3.1,2.5c0.6,1,1.3,1.9,2.2,2.8c2,3.2,2.9,7.5,1,9.4
c-2.6,2.6-5.9,1.7-12.1-2.4c-3.2-2.1-6.1-5.1-10.3-10.3c-0.5-0.6-2.7-3.3-3.3-4.1c-1.3-1.6-2.3-2.7-3.3-3.8
c-0.7-0.8-2-0.9-2.8-0.1c-0.8,0.7-0.9,2-0.1,2.8c0.9,1,1.9,2.2,3.2,3.7c0.6,0.7,2.8,3.5,3.3,4.1c4.5,5.5,7.6,8.7,11.2,11.1
c3.3,2.2,5.6,3.5,8,4.1c3.5,0.9,6.6,0.3,9.1-2.2c2.2-2.2,2.7-5.1,2-8.4c3.2,1.3,6.6,1.5,9.1-0.1c2.2-1.4,3.7-4.5,3.6-7.1
c1.5-0.2,3-0.7,4.2-1.6c2.8-2.1,3.9-5.7,3.3-9.9c-0.2-1.1-1.2-1.8-2.3-1.7s-1.8,1.2-1.7,2.3c0.4,2.9-0.2,5-1.7,6.1
c-0.9,0.7-2.1,1-3.4,0.9c-0.3-0.4-0.6-0.8-1-1.1c-1.7-1.7-3.8-2.4-5.4-0.5c-0.6,0.7-0.6,1.8,0,2.5c1,1.3,2.4,2.2,3.8,2.7
c0,0,0,0,0,0.1c0.4,1.1-0.5,3.4-1.7,4.2c-2.2,1.4-7-0.5-9.8-3.2C-103-38.5-103.7-39.3-104.4-40z"/>
<path id="Path_45_" class="st13" d="M-140.2-7.3c1.3-2,7.2-1.6,11.8,0.4c1,0.4,2.2,0,2.6-1s0-2.2-1-2.6
c-6.3-2.7-14-3.4-16.8,1.1c-0.6,0.9-0.3,2.2,0.6,2.8C-142-6.1-140.8-6.3-140.2-7.3z"/>
<path id="Path_46_" class="st13" d="M-90.8-6.7c2-1.6,5.5-1.8,9.4-0.8c1.1,0.3,2.2-0.4,2.4-1.4c0.3-1.1-0.4-2.2-1.4-2.4
c-5-1.3-9.6-1-12.9,1.6c-0.9,0.7-1,1.9-0.3,2.8S-91.6-6.1-90.8-6.7z"/>
<path id="Path_47_" class="st13" d="M-86.7,8.1l0.5,5.4c0.1,1.1,1.1,1.9,2.2,1.8c1.1-0.1,1.9-1.1,1.8-2.2l-0.5-5.4
c-0.1-1.1-1.1-1.9-2.2-1.8C-86,6-86.8,7-86.7,8.1z"/>
<path id="Path_48_" class="st13" d="M-134.1,12l0.4,5.4c0.1,1.1,1.1,1.9,2.2,1.8c1.1-0.1,1.9-1.1,1.8-2.2l-0.4-5.4
c-0.1-1.1-1.1-1.9-2.2-1.8C-133.4,10-134.2,10.9-134.1,12z"/>
<path id="Path_49_" class="st13" d="M-106.7,3.2c1.5,8.2,2.4,16.6,2.6,25c0.1,3.7-0.4,7.3-1.3,9.3c-0.8,1.6-1.2,1.7-2.8,0.4
c-1.6-1.3-2.6-4.2-2.9-7.6c-0.1-1.1-1.1-1.9-2.2-1.8s-1.9,1.1-1.8,2.2c0.5,4.3,1.8,8,4.3,10.2c3.7,3.2,7.2,2.2,9-1.7
c1.2-2.7,1.8-6.8,1.7-11.1c-0.2-8.6-1.1-17.2-2.7-25.6c-0.2-1.1-1.2-1.8-2.3-1.6C-106.2,1.1-106.9,2.1-106.7,3.2z"/>
<path id="Path_50_" class="st13" d="M-132.2,52c4.3,9.7,15.6,14.8,26.2,12.5c1.1-0.2,1.8-1.3,1.5-2.4
c-0.2-1.1-1.3-1.8-2.4-1.5c-8.8,1.9-18.1-2.3-21.7-10.2c-0.5-1-1.6-1.5-2.6-1S-132.6,51-132.2,52z"/>
</g>
</g>
</g>
<g id="Phone_x2F_Effect" transform="scale(1 1)">
<g id="Phone_x2F_Effect_x2F_Like">
<g id="addons" transform="translate(427.000000, 65.000000)">
<path id="Combined-Shape" class="st12" d="M-131.3-58.4c2.7,0.1,3.7,0.1,5,0.1c9.5,0,18.7,0.5,28.4,1.4c4.8,0.5,6.8,1.8,8.5,6
c1,2.5,1.4,5.3,1.5,8.8c0,1.7,0,3.2-0.1,5.9c0,0.5,0,0.7,0,0.9c-0.2,5.1-0.1,10.2,0.1,17.7c0,1,0,1.8,0.1,3.6
c0.1,3.8,0.2,5.6,0.2,7.7c0.1,6.2-0.8,12.6-3,16.4c-1.8,3.1-4.8,4.9-9,5.6c-3,0.6-6.1,0.6-11.7,0.4c-0.2,0-0.4,0-0.8,0
c-3-0.1-5-0.2-6.7-0.1l0.1-0.4c-3.4,9.2-5.1,13.3-8,18.2c-0.9,1.5-3.1,1.2-3.6-0.4c-0.3-0.9-0.6-1.8-1-3.2
c-0.3-0.9-0.4-1.3-0.6-1.7c-1.4-4.4-2.3-7.1-3.1-10.1c-0.2-0.6-0.4-1.2-0.6-2l-10.9,0c-7.7,0-12.3-1.6-14.6-7
c-1.5-3.5-2.2-7.7-2.5-13.1c-0.1-1.8-0.1-3.2-0.2-6.5c0-2.3-0.1-3.4-0.1-4.6c-0.1-1.6-0.1-2.8-0.3-5.8
c-0.2-3.4-0.3-5.1-0.4-7.1c-0.2-6.2,0.1-11.1,1.2-15.6c1.5-6.1,5-10.2,10.4-12.5c4.2-1.8,9.2-2.4,16.1-2.4l0.7,0
C-135.1-58.5-133.7-58.5-131.3-58.4z"/>
<path id="Path_51_" class="st9" d="M-122.4-37.4c5.5-5,11.8-7.3,17.2-3.8c4.6,3,5.2,10.3,2.8,15.5
c-3.1,6.5-8.8,13.6-15.9,20.5c-1,1-2.3,2.1-3.9,3.3c-0.4,0.3-0.9,0.7-1.3,1c-1.5,1.2-3.1,2.3-4.7,3.5
c-0.6,0.4-1.1,0.8-1.6,1.1c-0.3,0.2-0.5,0.3-0.6,0.4c-0.7,0.5-1.7,0.5-2.4-0.1c-8.2-6.4-16.5-21.7-16.8-31.7
c-0.2-5.5,1.8-10.6,5.3-13.4c3.9-3.1,9-2.6,13.5,1.7c2,1.9,3.1,4.8,3.6,8C-125.6-33.8-124-35.9-122.4-37.4z"/>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 28 KiB

View file

@ -0,0 +1,14 @@
import { sizingGrid, sizingX, sizingY } from "@html_builder/core/builder_overlay/builder_overlay";
import { patch } from "@web/core/utils/patch";
patch(sizingX, {
selector: sizingX.selector + ", .row > div",
exclude: sizingX.exclude + ", .o_mail_no_options, .s_col_no_resize.row > div, .s_col_no_resize",
});
patch(sizingY, {
selector: sizingY.selector + ", .o_mail_snippet_general, .o_mail_snippet_general .row > div",
exclude: sizingY.exclude + ", .o_mail_no_options, .s_col_no_resize.row > div, .s_col_no_resize",
});
patch(sizingGrid, {
exclude: sizingY.exclude + ", .o_mail_no_options, .s_col_no_resize.row > div, .s_col_no_resize",
});

View file

@ -0,0 +1,23 @@
import { BaseOptionComponent } from "@html_builder/core/utils";
export const FONT_FAMILIES = {
Arial: "Arial,Helvetica Neue,Helvetica,sans-serif",
"Courier New": "Courier New,Courier,Lucida Sans Typewriter,Lucida Typewriter,monospace",
Georgia: "Georgia,Times,Times New Roman,serif",
"Helvetica Neue": "Helvetica Neue,Helvetica,Arial,sans-serif",
"Lucida Grande": "Lucida Grande,Lucida Sans Unicode,Lucida Sans,Geneva,Verdana,sans-serif",
Tahoma: "Tahoma,Verdana,Segoe,sans-serif",
"Times New Roman": "TimesNewRoman,Times New Roman,Times,Baskerville,Georgia,serif",
"Trebuchet MS": "Trebuchet MS,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Tahoma,sans-serif",
Verdana: "Verdana,Geneva,sans-serif",
};
export class FontFamilyPicker extends BaseOptionComponent {
static template = "mass_mailing.FontFamilyPicker";
static props = {
action: String,
actionParam: Object,
extraClass: { type: String, optional: true },
};
FONT_FAMILIES = FONT_FAMILIES;
}

View file

@ -0,0 +1,9 @@
<templates>
<t t-name="mass_mailing.FontFamilyPicker">
<BuilderSelect className="props.extraClass" action="this.props.action" actionParam="this.props.actionParam">
<t t-foreach="this.FONT_FAMILIES" t-as="fontFamily" t-key="fontFamily">
<BuilderSelectItem t-out="fontFamily" actionValue="fontFamily_value"/>
</t>
</BuilderSelect>
</t>
</templates>

View file

@ -0,0 +1,73 @@
import { Component } from "@odoo/owl";
import { Builder } from "@html_builder/builder";
import { CORE_PLUGINS } from "@html_builder/core/core_plugins";
import { removePlugins } from "@html_builder/utils/utils";
import { DYNAMIC_PLACEHOLDER_PLUGINS } from "@html_editor/backend/plugin_sets";
import { registry } from "@web/core/registry";
import { CustomizeTab } from "@html_builder/sidebar/customize_tab";
import { OptionsContainerWithSnippetVersionControl } from "./options/options_container";
import { PowerButtonsPlugin } from "@html_editor/main/power_buttons_plugin";
class CustomizeTabWithSnippetVersionControl extends CustomizeTab {
static components = {
...CustomizeTab.components,
OptionsContainer: OptionsContainerWithSnippetVersionControl,
};
}
class BuilderWithSnippetVersionControl extends Builder {
static components = {
...Builder.components,
CustomizeTab: CustomizeTabWithSnippetVersionControl,
};
}
export class MassMailingBuilder extends Component {
static template = "mass_mailing.MassMailingBuilder";
static components = { Builder: BuilderWithSnippetVersionControl };
static props = {
builderProps: { type: Object },
toggleCodeView: { type: Function, optional: true },
toggleFullScreen: { type: Function },
};
get builderProps() {
const builderProps = Object.assign({}, this.props.builderProps);
const pluginsToRemove = [
"BuilderFontPlugin", // Makes call to Google API (can't be used for emails)
"SavePlugin",
"SaveSnippetPlugin",
"AnchorPlugin",
"ColorUIPlugin",
"EmbeddedFilePlugin",
"FilePlugin",
"AddDocumentsAttachmentPlugin",
"BannerPlugin",
"CTABadgeOptionPlugin",
"OperationPlugin",
];
const massMailingPlugins = removePlugins(
[
...registry.category("builder-plugins").getAll(),
...registry.category("mass_mailing-plugins").getAll(),
],
pluginsToRemove
);
const builderEditorPlugins = removePlugins(
[...CORE_PLUGINS, PowerButtonsPlugin],
pluginsToRemove
);
const optionalPlugins = [
...(this.props.builderProps.config.dynamicPlaceholder
? removePlugins(
DYNAMIC_PLACEHOLDER_PLUGINS,
["PromptPlugin"] // mass_mailing does not use the dependency banner plugin
)
: []),
];
builderProps.Plugins = [...builderEditorPlugins, ...massMailingPlugins, ...optionalPlugins];
return builderProps;
}
}
registry.category("lazy_components").add("mass_mailing.MassMailingBuilder", MassMailingBuilder);

View file

@ -0,0 +1,16 @@
<templates>
<t t-name="mass_mailing.MassMailingBuilder">
<Builder t-props="this.builderProps">
<t t-set-slot="extraActions">
<button t-if="props.toggleCodeView" t-on-click="props.toggleCodeView"
class="o-hb-btn btn d-flex align-items-center o_codeview_btn" title="Code View" accesskey="d"><i class="fa fa-code"/></button>
<button t-on-click="props.toggleFullScreen"
class="o-hb-btn btn d-flex align-items-center" title="Fullscreen" accesskey="f">
<span t-attf-class="fa fa-expand"/>
</button>
</t>
</Builder>
</t>
</templates>

View file

@ -0,0 +1,14 @@
<templates>
<t t-name="mass_mailing.AlertOption">
<BuilderRow label.translate="Size">
<BuilderSelect>
<BuilderSelectItem classAction="'s_alert_sm'">Small</BuilderSelectItem>
<BuilderSelectItem classAction="'s_alert_md'">Medium</BuilderSelectItem>
<BuilderSelectItem classAction="'s_alert_lg'">Large</BuilderSelectItem>
</BuilderSelect>
</BuilderRow>
<BuilderRow label.translate="Background Color">
<BuilderColorPicker styleAction="'background-color'" enabledTabs="['solid', 'custom']"/>
</BuilderRow>
</t>
</templates>

View file

@ -0,0 +1,12 @@
<templates>
<t t-name="mass_mailing.BlockAlignmentOption">
<BuilderRow label.translate="Alignment" t-if="!this.isActiveItem('so_width_100')">
<BuilderButtonGroup>
<!-- TODO EGGMAIL: investigate how margins behave in email clients -->
<BuilderButton icon="'fa-align-left'" title.translate="Left" classAction="'me-auto'"/>
<BuilderButton icon="'fa-align-center'" title.translate="Center" classAction="'mx-auto'"/>
<BuilderButton icon="'fa-align-right'" title.translate="Right" classAction="'ms-auto'"/>
</BuilderButtonGroup>
</BuilderRow>
</t>
</templates>

View file

@ -0,0 +1,8 @@
<templates>
<t t-name="mass_mailing.CustomerTestimonialsBlockquote">
<BuilderRow label.translate="Edge Spacing">
<BuilderRange action="'setClassRange'" actionParam="['p-1', 'p-2', 'p-3', 'p-4', 'p-5']" max="4"/>
</BuilderRow>
<t t-call="mass_mailing.BorderOption"/>
</t>
</templates>

View file

@ -0,0 +1,5 @@
<templates>
<t t-name="mass_mailing.BorderOption">
<BorderConfigurator label.translate="Border" withRoundCorner="this.withRoundCorner"/>
</t>
</templates>

View file

@ -0,0 +1,7 @@
<templates xml:space="preserve">
<t t-name="mass_mailing.ColorPickerOption">
<BuilderRow label.translate="Background Color">
<BuilderColorPicker styleAction="'background-color'" noTransparency="true" enabledTabs="['solid', 'custom']"/>
</BuilderRow>
</t>
</templates>

View file

@ -0,0 +1,11 @@
<templates>
<t t-name="mass_mailing.CompanyTeamShapesWidth">
<BuilderRow label.translate="Content Width" applyTo="'div:is(.o_container_small, .container, .container-fluid)'">
<BuilderButtonGroup action="'classAction'">
<BuilderButton actionParam="'o_container_small'"><Img src="'/mass_mailing/static/src/img/snippets_options/content_width_small.svg'" /></BuilderButton>
<BuilderButton actionParam="'container'"><Img src="'/mass_mailing/static/src/img/snippets_options/content_width_normal.svg'" /></BuilderButton>
<BuilderButton actionParam="'container-fluid'"><Img src="'/mass_mailing/static/src/img/snippets_options/content_width_full.svg'" /></BuilderButton>
</BuilderButtonGroup>
</BuilderRow>
</t>
</templates>

View file

@ -0,0 +1,6 @@
<templates>
<t t-name="mass_mailing.CTABadgeOption">
<t t-call="mass_mailing.BlockAlignmentOption"/>
<t t-call="mass_mailing.BorderOption"/>
</t>
</templates>

View file

@ -0,0 +1,12 @@
import { useDomState } from "@html_builder/core/utils";
import { ImageToolOption } from "@html_builder/plugins/image/image_tool_option";
export class MassMailingImageToolOption extends ImageToolOption {
static template = "mass_mailing.ImageToolOption";
setup() {
super.setup();
this.massMailingState = useDomState((editingElement) => ({
isImgFluid: editingElement.classList.contains("img-fluid"),
}));
}
}

View file

@ -0,0 +1,35 @@
<templates>
<t t-name="mass_mailing.ImageAndFaOption">
<t t-call="mass_mailing.BorderOption"/>
<t t-call="mass_mailing.HorizontalPaddingOption"/>
<t t-call="mass_mailing.VerticalPaddingOption"/>
</t>
<t t-name="mass_mailing.ImageToolOption" t-inherit="html_builder.ImageToolOption">
<xpath expr="//ImageShapeOption" position="attributes">
<attribute name="withAnimatedShapes">false</attribute>
</xpath>
<xpath expr="//ImageTransformOption" position="replace"/>
<xpath expr="//BuilderRow[@label.translate=&quot;Size&quot;]" position="attributes">
<attribute name="t-if">massMailingState.isImgFluid</attribute>
</xpath>
</t>
<t t-name="mass_mailing.FontAwesomeOption">
<BuilderRow label.translate="Color">
<BuilderColorPicker styleAction="'color'" enabledTabs="['custom', 'solid']"/>
</BuilderRow>
<BuilderRow label.translate="Background Color">
<BuilderColorPicker styleAction="'background-color'" enabledTabs="['custom', 'solid']"/>
</BuilderRow>
<BuilderRow label.translate="Size">
<BuilderButtonGroup>
<BuilderButton classAction="''" title.translate="Default">1X</BuilderButton>
<BuilderButton classAction="'fa-2x'" title.translate="2X Size">2X</BuilderButton>
<BuilderButton classAction="'fa-3x'" title.translate="3X Size">3X</BuilderButton>
<BuilderButton classAction="'fa-4x'" title.translate="4X Size">4X</BuilderButton>
<BuilderButton classAction="'fa-5x'" title.translate="5X Size">5X</BuilderButton>
</BuilderButtonGroup>
</BuilderRow>
</t>
</templates>

View file

@ -0,0 +1,256 @@
<templates>
<t t-name="mass_mailing.MasonryBlockTemplateOption">
<BuilderRow label.translate="Template">
<BuilderSelect id="'masonry_template_opt'" action="'changeMasonryTemplate'">
<BuilderSelectItem title.translate="Default" actionValue="'default_template'"><img src="/mass_mailing/static/src/img/snippets_options/masonry_template_default.svg"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Default Reversed" actionValue="'reversed_template'"><img src="/mass_mailing/static/src/img/snippets_options/masonry_template_reversed.svg"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Images" actionValue="'images_template'"><img src="/mass_mailing/static/src/img/snippets_options/masonry_template_images.svg"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Image Text Image" actionValue="'image_texts_image_template'"><img src="/mass_mailing/static/src/img/snippets_options/masonry_template_image_texts_image.svg"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Mosaic" actionValue="'mosaic_template'"><img src="/mass_mailing/static/src/img/snippets_options/masonry_template_mosaic.svg"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Text Image Text" actionValue="'texts_image_texts_template'"><img src="/mass_mailing/static/src/img/snippets_options/masonry_template_texts_image_texts.svg"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Alternate Text" actionValue="'alternation_text_template'"><img src="/mass_mailing/static/src/img/snippets_options/masonry_template_alternate_texts.svg"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Alternate Text Image" actionValue="'alternation_text_image_template'"><img src="/mass_mailing/static/src/img/snippets_options/masonry_template_alternate_text_image.svg"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Alternate Image Text" actionValue="'alternation_image_text_template'"><img src="/mass_mailing/static/src/img/snippets_options/masonry_template_alternate_image_text.svg"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Alternate Text Image Text" actionValue="'alternation_text_image_text_template'"><img src="/mass_mailing/static/src/img/snippets_options/masonry_template_alternate_text_image_text.svg"/></BuilderSelectItem>
</BuilderSelect>
</BuilderRow>
</t>
<t t-name="mass_mailing.s_masonry_block_default_template">
<div class="row">
<div class="col-md-6 col-12 oe_img_bg text-center pb224 pt224" data-name="Block" style="background-image: url(/web/image/mass_mailing.s_masonry_block_default_image_1);">
<p><br/></p>
</div>
<div class="col-md-6 col-12 s_col_no_resize o_masonry_grid_container">
<div class="row h-100">
<div class="col-md-6 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-6 col-12 pt24 pb8 text-center o_cc o_cc3" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-6 col-12 pt24 pb8 text-center o_cc o_cc4" data-name="Block">
<h3><font style="color: white">A great title</font></h3>
<p><font style="color: white">And a great subtitle</font></p>
</div>
<div class="col-md-6 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
</div>
</div>
</div>
</t>
<t t-name="mass_mailing.s_masonry_block_reversed_template">
<div class="row">
<div class="col-md-6 col-12 s_col_no_resize o_masonry_grid_container">
<div class="row h-100">
<div class="col-md-6 col-12 pt24 pb8 text-center o_cc o_cc3" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-6 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-6 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-6 col-12 pt24 pb8 text-center o_cc o_cc4" data-name="Block">
<h3><font style="color: white">A great title</font></h3>
<p><font style="color: white">And a great subtitle</font></p>
</div>
</div>
</div>
<div class="col-md-6 col-12 oe_img_bg text-center pb224 pt224" data-name="Block" style="background-image: url(/web/image/mass_mailing.s_masonry_block_default_image_1);">
<p><br/></p>
</div>
</div>
</t>
<t t-name="mass_mailing.s_masonry_block_images_template" >
<div class="row">
<div class="col-md-6 col-12 oe_img_bg text-center pb224 pt224" data-name="Block" style="background-image: url(/web/image/mass_mailing.s_masonry_block_default_image_1);">
<p><br/></p>
</div>
<div class="col-md-6 col-12 oe_img_bg text-center pb224 pt224" data-name="Block" style="background-image: url(/web/image/mass_mailing.s_masonry_block_default_image_2);">
<p><br/></p>
</div>
</div>
</t>
<t t-name="mass_mailing.s_masonry_block_image_texts_image_template">
<div class="row">
<div class="col-md-3 col-12 oe_img_bg text-center pt224 pb224" data-name="Block" style="background-image: url(/web/image/mass_mailing.s_masonry_block_default_image_2);">
<p><br/></p>
</div>
<div class="col-md-3 col-12 s_col_no_resize o_masonry_grid_container">
<div class="row h-100">
<div class="col-md-12 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-12 col-12 pt24 pb8 text-center o_cc o_cc4" data-name="Block">
<h3><font style="color: white">A great title</font></h3>
<p><font style="color: white">And a great subtitle</font></p>
</div>
</div>
</div>
<div class="col-md-6 col-12 oe_img_bg text-center pt224 pb224" data-name="Block" style="background-image: url(/web/image/mass_mailing.s_masonry_block_default_image_1);">
<p><br/></p>
</div>
</div>
</t>
<t t-name="mass_mailing.s_masonry_block_mosaic_template">
<div class="row">
<div class="col-md-6 col-12 s_col_no_resize o_masonry_grid_container">
<div class="row">
<div class="col-md-6 col-12 pt24 pb8 text-center o_cc o_cc3" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-6 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
</div>
<div class="row">
<div class="col-md-12 col-12 oe_img_bg text-center pt224 pb224" data-name="Block"
style="background-image: url(/web/image/mass_mailing.s_masonry_block_default_image_1);">
<p><br/></p>
</div>
</div>
</div>
<div class="col-md-6 col-12 s_col_no_resize o_masonry_grid_container">
<div class="row">
<div class="col-md-12 col-12 oe_img_bg text-center pt224 pb224" data-name="Block"
style="background-image: url(/web/image/mass_mailing.s_masonry_block_default_image_2);">
<p><br/></p>
</div>
</div>
<div class="row">
<div class="col-md-6 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-6 col-12 pt24 pb8 text-center o_cc o_cc4" data-name="Block">
<h3><font style="color: white">A great title</font></h3>
<p><font style="color: white">And a great subtitle</font></p>
</div>
</div>
</div>
</div>
</t>
<t t-name="mass_mailing.s_masonry_block_texts_image_texts_template">
<div class="row">
<div class="col-md-3 col-12 s_col_no_resize o_masonry_grid_container">
<div class="row h-100">
<div class="col-md-12 col-12 pt24 pb8 text-center o_cc o_cc3" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-12 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
</div>
</div>
<div class="col-md-6 col-12 oe_img_bg text-center pt224 pb224" data-name="Block"
style="background-image: url(/web/image/mass_mailing.s_masonry_block_default_image_1);">
<p><br/></p>
</div>
<div class="col-md-3 col-12 s_col_no_resize o_masonry_grid_container">
<div class="row h-100">
<div class="col-md-12 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-12 col-12 pt24 pb8 text-center o_cc o_cc4" data-name="Block">
<h3><font style="color: white">A great title</font></h3>
<p><font style="color: white">And a great subtitle</font></p>
</div>
</div>
</div>
</div>
</t>
<t t-name="mass_mailing.s_masonry_block_alternation_text_template">
<div class="row">
<div class="col-md-3 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-3 col-12 pt24 pb8 text-center o_cc o_cc4" data-name="Block">
<h3><font style="color: white">A great title</font></h3>
<p><font style="color: white">And a great subtitle</font></p>
</div>
<div class="col-md-3 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-3 col-12 pt24 pb8 text-center o_cc o_cc3" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
</div>
</t>
<t t-name="mass_mailing.s_masonry_block_alternation_text_image_template">
<div class="row">
<div class="col-md-3 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-3 col-12 oe_img_bg text-center pt224 pb224" data-name="Block" style="background-image: url(/web/image/mass_mailing.s_masonry_block_default_image_1);">
<p><br/></p>
</div>
<div class="col-md-3 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-3 col-12 oe_img_bg text-center pt224 pb224" data-name="Block" style="background-image: url(/web/image/mass_mailing.s_masonry_block_default_image_2);">
<p><br/></p>
</div>
</div>
</t>
<t t-name="mass_mailing.s_masonry_block_alternation_image_text_template">
<div class="row">
<div class="col-md-3 col-12 oe_img_bg text-center pt224 pb224" data-name="Block" style="background-image: url(/web/image/mass_mailing.s_masonry_block_default_image_1);">
<p><br/></p>
</div>
<div class="col-md-3 col-12 pt24 pb8 text-center o_cc o_cc4" data-name="Block">
<h3><font style="color: white">A great title</font></h3>
<p><font style="color: white">And a great subtitle</font></p>
</div>
<div class="col-md-3 col-12 oe_img_bg text-center pt224 pb224" data-name="Block" style="background-image: url(/web/image/mass_mailing.s_masonry_block_default_image_2);">
<p><br/></p>
</div>
<div class="col-md-3 col-12 pt24 pb8 text-center o_cc o_cc3" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
</div>
</t>
<t t-name="mass_mailing.s_masonry_block_alternation_text_image_text_template">
<div class="row">
<div class="col-md-3 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
<div class="col-md-6 col-12 oe_img_bg text-center pt224 pb224" data-name="Block" style="background-image: url(/web/image/mass_mailing.s_masonry_block_default_image_1);">
<p><br/></p>
</div>
<div class="col-md-3 col-12 pt24 pb8 text-center o_cc" data-name="Block">
<h3>A great title</h3>
<p>And a great subtitle</p>
</div>
</div>
</t>
</templates>

View file

@ -0,0 +1,24 @@
import { OptionsContainer } from "@html_builder/sidebar/option_container";
import { useState } from "@odoo/owl";
export class OptionsContainerWithSnippetVersionControl extends OptionsContainer {
static template = "mass_mailing.OptionsContainer";
setup() {
super.setup();
this.versionState = useState({
isUpToDate: this.env.editor.shared.versionControl.hasAccessToOutdatedEl(
this.props.editingElement
),
});
}
// Version control
replaceElementWithNewVersion() {
this.callOperation(() => {
this.env.editor.shared.versionControl.replaceWithNewVersion(this.props.editingElement);
});
}
accessOutdated() {
this.env.editor.shared.versionControl.giveAccessToOutdatedEl(this.props.editingElement);
this.versionState.isUpToDate = true;
}
}

View file

@ -0,0 +1,11 @@
.options-container {
.o_we_version_control {
background-color: $o-we-color-info;
div.title {
margin-bottom: $o-we-sidebar-content-field-label-spacing;
text-transform: uppercase;
font-weight: bold;
}
}
}

View file

@ -0,0 +1,24 @@
<templates xml:space="preserve">
<t t-name="mass_mailing.OptionsContainer" t-inherit="html_builder.OptionsContainer">
<xpath expr="//div[@t-ref='content']" position="replace">
<t t-if="versionState.isUpToDate">
<div class="we-bg-options-container pb-3" t-ref="content">
<t t-foreach="props.options" t-as="OptionClass" t-key="OptionClass.name + '-' + OptionClass.template">
<BuilderContext applyTo="OptionClass.applyTo" t-if="hasAccess(OptionClass.groups)">
<t t-component="OptionClass"></t>
</BuilderContext>
</t>
</div>
</t>
<t t-else="">
<div class="o_we_version_control d-flex flex-column p-3 pt-4 align-items-center text-center text-white">
<div class="title">This block is outdated.</div>
<div>You might not be able to customize it anymore.</div>
<button type="button" class="btn btn-primary py-2 my-4 border-0" t-on-click="() => this.replaceElementWithNewVersion()">REPLACE BY NEW VERSION</button>
<div>You can still access the block options but it might be ineffective.</div>
<button type="button" class="btn btn-primary py-2 my-4 border-0" t-on-click="() => this.accessOutdated()">ACCESS OPTIONS ANYWAY</button>
</div>
</t>
</xpath>
</t>
</templates>

View file

@ -0,0 +1,14 @@
<templates>
<t t-name="mass_mailing.HorizontalPaddingOption">
<BuilderRow label.translate="Padding ↔">
<BuilderNumberInput title.translate="Left" styleAction="'padding-left'" unit="'px'"/>
<BuilderNumberInput title.translate="Right" styleAction="'padding-right'" unit="'px'"/>
</BuilderRow>
</t>
<t t-name="mass_mailing.VerticalPaddingOption">
<BuilderRow label.translate="Padding ↕">
<BuilderNumberInput title.translate="Top" styleAction="'padding-top'" unit="'px'"/>
<BuilderNumberInput title.translate="Bottom" styleAction="'padding-bottom'" unit="'px'"/>
</BuilderRow>
</t>
</templates>

View file

@ -0,0 +1,14 @@
section[data-filter-domain]:not([data-filter-domain="[]"]) {
position: relative;
& > *:first-child::before {
right: 20px; // See Website for indicator values.
top: 0;
pointer-events: none;
opacity: 50%;
position: absolute;
font-family: "FontAwesome";
content: "\f070";
font-size: xx-large;
color: $o-we-color-accent;
}
}

View file

@ -0,0 +1,79 @@
import { BaseOptionComponent, useDomState } from "@html_builder/core/utils";
import { Domain } from "@web/core/domain";
import { DomainSelectorDialog } from "@web/core/domain_selector_dialog/domain_selector_dialog";
import { useService } from "@web/core/utils/hooks";
/**
* Option Component to enable the user to filter some snippets to a specific subset of ids following
* a domain.
*/
export class SnippetVisibilityOption extends BaseOptionComponent {
static template = "mass_mailing.VisibilityOption";
static selector = "section";
static dependencies = ["mass_mailing.SnippetVisibility"];
setup() {
super.setup();
this.getModel = this.dependencies["mass_mailing.SnippetVisibility"].getModel;
this.treeProcessor = useService("tree_processor");
this.dialog = useService("dialog");
this.historyPlugin = this.env.editor.shared.history;
this.overlayButtonsPlugin = this.env.editor.shared.overlayButtons;
this.state = useDomState((editingElement) => {
const currentDomain = new Domain(
JSON.parse(editingElement.dataset.filterDomain || "[]")
);
this.parseTree(currentDomain);
return {
domain: currentDomain,
};
});
}
get stringifiedDomain() {
return JSON.stringify(this.state.domain.toJson());
}
/**
*
* @param {import("@web/core/tree_editor/condition_tree").Tree} tree
*/
async parseTree(domain) {
const resModel = this.getModel();
const tree = await this.treeProcessor.treeFromDomain(resModel, domain, !this.env.debug);
// Extract subtrees connected by an `&`, Odoo Standard for domain facets
const trees = !tree.negate && tree.value === "&" ? tree.children : [tree];
this.state.facets = await Promise.all(
trees.map((tree) =>
this.treeProcessor.getDomainTreeDescription(resModel, tree, false, 2, 1)
)
);
}
onClickEditDomain() {
this.overlayButtonsPlugin.hideOverlayButtonsUi();
this.dialog.add(
DomainSelectorDialog,
{
resModel: this.getModel(),
domain: this.state.domain.toString(),
isDebugMode: !!this.env.debug,
onConfirm: (domain) => {
const newDomain = new Domain(domain);
this.state.domain = newDomain;
this.env.getEditingElement().dataset.filterDomain = JSON.stringify(
this.state.domain.toJson()
);
this.parseTree(newDomain);
this.config.onChange?.({ isPreviewing: false });
},
},
{
onClose: () => {
this.overlayButtonsPlugin.showOverlayButtonsUi();
},
}
);
}
}

View file

@ -0,0 +1,29 @@
<templates>
<t t-name="mass_mailing.VisibilityOption">
<BuilderRow label.translate="Visibility">
<BuilderSelect action="'dataAttributeChangeAction'" actionParam="'filterDomain'">
<BuilderSelectItem actionValue="''">Always Visible</BuilderSelectItem>
<BuilderSelectItem actionValue="this.stringifiedDomain" id="'show_domain_selector'">Conditionally</BuilderSelectItem>
</BuilderSelect>
</BuilderRow>
<BuilderContext t-if="this.isActiveItem('show_domain_selector')">
<BuilderRow level="1" label.translate="Domain" extraLabelClass="'align-self-end'">
<div t-if="this.state.facets?.length" class="d-flex flex-column">
<div class="d-inline-flex align-items-center pt-1" t-foreach="this.state.facets" t-as="facet" t-key="facet_index">
<span class="fa fa-filter pe-1"/>
<span t-out="facet"/>
</div>
</div>
<button t-else="" class="btn btn-secondary me-auto mt-1" t-on-click="this.onClickEditDomain" >
Edit Conditions
</button>
</BuilderRow>
<!-- Trick to have the content of two rows on the same level -->
<BuilderRow t-if="this.state.facets?.length" label.translate=" ">
<button class="btn btn-secondary me-auto mt-1" t-on-click="this.onClickEditDomain">
Add Conditions
</button>
</BuilderRow>
</BuilderContext>
</t>
</templates>

View file

@ -0,0 +1,37 @@
import { BaseOptionComponent } from "@html_builder/core/utils";
import { BorderConfigurator } from "@html_builder/plugins/border_configurator_option";
import { after, WIDTH } from "@html_builder/utils/option_sequence";
import { Plugin } from "@html_editor/plugin";
import { withSequence } from "@html_editor/utils/resource";
import { registry } from "@web/core/registry";
export class AlertOption extends BaseOptionComponent {
static template = "mass_mailing.AlertOption";
static selector = ".s_mail_alert .s_alert";
}
export class BorderOption extends BaseOptionComponent {
static template = "mass_mailing.BorderOption";
static selector = ".s_mail_alert .s_alert";
static components = { BorderConfigurator };
}
class AlertOptionPlugin extends Plugin {
static id = "mass_mailing.AlertOption";
resources = {
builder_options: [
withSequence(after(WIDTH), AlertOption),
withSequence(after(WIDTH), BorderOption),
],
patch_builder_options: [
{
target_name: "alertTypeOption",
target_element: "exclude",
method: "replace",
value: ".s_mail_alert .s_alert",
},
],
};
}
registry.category("mass_mailing-plugins").add(AlertOptionPlugin.id, AlertOptionPlugin);

View file

@ -0,0 +1,28 @@
import { BackgroundOption } from "@html_builder/plugins/background_option/background_option";
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";
export class MailingBackgroundOption extends BackgroundOption {
static selector =
".s_masonry_block > .container > .row > div:not(:has(.row)), .s_cover > .container > .row > div, .s_reviews_wall";
static props = {
...BackgroundOption.props,
withColors: { type: Boolean, optional: true },
withImages: { type: Boolean, optional: true },
withColorCombinations: { type: Boolean, optional: true },
};
static defaultProps = {
withImages: true,
withColors: false,
withColorCombinations: false,
};
}
class BackgroundOptionPlugin extends Plugin {
static id = "mass_mailing.BackgroundOption";
resources = {
builder_options: MailingBackgroundOption,
};
}
registry.category("mass_mailing-plugins").add(BackgroundOptionPlugin.id, BackgroundOptionPlugin);

View file

@ -0,0 +1,51 @@
import { BaseOptionComponent } from "@html_builder/core/utils";
import { BorderConfigurator } from "@html_builder/plugins/border_configurator_option";
import { before, VERTICAL_ALIGNMENT, WIDTH } from "@html_builder/utils/option_sequence";
import { Plugin } from "@html_editor/plugin";
import { withSequence } from "@html_editor/utils/resource";
import { registry } from "@web/core/registry";
class MassMailingBorderOption extends BaseOptionComponent {
static template = "mass_mailing.BorderOption";
static components = { BorderConfigurator };
withRoundCorner = true;
}
export class BorderOption1 extends MassMailingBorderOption {
static selector =
".s_three_columns .row > div, .s_comparisons .row > div, .s_mail_block_event .row > div";
static applyTo = ".card";
}
export class BorderOption2 extends MassMailingBorderOption {
static selector = ".s_text_block, .o_mail_block_discount2";
}
export class BorderOption3 extends MassMailingBorderOption {
static selector = "table, table td, table tr";
withRoundCorner = false;
}
export class BorderOption4 extends MassMailingBorderOption {
static selector = ".row > div";
static exclude = [
".o_mail_wrapper_td, .s_image_gallery .row > div",
BorderOption1.selector,
BorderOption2.selector,
BorderOption3.selector,
].join(",");
}
export class BorderOptionPlugin extends Plugin {
static id = "mass_mailing.BorderOption";
resources = {
builder_options: [
withSequence(before(WIDTH), BorderOption1),
withSequence(before(WIDTH), BorderOption2),
withSequence(before(WIDTH), BorderOption3),
withSequence(VERTICAL_ALIGNMENT, BorderOption4),
],
};
}
registry.category("mass_mailing-plugins").add(BorderOptionPlugin.id, BorderOptionPlugin);

View file

@ -0,0 +1,14 @@
import { ColorUIPlugin } from "@html_builder/core/color_ui_plugin";
import { registry } from "@web/core/registry";
export class MassMailingColorUIPlugin extends ColorUIPlugin {
getPropsForColorSelector(type) {
const props = { ...super.getPropsForColorSelector(type) };
props.enabledTabs = ["solid", "custom"];
return props;
}
}
registry
.category("mass_mailing-plugins")
.add(MassMailingColorUIPlugin.id, MassMailingColorUIPlugin);

View file

@ -0,0 +1,36 @@
import { BaseOptionComponent } from "@html_builder/core/utils";
import { before, VERTICAL_ALIGNMENT } from "@html_builder/utils/option_sequence";
import { Plugin } from "@html_editor/plugin";
import { withSequence } from "@html_editor/utils/resource";
import { registry } from "@web/core/registry";
export class ColorPickerOption extends BaseOptionComponent {
static template = "mass_mailing.ColorPickerOption";
// This selector targets all direct children of .oe_structure except nested structures
static selector = `.note-editable .oe_structure > div:not(:has(> .o_mail_snippet_general)),
.note-editable .oe_structure > .o_mail_snippet_general,
.note-editable .oe_structure > .o_mail_snippet_general .o_cc,
.s_mail_color_blocks_2 .row > div, table td, .s_cta_badge`;
static exclude = ".o_mail_no_colorpicker, .o_mail_no_options, .s_mail_color_blocks_2";
}
export class ColorPickerOption2 extends BaseOptionComponent {
static template = "mass_mailing.ColorPickerOption";
static selector =
".s_three_columns .row > div, .s_comparisons .row > div, .s_mail_block_event .row > div";
static applyTo = ".card-body, .card-footer";
}
class ColorPickerOptionPlugin extends Plugin {
static id = "mass_mailing.ColorPicker";
colorPickerSelector = ColorPickerOption.selector;
resources = {
builder_options: [
withSequence(before(VERTICAL_ALIGNMENT), ColorPickerOption),
ColorPickerOption2,
],
};
}
registry.category("mass_mailing-plugins").add(ColorPickerOptionPlugin.id, ColorPickerOptionPlugin);

View file

@ -0,0 +1,18 @@
import { BaseOptionComponent } from "@html_builder/core/utils";
import { Plugin } from "@html_editor/plugin";
import { withSequence } from "@html_editor/utils/resource";
import { registry } from "@web/core/registry";
class CompanyTeamShapesWidthOption extends BaseOptionComponent {
static selector = ".s_company_team_shapes";
static template = "mass_mailing.CompanyTeamShapesWidth";
}
export class CompanyTeamOptionPlugin extends Plugin {
static id = "mass_mailing.CompanyTeamOption";
resources = {
builder_options: [withSequence(1, CompanyTeamShapesWidthOption)],
};
}
registry.category("mass_mailing-plugins").add(CompanyTeamOptionPlugin.id, CompanyTeamOptionPlugin);

View file

@ -0,0 +1,20 @@
import { CTABadgeOption } from "@html_builder/plugins/cta_badge_option_plugin";
import { BLOCK_ALIGN } from "@html_builder/utils/option_sequence";
import { Plugin } from "@html_editor/plugin";
import { withSequence } from "@html_editor/utils/resource";
import { registry } from "@web/core/registry";
export class MassMailingCTABadgeOption extends CTABadgeOption {
static selector = ".s_cta_badge";
static template = "mass_mailing.CTABadgeOption";
}
export class CTABadgePlugin extends Plugin {
static id = "mass_mailing.CTABadgePlugin";
resources = {
builder_options: [withSequence(BLOCK_ALIGN, MassMailingCTABadgeOption)],
so_content_addition_selector: [".s_cta_badge"],
};
}
registry.category("mass_mailing-plugins").add(CTABadgePlugin.id, CTABadgePlugin);

View file

@ -0,0 +1,255 @@
import { BuilderAction } from "@html_builder/core/builder_action";
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";
import { memoize } from "@web/core/utils/functions";
import { CUSTOMIZE_MAILING_VARIABLES } from "@mass_mailing/builder/plugins/customize_mailing_variables";
import { CUSTOMIZE_MAILING_VARIABLES_DEFAULTS } from "./customize_mailing_variables";
import { splitSelectorAroundCommasOutsideParentheses } from "@mail/views/web/fields/html_mail_field/convert_inline";
import { getCSSVariableValue } from "@html_editor/utils/formatting";
const RE_SELECTOR_ENDS_WITH_GT_STAR = />\s*\*\s*$/;
export const PRIORITY_STYLES = {
h1: new Set(["font-family"]),
h2: new Set(["font-family"]),
h3: new Set(["font-family"]),
p: new Set(["font-family"]),
hr: new Set(["border-top-width", "border-top-style", "border-top-color"]),
};
export class CustomizeMailingPlugin extends Plugin {
static id = "mass_mailing.CustomizeMailingPlugin";
static dependencies = [];
static shared = ["getVariableValue", "setVariable"];
resources = {
builder_actions: {
CustomizeMailingVariable,
},
clean_for_save_handlers: ({ root }) => this.cleanForSave(root),
snippet_preview_dialog_stylesheets_handlers: ({ iframe }) => {
const styleSheet = this.extractStylesheetForPreview(iframe.contentDocument);
iframe.contentDocument.adoptedStyleSheets.push(styleSheet);
},
};
getRule = memoize((selector) => this._getRule(selector));
setup() {
this.iframeWindow = this.document.defaultView;
// To have priority over some rules from style assets, the `cssPrefix` is intentionally made
// very specific (3 depth level).
this.cssPrefix = ".o_layout .o_mail_wrapper .o_mail_wrapper_td";
this.styleSheet = new this.iframeWindow.CSSStyleSheet();
const styleEl = this.editable.querySelector("#design-element");
if (styleEl) {
this.parseDesignElement(styleEl);
styleEl.remove();
}
this.setupMailingVariables();
this.document.adoptedStyleSheets = [...this.document.adoptedStyleSheets, this.styleSheet];
}
cleanForSave(clone) {
const layoutEl = clone.querySelector(".o_layout");
if (!layoutEl) {
return;
}
const styleEl = this.document.createElement("STYLE");
styleEl.id = "design-element";
const cssTextArray = [];
for (const rule of Array.from(this.styleSheet.cssRules)) {
if (!rule.style.length) {
continue;
}
cssTextArray.push(rule.cssText);
}
styleEl.textContent = cssTextArray.join("\n");
layoutEl.prepend(styleEl);
}
extractStylesheetForPreview(contentDocument) {
const cssRules = this.styleSheet.cssRules;
const newStyleSheet = new contentDocument.defaultView.CSSStyleSheet();
for (const cssRule of cssRules) {
let previewRule = cssRule.cssText.replace(this.cssPrefix, ".o_add_snippets_preview");
if (previewRule.includes("> [data-snippet]")) {
previewRule = previewRule.replace(
"> [data-snippet]",
".o_snippet_preview_wrap [data-snippet]"
);
}
newStyleSheet.insertRule(previewRule);
}
return newStyleSheet;
}
setupMailingVariables() {
const varRule = this.getRule(this.cssPrefix);
for (const variable of Object.keys(CUSTOMIZE_MAILING_VARIABLES)) {
const currentValue = this.getVariableValue(variable);
const defaultValue =
Object.values(CUSTOMIZE_MAILING_VARIABLES_DEFAULTS[variable] ?? {})[0] ?? "";
if (currentValue === "" && defaultValue !== "") {
varRule.style.setProperty(variable, defaultValue);
}
this.refreshMailingVariableSelector(variable);
}
}
refreshMailingVariableSelector(variable) {
const options = CUSTOMIZE_MAILING_VARIABLES[variable];
const currentValue = this.getVariableValue(variable);
let value = "";
if (currentValue !== "") {
value = `var(${variable})`;
}
for (const selector of options.selectors) {
const rule = this.getRule(selector);
for (const property of options.properties) {
const important = PRIORITY_STYLES[selector]?.has(property) ? "important" : "";
rule.style.setProperty(property, value, important);
}
}
}
parseDesignElement(styleEl) {
const rules = [...styleEl.sheet.cssRules];
for (const rule of rules) {
for (const selector of splitSelectorAroundCommasOutsideParentheses(rule.selectorText)) {
for (const property of rule.style) {
const selectors =
property !== "font-family"
? [selector]
: this.transformFontFamilySelector(selector);
for (const selector of selectors) {
this.addCSSRule(selector, rule.style, property);
}
}
}
}
}
addSelectorPrefix(selector) {
if (!selector.trim().startsWith(this.cssPrefix)) {
return `${this.cssPrefix} ${selector}`;
}
return selector;
}
_getRule(selector) {
selector = this.addSelectorPrefix(selector);
for (const rule of this.styleSheet.cssRules) {
if (rule.selectorText === selector) {
return rule;
}
}
return this.styleSheet.cssRules.item(this.styleSheet.insertRule(`${selector} { }`));
}
getVariableValue(variable) {
return this.getRule(this.cssPrefix).style.getPropertyValue(variable);
}
setVariable(variable, value) {
const currentValue = this.getVariableValue(variable);
this.getRule(this.cssPrefix).style.setProperty(variable, value);
if (Boolean(currentValue) !== Boolean(value)) {
this.refreshMailingVariableSelector(variable);
}
}
/**
* Ensure that FontAwesome icons are not impacted by font-family selectors
*/
transformFontFamilySelector(selector) {
if (selector.trim().endsWith(":not(.fa)")) {
return [selector];
}
if (!selector.endsWith("*")) {
return [`${selector.trim()}:not(.fa)`, `${selector.trim()} :not(.fa)`];
} else if (RE_SELECTOR_ENDS_WITH_GT_STAR.test(selector)) {
return [`${selector.replace(RE_SELECTOR_ENDS_WITH_GT_STAR, "").trim()} :not(.fa)`];
}
}
/**
* @param {String} selector
* @param {CSSStyleDeclaration} ruleStyle
* @param {String} property
*/
addCSSRule(selector, ruleStyle, property) {
selector = selector.trim();
const rule = this.getRule(selector);
rule.style.setProperty(
property,
ruleStyle.getPropertyValue(property),
ruleStyle.getPropertyPriority(property)
);
}
}
export class CustomizeMailingVariable extends BuilderAction {
static id = "mass_mailing.CustomizeMailingVariable";
static dependencies = [
"builderActions",
"color",
"mass_mailing.CustomizeMailingPlugin",
"history",
];
isApplied({ value }) {
return this.getValue(...arguments) === value;
}
/**
* @param { Object } params
* @param { String[] } params.selectors
* @param { string } params.property
*/
getValue({ params }) {
const variable = this.dependencies["mass_mailing.CustomizeMailingPlugin"].getVariableValue(
params.variable
);
if (!params.variable.includes("color") || !/var\(/g.test(variable)) {
return variable;
}
const match = variable.match(/var\(--([\w-]+)\)/)[1];
return getCSSVariableValue(
match,
this.window.getComputedStyle(this.document.documentElement)
);
}
apply({ params, value }) {
const oldValue = this.getValue(...arguments);
this.dependencies.history.applyCustomMutation({
apply: () => {
this.dependencies["mass_mailing.CustomizeMailingPlugin"].setVariable(
params.variable,
value
);
},
revert: () => {
this.dependencies["mass_mailing.CustomizeMailingPlugin"].setVariable(
params.variable,
oldValue
);
},
});
}
clean({ params }) {
const oldValue = this.getValue(...arguments);
this.dependencies.history.applyCustomMutation({
apply: () => {
this.dependencies["mass_mailing.CustomizeMailingPlugin"].setVariable(
params.variable,
params.clean ?? ""
);
},
revert: () => {
this.dependencies["mass_mailing.CustomizeMailingPlugin"].setVariable(
params.variable,
oldValue
);
},
});
}
}
registry.category("mass_mailing-plugins").add(CustomizeMailingPlugin.id, CustomizeMailingPlugin);

View file

@ -0,0 +1,281 @@
/**
* reconstruction of a customizable_css_variable:
* --optionName-propertyLikeName (i.e. --button-padding-x, --button-padding-y
*/
import { BASE_CONTAINER_CLASS } from "@html_editor/utils/base_container";
function getProperties(propertyDescription) {
switch (propertyDescription) {
case "padding-y":
return ["padding-top", "padding-bottom"];
case "padding-x":
return ["padding-left", "padding-right"];
default:
return [propertyDescription];
}
}
function generateSimpleMailingVariables(prefix, selectors, properties) {
const variables = {};
for (const propertyDescription of properties) {
variables[`--${prefix}-${propertyDescription}`] = {
properties: getProperties(propertyDescription),
selectors: selectors,
};
}
return variables;
}
// Properties and default values:
/* eslint-disable */
const wrapperProperties = [
"background-color",
];
const textProperties = [
"font-size",
"font-weight",
"font-style",
"font-family",
"text-decoration-line",
"color",
];
const textContainerProperties = [
"margin-bottom",
];
const buttonProperties = [
...textProperties,
"background-color",
"padding-x",
"padding-y",
"border-style",
"border-width",
"border-color",
];
const separatorProperties = [
"border-top-width",
"border-style",
"border-color",
"width",
];
/* eslint-enable */
export const CUSTOMIZE_MAILING_VARIABLES = Object.assign(
generateSimpleMailingVariables("wrapper", ["> [data-snippet]"], wrapperProperties),
(() => {
const variables = {};
for (const depth of [1, 2, 3]) {
const prefix = `h${depth}`;
Object.assign(
variables,
generateSimpleMailingVariables(
prefix,
[prefix],
[...textProperties, ...textContainerProperties]
)
);
}
return variables;
})(),
generateSimpleMailingVariables("text", [`.${BASE_CONTAINER_CLASS}`, "p", "li"], textProperties),
generateSimpleMailingVariables("text-container", ["p", "ul"], textContainerProperties),
generateSimpleMailingVariables(
"link",
["a:not(.btn):not(:has(.fa, img))", "a.btn.btn-link"],
textProperties
),
generateSimpleMailingVariables(
"btn-primary",
["a.btn.btn-fill-primary", "a.btn.btn-outline-primary", "a.btn.btn-primary"],
buttonProperties
),
generateSimpleMailingVariables(
"btn-secondary",
["a.btn.btn-fill-secondary", "a.btn.btn-outline-secondary", "a.btn.btn-secondary"],
buttonProperties
),
generateSimpleMailingVariables("separator", ["hr"], separatorProperties)
);
export const CUSTOMIZE_MAILING_VARIABLES_DEFAULTS = {
"--wrapper-background-color": {
"background-color": "#FFFFFF",
},
"--h1-font-size": {
"font-size": "28px",
},
"--h1-font-weight": {
"font-weight": "500",
},
"--h1-font-style": {
"font-style": "",
},
"--h1-font-family": {
"font-family": "Arial,Helvetica Neue,Helvetica,sans-serif",
},
"--h1-text-decoration-line": {
"text-decoration-line": "",
},
"--h1-color": {
color: "rgb(0, 0, 0)",
},
"--h1-margin-bottom": {
"margin-bottom": "7px",
},
"--h2-font-size": {
"font-size": "23px",
},
"--h2-font-weight": {
"font-weight": "500",
},
"--h2-font-style": {
"font-style": "",
},
"--h2-font-family": {
"font-family": "Arial,Helvetica Neue,Helvetica,sans-serif",
},
"--h2-text-decoration-line": {
"text-decoration-line": "",
},
"--h2-color": {
color: "rgb(0, 0, 0)",
},
"--h2-margin-bottom": {
"margin-bottom": "7px",
},
"--h3-font-size": {
"font-size": "20px",
},
"--h3-font-weight": {
"font-weight": "500",
},
"--h3-font-style": {
"font-style": "",
},
"--h3-font-family": {
"font-family": "Arial,Helvetica Neue,Helvetica,sans-serif",
},
"--h3-text-decoration-line": {
"text-decoration-line": "",
},
"--h3-color": {
color: "rgb(0, 0, 0)",
},
"--h3-margin-bottom": {
"margin-bottom": "7px",
},
"--text-font-size": {
"font-size": "16px",
},
"--text-font-weight": {
"font-weight": "400",
},
"--text-font-style": {
"font-style": "",
},
"--text-font-family": {
"font-family": "Arial,Helvetica Neue,Helvetica,sans-serif",
},
"--text-text-decoration-line": {
"text-decoration-line": "",
},
"--text-color": {
color: "rgb(0, 0, 0)",
},
"--text-container-margin-bottom": {
"margin-bottom": "16px",
},
"--link-font-size": {
"font-size": "16px",
},
"--link-font-weight": {
"font-weight": "400",
},
"--link-font-style": {
"font-style": "",
},
"--link-font-family": {
"font-family": "Arial,Helvetica Neue,Helvetica,sans-serif",
},
"--link-text-decoration-line": {
"text-decoration-line": "",
},
"--link-color": {
color: "rgb(113, 75, 103)",
},
"--btn-primary-font-size": {
"font-size": "12px",
},
"--btn-primary-color": {
color: "rgb(255, 255, 255)",
},
"--btn-primary-background-color": {
"background-color": "rgb(53, 151, 156)",
},
"--btn-primary-padding-x": {
"padding-left": "10px",
"padding-right": "10px",
},
"--btn-primary-padding-y": {
"padding-top": "5px",
"padding-bottom": "5px",
},
"--btn-primary-font-family": {
"font-family": "Arial,Helvetica Neue,Helvetica,sans-serif",
},
"--btn-primary-border-style": {
"border-style": "solid",
},
"--btn-primary-border-width": {
"border-width": "1px",
},
"--btn-primary-border-color": {
"border-color": "rgb(53, 151, 156)",
},
"--btn-secondary-font-size": {
"font-size": "12px",
},
"--btn-secondary-color": {
color: "rgb(255, 255, 255)",
},
"--btn-secondary-background-color": {
"background-color": "rgb(104, 85, 99)",
},
"--btn-secondary-padding-x": {
"padding-left": "10px",
"padding-right": "10px",
},
"--btn-secondary-padding-y": {
"padding-top": "5px",
"padding-bottom": "5px",
},
"--btn-secondary-font-family": {
"font-family": "Arial,Helvetica Neue,Helvetica,sans-serif",
},
"--btn-secondary-border-style": {
"border-style": "solid",
},
"--btn-secondary-border-width": {
"border-width": "1px",
},
"--btn-secondary-border-color": {
"border-color": "rgb(104, 85, 99)",
},
"--separator-border-top-width": {
"border-top-width": "1px",
},
"--separator-border-style": {
"border-style": "solid",
},
"--separator-border-color": {
"border-color": "rgb(33, 37, 41)",
},
"--separator-width": {
width: "100%",
},
};

View file

@ -0,0 +1,91 @@
import { Plugin } from "@html_editor/plugin";
import { withSequence } from "@html_editor/utils/resource";
import { _t } from "@web/core/l10n/translation";
import { registry } from "@web/core/registry";
import { FontFamilyPicker } from "../fontfamily_picker";
import { BaseOptionComponent } from "@html_builder/core/utils";
export const OPTION_POSITIONS = {
BODY: 10,
SETTINGS: 20,
HEADINGS: 30,
PARAGRAPH: 40,
BUTTON: 50,
LINK: 60,
SEPARATORS: 70,
};
class DesignTabPlugin extends Plugin {
static id = "mass_mailing.DesignTab";
static dependencies = ["builderActions"];
resources = {
builder_components: {
FontFamilyPicker,
},
design_options: [
withSequence(
OPTION_POSITIONS.BODY,
this.getDesignOptionBlock("design-body", {
template: "mass_mailing.DesignBodyOption",
title: _t("Body"),
})
),
withSequence(
OPTION_POSITIONS.HEADINGS,
this.getDesignOptionBlock("design-headings", {
template: "mass_mailing.DesignHeadingsOption",
title: _t("Heading"),
})
),
withSequence(
OPTION_POSITIONS.PARAGRAPH,
this.getDesignOptionBlock("design-paragraph", {
template: "mass_mailing.DesignParagraphOption",
title: _t("Paragraph"),
})
),
withSequence(
OPTION_POSITIONS.BUTTON,
this.getDesignOptionBlock("design-button", {
template: "mass_mailing.DesignButtonOption",
title: _t("Button"),
})
),
withSequence(
OPTION_POSITIONS.LINK,
this.getDesignOptionBlock("design-link", {
template: "mass_mailing.DesignLinkOption",
title: _t("Link"),
})
),
withSequence(
OPTION_POSITIONS.SEPARATORS,
this.getDesignOptionBlock("design-separators", {
template: "mass_mailing.DesignSeparatorOption",
title: _t("Separator"),
})
),
],
};
getDesignOptionBlock(id, options) {
const Option = class extends BaseOptionComponent {
static selector = "*";
};
Object.assign(Option, options);
return {
id: id,
element: this.editable,
hasOverlayOptions: false,
headerMiddleButton: false,
isClonable: false,
isRemovable: false,
options: [Option],
optionsContainerTopButtons: [],
snippetModel: {},
};
}
}
registry.category("mass_mailing-plugins").add(DesignTabPlugin.id, DesignTabPlugin);

View file

@ -0,0 +1,65 @@
import { Plugin } from "@html_editor/plugin";
import { isPhrasingContent } from "@html_editor/utils/dom_info";
import { registry } from "@web/core/registry";
class DropzonePlugin extends Plugin {
static id = "mass_mailing.DropzonePlugin";
resources = {
dropzone_selector: [
{
selector:
".s_mail_blockquote, .s_mail_alert, .s_rating, .s_hr, .s_mail_text_highlight",
dropNear:
"p, h1, h2, h3, ul, ol, .row > div > img, .s_mail_blockquote, .s_mail_alert, .s_rating, .s_hr, .s_mail_text_highlight",
dropIn: ".content, nav",
},
{
selector: "blockquote",
dropNear: "section",
dropIn: ".o_mail_wrapper_td",
},
{
// table_column
selector: ".col>td, .col>th",
exclude: this.noOptionsSelector,
dropNear: ".col>td, .col>th",
},
{
// table_column_mv
selector: ".col_mv, td, th",
exclude: this.noOptionsSelector,
dropNear: ".col_mv, td, th",
},
{
// table_row
selector: "tr:has(> .row), tr:has(> .col_mv)",
exclude: this.noOptionsSelector,
dropNear: "tr:has(> .row), tr:has(> .col_mv)",
},
{
// content
selector:
".note-editable > div:not(.o_layout), .note-editable .oe_structure > *, .oe_snippet_body",
exclude: this.noOptionsSelector,
dropNear: "[data-oe-field='body_html']:not(:has(.o_layout)) > *, .oe_structure > *",
dropIn: "[data-oe-field='body_html']:not(:has(.o_layout)), .oe_structure",
},
{
// sizing_x
selector: ".row > div",
exclude: ".o_mail_no_options, .s_col_no_resize.row > div, .s_col_no_resize",
dropNear: ".row:not(.s_col_no_resize) > div",
},
],
// Prevent dropping as phrasingContent siblings (reduces the amount of drop zones for
// HR block).
filter_for_sibling_dropzone_predicates: (el) => isPhrasingContent(el),
};
get noOptionsSelector() {
return ".o_mail_no_options";
}
}
registry.category("mass_mailing-plugins").add(DropzonePlugin.id, DropzonePlugin);

View file

@ -0,0 +1,45 @@
import { Plugin } from "@html_editor/plugin";
import { withSequence } from "@html_editor/utils/resource";
import { registry } from "@web/core/registry";
export class EmptyMailingPlugin extends Plugin {
static id = "EmptyMailing";
static dependencies = [
"baseContainer",
"builderOptions",
"disableSnippets",
"history",
"selection",
];
resources = {
beforeinput_handlers: withSequence(1, this.ensureTextBlock.bind(this)),
};
ensureTextBlock() {
const wrapperTd = this.editable.querySelector(".o_mail_wrapper_td");
if (!wrapperTd) {
return;
}
const { anchorNode } = this.dependencies.selection.getEditableSelection();
if (anchorNode === wrapperTd && !wrapperTd.firstChild) {
const textSnippet = this.config.snippetModel
.getSnippetByName("snippet_structure", "s_text_block")
.content.cloneNode(true);
const baseContainer = this.dependencies.baseContainer.createBaseContainer();
baseContainer.append(this.document.createElement("br"));
const container = textSnippet.querySelector(".container");
container.replaceChildren(baseContainer);
wrapperTd.replaceChildren(textSnippet);
this.dependencies.selection.setSelection({
anchorNode: baseContainer,
anchorOffset: 0,
});
this.dependencies.history.addStep();
this.dependencies.builderOptions.updateContainers(textSnippet);
this.dependencies.disableSnippets.disableUndroppableSnippets();
}
}
}
registry.category("mass_mailing-plugins").add(EmptyMailingPlugin.id, EmptyMailingPlugin);

View file

@ -0,0 +1,35 @@
import { Plugin } from "@html_editor/plugin";
import { isEmptyBlock } from "@html_editor/utils/dom_info";
import { closestElement } from "@html_editor/utils/dom_traversal";
import { registry } from "@web/core/registry";
export class EmptyNotEditableElementsPlugin extends Plugin {
static id = "mass_mailing.EmptyNotEditableElements";
static dependencies = ["selection"];
resources = {
normalize_handlers: this.normalize.bind(this),
};
/**
* @param {HTMLElement} element
*/
normalize(element) {
const potentiallyEmptyElements = element.querySelectorAll(
".o_not_editable [data-oe-zws-empty-inline]"
);
potentiallyEmptyElements.forEach((emptyElement) => {
const emptyNonEditableBlock = closestElement(emptyElement, ".o_not_editable");
if (isEmptyBlock(emptyNonEditableBlock)) {
emptyNonEditableBlock.remove();
}
});
const selection = this.document.getSelection();
if (!this.dependencies.selection.isSelectionInEditable(selection)) {
this.dependencies.selection.resetSelection();
}
}
}
registry
.category("mass_mailing-plugins")
.add(EmptyNotEditableElementsPlugin.id, EmptyNotEditableElementsPlugin);

View file

@ -0,0 +1,32 @@
import { Plugin } from "@html_editor/plugin";
import { wrapInlinesInBlocks } from "@html_editor/utils/dom";
import { registry } from "@web/core/registry";
export class MassMailingIconSnippetOptionPlugin extends Plugin {
static id = "mass_mailing.iconSnippetOption";
static dependencies = ["media"];
resources = {
on_snippet_dropped_handlers: this.onSnippetDropped.bind(this),
};
async onSnippetDropped({ snippetEl }) {
if (!snippetEl.matches("p:has(> .s_icon)")) {
return;
}
let iconInserted = false;
await this.dependencies.media.openMediaDialog({
activeTab: "ICONS",
save: async (selectedIconEl) => {
iconInserted = true;
snippetEl.insertAdjacentElement("afterend", selectedIconEl);
snippetEl.remove();
wrapInlinesInBlocks(selectedIconEl.parentElement);
},
});
return !iconInserted;
}
}
registry
.category("mass_mailing-plugins")
.add(MassMailingIconSnippetOptionPlugin.id, MassMailingIconSnippetOptionPlugin);

View file

@ -0,0 +1,25 @@
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";
class MassMailingImageSnippetOptionPlugin extends Plugin {
static id = "mass_mailing.imageSnippetOption";
static dependencies = ["imageSnippetOption"];
resources = {
on_snippet_dropped_handlers: this.onSnippetDropped.bind(this),
};
async onSnippetDropped({ snippetEl, dragState }) {
if (!snippetEl.matches("p:has(> .s_image)")) {
return;
}
const imageEl = snippetEl.querySelector(".s_image");
return this.dependencies.imageSnippetOption.onSnippetDropped({
snippetEl: imageEl,
dragState,
});
}
}
registry
.category("mass_mailing-plugins")
.add(MassMailingImageSnippetOptionPlugin.id, MassMailingImageSnippetOptionPlugin);

View file

@ -0,0 +1,58 @@
import { BaseOptionComponent } from "@html_builder/core/utils";
import { BorderConfigurator } from "@html_builder/plugins/border_configurator_option";
import {
CropImageAction,
ImageAndFaOption,
} from "@html_builder/plugins/image/image_tool_option_plugin";
import { IMAGE_TOOL } from "@html_builder/utils/option_sequence";
import { Plugin } from "@html_editor/plugin";
import { closestElement } from "@html_editor/utils/dom_traversal";
import { withSequence } from "@html_editor/utils/resource";
import { MassMailingImageToolOption } from "@mass_mailing/builder/options/image_tool_option";
import { registry } from "@web/core/registry";
import { patch } from "@web/core/utils/patch";
export class FontAwesomeOption extends BaseOptionComponent {
static template = "mass_mailing.FontAwesomeOption";
static selector = "span.fa, i.fa";
}
patch(ImageAndFaOption, {
components: { ...ImageAndFaOption.components, BorderConfigurator },
});
class ImageToolOptionPlugin extends Plugin {
static id = "mass_mailing.ImageToolOption";
resources = {
patch_builder_options: [
{
target_name: "imageAndFaOption",
target_element: "template",
method: "replace",
value: "mass_mailing.ImageAndFaOption",
},
{
target_name: "imageAndFaOption",
target_element: "exclude",
method: "remove",
},
{
target_name: "imageToolOption",
target_element: "OptionComponent",
method: "replace",
value: MassMailingImageToolOption,
},
],
builder_options: [withSequence(IMAGE_TOOL, FontAwesomeOption)],
};
}
patch(CropImageAction.prototype, {
setup() {
super.setup();
this.withLoadingEffect =
closestElement(this.editable, ".o_mass_mailing_with_builder") !== null;
},
});
registry.category("mass_mailing-plugins").add(ImageToolOptionPlugin.id, ImageToolOptionPlugin);

View file

@ -0,0 +1,53 @@
import { LayoutColumnOption } from "@html_builder/plugins/layout_column_option";
import { before, WIDTH } from "@html_builder/utils/option_sequence";
import { Plugin } from "@html_editor/plugin";
import { withSequence } from "@html_editor/utils/resource";
import { registry } from "@web/core/registry";
import { isEmptyBlock } from "@html_editor/utils/dom_info";
import { closestElement } from "@html_editor/utils/dom_traversal";
export class MassMailingLayoutColumnOption extends LayoutColumnOption {
static selector = ".o_mail_snippet_general";
static exclude = ".s_reviews_wall, .s_mail_alert";
static applyTo = ":scope > *:has(> .row:not(.s_nb_column_fixed)), * > .s_allow_columns";
}
class MassMailingLayoutColumnPlugin extends Plugin {
static id = "mass_mailing.LayoutColumnPlugin";
resources = {
mark_color_level_selector_params: [{ selector: ".o_mail_snippet_general" }],
builder_options: [withSequence(before(WIDTH), MassMailingLayoutColumnOption)],
normalize_handlers: this.normalize.bind(this),
};
normalize(element) {
const emptyRowCandidates = element.querySelectorAll(".container > .row:not(:has(> *))");
const emptyContainerCandidates = new Set();
const emptySectionCandidates = new Set();
for (const emptyRowCandidate of emptyRowCandidates) {
if (isEmptyBlock(emptyRowCandidate)) {
emptyContainerCandidates.add(emptyRowCandidate.parentElement);
emptyRowCandidate.remove();
}
}
for (const emptyContainerCandidate of emptyContainerCandidates) {
if (isEmptyBlock(emptyContainerCandidate)) {
const section = closestElement(emptyContainerCandidate, "section");
if (section) {
emptySectionCandidates.add(section);
}
emptyContainerCandidate.remove();
}
}
for (const emptySectionCandidate of emptySectionCandidates) {
if (isEmptyBlock(emptySectionCandidate)) {
emptySectionCandidate.remove();
}
}
}
}
registry
.category("mass_mailing-plugins")
.add(MassMailingLayoutColumnPlugin.id, MassMailingLayoutColumnPlugin);

View file

@ -0,0 +1,19 @@
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";
class AlertOptionPlugin extends Plugin {
static id = "mass_mailing.MailBlockquotePlugin";
resources = {
clean_for_save_handlers: this.cleanForSave.bind(this),
};
cleanForSave({ root }) {
for (const quote of root.querySelectorAll("blockquote")) {
quote.dataset.oMailQuoteNode = "1";
quote.dataset.oMailQuote = "1";
}
}
}
registry.category("mass_mailing-plugins").add(AlertOptionPlugin.id, AlertOptionPlugin);

View file

@ -0,0 +1,40 @@
import { BuilderAction } from "@html_builder/core/builder_action";
import { BaseOptionComponent } from "@html_builder/core/utils";
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";
import { renderToElement } from "@web/core/utils/render";
class MasonryBlockTemplateOptionPlugin extends Plugin {
static id = "mass_mailing.MasonryBlock";
resources = {
builder_options: [MasonryBlockTemplateOption],
builder_actions: {
ChangeMasonryTemplate,
},
};
}
class MasonryBlockTemplateOption extends BaseOptionComponent {
static template = "mass_mailing.MasonryBlockTemplateOption";
static selector = ".s_masonry_block";
static groups = ["base.group_user"];
}
class ChangeMasonryTemplate extends BuilderAction {
static id = "changeMasonryTemplate";
apply({ editingElement, value }) {
editingElement.dataset.templateName = value;
const templateName = `mass_mailing.s_masonry_block_${value}`;
const newTemplate = renderToElement(templateName);
newTemplate.dataset.templateName = value;
const target = editingElement.querySelector(".container");
target.replaceChildren(newTemplate);
}
isApplied({ editingElement, value }) {
return editingElement.dataset.templateName === value;
}
}
registry
.category("mass_mailing-plugins")
.add(MasonryBlockTemplateOptionPlugin.id, MasonryBlockTemplateOptionPlugin);

View file

@ -0,0 +1,32 @@
import { Plugin } from "@html_editor/plugin";
import { _t } from "@web/core/l10n/translation";
import { registry } from "@web/core/registry";
export class MassMailingSetupPlugin extends Plugin {
static id = "mass_mailing_setup_plugin";
resources = {
o_editable_selectors: ".o_mail_wrapper_td",
snippet_preview_dialog_bundles: [
"mass_mailing.assets_iframe_style",
"mass_mailing.iframe_add_dialog",
],
clean_for_save_handlers: this.cleanForSave.bind(this),
powerbox_blacklist_selectors: ".o_mail_wrapper_td",
};
setup() {
const wrapperTd = this.editable.querySelector(".o_mail_wrapper_td");
wrapperTd?.classList.add("oe_empty");
wrapperTd?.setAttribute("data-editor-message-default", true);
wrapperTd?.setAttribute("data-editor-message", _t("DRAG BUILDING BLOCKS HERE"));
}
cleanForSave({ root }) {
const wrapperTd = root.querySelector(".o_mail_wrapper_td.oe_empty");
wrapperTd?.classList.remove("oe_empty");
wrapperTd?.removeAttribute("data-editor-message-default");
wrapperTd?.removeAttribute("data-editor-message");
}
}
registry.category("mass_mailing-plugins").add(MassMailingSetupPlugin.id, MassMailingSetupPlugin);

View file

@ -0,0 +1,22 @@
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";
class MovePlugin extends Plugin {
static id = "mass_mailing.MovePlugin";
static dependencies = ["move"];
resources = {
is_movable_selector: [
{
selector: ".o_mail_snippet_general",
direction: "vertical",
},
{
selector: ".row:not(.s_col_no_resize) > div",
direction: "horizontal",
exclude: ".s_showcase .row > div",
},
],
};
}
registry.category("mass_mailing-plugins").add(MovePlugin.id, MovePlugin);

View file

@ -0,0 +1,27 @@
import { OperationPlugin } from "@html_builder/core/operation_plugin";
import { registry } from "@web/core/registry";
export class MassMailingOperationPlugin extends OperationPlugin {
static shared = [...OperationPlugin.shared, "getUnlockedDef"];
/**
* Does not throw if the editor was destroyed before the operation could be
* completed.
* @override
*/
async next() {
return super.next(...arguments).catch((error) => {
if (!this.isDestroyed) {
throw error;
}
});
}
getUnlockedDef() {
return this.operation.mutex.getUnlockedDef();
}
}
registry
.category("mass_mailing-plugins")
.add(MassMailingOperationPlugin.id, MassMailingOperationPlugin);

View file

@ -0,0 +1,32 @@
import { BaseOptionComponent } from "@html_builder/core/utils";
import { after, VERTICAL_ALIGNMENT } from "@html_builder/utils/option_sequence";
import { Plugin } from "@html_editor/plugin";
import { withSequence } from "@html_editor/utils/resource";
import { registry } from "@web/core/registry";
export class HorizontalPaddingOption extends BaseOptionComponent {
static template = "mass_mailing.HorizontalPaddingOption";
static selector =
"[class*='col-md-'], .s_discount2, .s_text_block, .s_media_list, .s_picture, .s_rating, .s_title, .o_mail_block_footer_social, .s_header_logo, .s_header_social";
static exclude = ".s_col_no_resize.row > div, .s_col_no_resize, img";
}
export class VerticalPaddingOption extends BaseOptionComponent {
static template = "mass_mailing.VerticalPaddingOption";
static selector = ".o_mail_block_footer_social, .s_header_logo, .s_header_social";
static exclude = ".s_col_no_resize.row > div, .s_col_no_resize";
}
class PaddingOptionPlugin extends Plugin {
static id = "horizontalPaddingOption";
selector = HorizontalPaddingOption.selector;
resources = {
mark_color_level_selector_params: [{ selector: HorizontalPaddingOption.selector }],
builder_options: [
withSequence(after(VERTICAL_ALIGNMENT), HorizontalPaddingOption),
withSequence(after(VERTICAL_ALIGNMENT), VerticalPaddingOption),
],
};
}
registry.category("mass_mailing-plugins").add(PaddingOptionPlugin.id, PaddingOptionPlugin);

View file

@ -0,0 +1,5 @@
.o_mass_mailing_iframe_wrapper {
[data-oe-local-overlay-id="oe-power-buttons-overlay"] .power_button:not(:hover) {
opacity: 0.5;
}
}

View file

@ -0,0 +1,21 @@
import { BaseAddProductOption } from "@html_builder/plugins/add_product_option";
import { Plugin } from "@html_editor/plugin";
import { withSequence } from "@html_editor/utils/resource";
import { BEGIN } from "@html_builder/utils/option_sequence";
import { registry } from "@web/core/registry";
export class MassMailingAddProductOption extends BaseAddProductOption {
static selector = ".s_pricelist_boxed_section:has(> .container)";
productSelector = ".container";
}
export class PricelistBoxedOptionPlugin extends Plugin {
static id = "mass_mailing.PricelistBoxedOptionPlugin";
resources = {
builder_options: [withSequence(BEGIN, MassMailingAddProductOption)],
};
}
registry
.category("mass_mailing-plugins")
.add(PricelistBoxedOptionPlugin.id, PricelistBoxedOptionPlugin);

View file

@ -0,0 +1,25 @@
import { BaseOptionComponent } from "@html_builder/core/utils";
import { BorderConfigurator } from "@html_builder/plugins/border_configurator_option";
import { LayoutColumnOption } from "@html_builder/plugins/layout_column_option";
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";
export class CustomerTestimonialsBlockquote extends BaseOptionComponent {
static template = "mass_mailing.CustomerTestimonialsBlockquote";
static selector = ".s_reviews_wall .s_mail_blockquote";
static components = { BorderConfigurator };
}
export class MassMailingLayoutColumnOption extends LayoutColumnOption {
static selector = ".s_reviews_wall .container";
static applyTo = ":scope > .row:has(> .s_mail_blockquote), :scope > .row > .s_allow_columns";
}
class ReviewsWallOptionPlugin extends Plugin {
static id = "mass_mailing.ReviewsWallOptionPlugin";
resources = {
builder_options: [CustomerTestimonialsBlockquote, MassMailingLayoutColumnOption],
};
}
registry.category("mass_mailing-plugins").add(ReviewsWallOptionPlugin.id, ReviewsWallOptionPlugin);

View file

@ -0,0 +1,21 @@
import { BaseAddProductOption } from "@html_builder/plugins/add_product_option";
import { Plugin } from "@html_editor/plugin";
import { withSequence } from "@html_editor/utils/resource";
import { BEGIN } from "@html_builder/utils/option_sequence";
import { registry } from "@web/core/registry";
import { _t } from "@web/core/l10n/translation";
export class MassMailingScheduleAddProductOption extends BaseAddProductOption {
static selector = ".s_schedule:has(table)";
productSelector = "tr";
buttonLabel = _t("Add Activity");
}
export class ScheduleOptionPlugin extends Plugin {
static id = "mass_mailing.ScheduleOptionPlugin";
resources = {
builder_options: [withSequence(BEGIN, MassMailingScheduleAddProductOption)],
};
}
registry.category("mass_mailing-plugins").add(ScheduleOptionPlugin.id, ScheduleOptionPlugin);

View file

@ -0,0 +1,41 @@
import { registry } from "@web/core/registry";
import { user } from "@web/core/user";
import { Plugin } from "@html_editor/plugin";
import { SignatureDialog } from "@web/core/signature/signature_dialog";
export class MassMailingSignatureSnippetPlugin extends Plugin {
static id = "mass_mailing.signatureSnippet";
resources = {
on_snippet_dropped_handlers: this.onSnippetDropped.bind(this),
};
async onSnippetDropped({ snippetEl }) {
const images = snippetEl.querySelectorAll(".o_mail_signature_image");
if (!images.length) {
return;
}
this.services.dialog.add(
SignatureDialog,
{
defaultName: user.name,
nameAndSignatureProps: {
displaySignatureRatio: 3,
},
uploadSignature: (signature) => {
for (const image of images) {
image.src = signature.signatureImage;
}
},
},
{
onClose: () => {
snippetEl.remove();
},
}
);
}
}
registry
.category("mass_mailing-plugins")
.add(MassMailingSignatureSnippetPlugin.id, MassMailingSignatureSnippetPlugin);

View file

@ -0,0 +1,52 @@
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";
import { SnippetVisibilityOption } from "../options/snippet_visibility_option";
import { withSequence } from "@html_editor/utils/resource";
import { effect } from "@web/core/utils/reactive";
import { DataAttributeAction } from "@html_builder/core/core_builder_action_plugin";
class DataAttributeChangeAction extends DataAttributeAction {
static id = "dataAttributeChangeAction";
apply(context) {
super.apply(context);
this.config.onChange?.(context);
}
}
class SnippetVisibilityPlugin extends Plugin {
static id = "mass_mailing.SnippetVisibility";
static shared = ["getModel"];
resources = {
builder_actions: { DataAttributeChangeAction },
builder_options: [withSequence(Infinity, SnippetVisibilityOption)],
system_attributes: "data-filter-domain",
};
setup() {
this.mailingModelId = this.config.record.data.mailing_model_id.id;
effect(
(record) => {
if (this.isDestroyed) {
return;
}
if (record.data.mailing_model_id.id !== this.mailingModelId) {
this.mailingModelId = record.data.mailing_model_id.id;
this.resetFilterDomains();
}
},
[this.config.record]
);
}
getModel() {
return this.config.record.data.mailing_model_real;
}
resetFilterDomains() {
const filteredElements = this.editable.querySelectorAll("[data-filter-domain]");
filteredElements.forEach((el) => el.removeAttribute("data-filter-domain"));
this.config.onChange?.({ isPreviewing: false });
}
}
registry.category("mass_mailing-plugins").add(SnippetVisibilityPlugin.id, SnippetVisibilityPlugin);

View file

@ -0,0 +1,41 @@
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";
export class VersionControlPlugin extends Plugin {
static id = "versionControl";
static dependencies = ["builderOptions"];
accessPerOutdatedEl = new WeakMap();
static shared = ["hasAccessToOutdatedEl", "giveAccessToOutdatedEl", "replaceWithNewVersion"];
hasAccessToOutdatedEl(el) {
if (!el.dataset.snippet) {
return true;
}
if (this.accessPerOutdatedEl.has(el)) {
return this.accessPerOutdatedEl.get(el);
}
const snippetKey = el.dataset.snippet;
const snippet = this.config.snippetModel.getOriginalSnippet(snippetKey);
let isUpToDate = true;
if (snippet) {
const { vxml: originalVxml } = snippet.content.dataset;
const { vxml: elVxml } = el.dataset;
isUpToDate = originalVxml === elVxml;
}
this.accessPerOutdatedEl.set(el, isUpToDate);
return isUpToDate;
}
giveAccessToOutdatedEl(el) {
this.accessPerOutdatedEl.set(el, true);
}
replaceWithNewVersion(el) {
const snippetKey = el.dataset.snippet;
const snippet = this.config.snippetModel.getOriginalSnippet(snippetKey);
const cloneEl = snippet.content.cloneNode(true);
el.after(cloneEl);
el.remove();
this.dependencies.builderOptions.setNextTarget(cloneEl);
}
}
registry.category("mass_mailing-plugins").add(VersionControlPlugin.id, VersionControlPlugin);

View file

@ -0,0 +1,20 @@
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";
class VerticalAlignmentOptionPlugin extends Plugin {
static id = "mass_mailing.VerticalAlignmentOption";
resources = {
patch_builder_options: [
{
target_name: "verticalAlignmentOption",
target_element: "selector",
method: "add",
value: ".s_mail_block_event",
},
],
};
}
registry
.category("mass_mailing-plugins")
.add(VerticalAlignmentOptionPlugin.id, VerticalAlignmentOptionPlugin);

View file

@ -0,0 +1,18 @@
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";
class WidthOptionPlugin extends Plugin {
static id = "mass_mailing.WidthOption";
resources = {
patch_builder_options: [
{
target_name: "widthOption",
target_element: "selector",
method: "add",
value: ".s_mail_alert .s_alert, .s_mail_blockquote, .s_mail_text_highlight",
},
],
};
}
registry.category("mass_mailing-plugins").add(WidthOptionPlugin.id, WidthOptionPlugin);

View file

@ -0,0 +1,22 @@
.o_snippets_preview_row {
transform: scale(0.6) !important;
width: 166% !important;
.o_snippet_preview_wrap {
min-height: auto !important;
}
.o_mail_footer_links {
a:not(.btn), a.btn.btn-link {
padding: 0;
}
}
}
.o_snippet_preview_wrap {
[data-snippet] {
.container {
padding: 0;
max-width: 100%;
}
}
}

View file

@ -0,0 +1,19 @@
import { Component, useState } from "@odoo/owl";
import { useOptionsSubEnv } from "@html_builder/utils/utils";
import { OptionsContainer } from "@html_builder/sidebar/option_container";
export class DesignTab extends Component {
static template = "mass_mailing.DesignTab";
static components = { OptionsContainer };
static props = {
colorPresetToShow: { optional: true },
};
setup() {
useOptionsSubEnv(() => [this.env.editor.document.body]);
this.state = useState({
fontsData: {},
});
this.optionsContainers = this.env.editor.resources["design_options"];
}
}

View file

@ -0,0 +1,178 @@
<templates xml:space="preserve">
<t t-name="mass_mailing.DesignTab">
<div class="o_design_tab h-100">
<div t-ref="content" class="d-flex flex-column h-100">
<t t-foreach="optionsContainers" t-as="optionsContainer" t-key="optionsContainer.id">
<!-- TODO EGGMAIL (check theme_tab.xml todo) Define a more basic kind of options container -->
<OptionsContainer
snippetModel="optionsContainer.snippetModel"
editingElement="optionsContainer.element"
options="optionsContainer.options"
containerTitle="optionsContainer.containerTitle"
headerMiddleButtons="optionsContainer.headerMiddleButtons"
isRemovable="optionsContainer.isRemovable"
isClonable="optionsContainer.isClonable"
containerTopButtons="optionsContainer.optionsContainerTopButtons"/>
</t>
</div>
</div>
</t>
<t t-name="mass_mailing.DesignBodyOption">
<BuilderRow label.translate="Body Width">
<BuilderButtonGroup>
<BuilderButton classAction="'o_mail_small'" applyTo="'.o_mail_wrapper'">
<Img src="'/mass_mailing/static/src/img/snippets_options/content_width_small.svg'" />
</BuilderButton>
<BuilderButton classAction="'o_mail_regular'" applyTo="'.o_mail_wrapper'">
<Img src="'/mass_mailing/static/src/img/snippets_options/content_width_normal.svg'" />
</BuilderButton>
<BuilderButton classAction="''" applyTo="'.o_mail_wrapper'">
<Img src="'/mass_mailing/static/src/img/snippets_options/content_width_full.svg'" />
</BuilderButton>
</BuilderButtonGroup>
</BuilderRow>
<BuilderRow label.translate="Mailing Background" extraLabelClass="'pe-2'">
<BuilderColorPicker noTransparency="true"
enabledTabs="['solid', 'custom']"
styleAction="'background-color'"
applyTo="'.o_layout'"
/>
</BuilderRow>
<BuilderRow label.translate="Content Background" extraLabelClass="'pe-2'">
<BuilderColorPicker noTransparency="true"
enabledTabs="['solid', 'custom']"
action="'mass_mailing.CustomizeMailingVariable'"
actionParam="{ variable: '--wrapper-background-color' }"
/>
</BuilderRow>
</t>
<t t-name="mass_mailing.DesignHeadingsOption">
<t t-call="mass_mailing.DesignTextOption">
<t t-set="label">Heading 1</t>
<t t-set="prefix" t-value="`--h1-`"/>
<t t-set="marginPrefix" t-value="prefix"/>
</t>
<t t-call="mass_mailing.DesignTextOption">
<t t-set="label">Heading 2</t>
<t t-set="prefix" t-value="`--h2-`"/>
<t t-set="marginPrefix" t-value="prefix"/>
</t>
<t t-call="mass_mailing.DesignTextOption">
<t t-set="label">Heading 3</t>
<t t-set="prefix" t-value="`--h3-`"/>
<t t-set="marginPrefix" t-value="prefix"/>
</t>
</t>
<t t-name="mass_mailing.DesignParagraphOption">
<t t-call="mass_mailing.DesignTextOption">
<t t-set="label">Text</t>
<t t-set="prefix" t-value="`--text-`"/>
<t t-set="marginPrefix" t-value="`--text-container-`"/>
</t>
</t>
<t t-name="mass_mailing.DesignLinkOption">
<t t-call="mass_mailing.DesignTextOption">
<t t-set="label">Links</t>
<t t-set="prefix" t-value="`--link-`"/>
</t>
</t>
<t t-name="mass_mailing.DesignTextOption">
<BuilderContext action="'mass_mailing.CustomizeMailingVariable'">
<BuilderRow label="label" extraLabelClass="'fw-bolder'">
<BuilderNumberInput actionParam="{ variable: `${prefix}font-size` }" unit="'px'" saveUnit="'px'" default="0"/>
<BuilderColorPicker noTransparency="true" title.translate="Text Color" enabledTabs="['solid', 'custom']"
actionParam="{ variable: `${prefix}color` }"/>
</BuilderRow>
<BuilderRow t-if="marginPrefix" label.translate="Margin" level="1">
<BuilderNumberInput title.translate="Bottom" unit="'px'" saveUnit="'px'" actionParam="{ variable: `${marginPrefix}margin-bottom` }" default="0"/>
</BuilderRow>
<BuilderRow>
<FontFamilyPicker extraClass="'ps-2'" action="'mass_mailing.CustomizeMailingVariable'" actionParam="{variable: `${prefix}font-family`}"/>
<BuilderButton icon="'fa-fw fa-bold'" actionParam="{ variable: `${prefix}font-weight` }" actionValue="'bolder'"/>
<BuilderButton icon="'fa-fw fa-italic'" actionParam="{ variable: `${prefix}font-style` }" actionValue="'italic'"/>
<BuilderButton icon="'fa-fw fa-underline'" actionParam="{ variable: `${prefix}text-decoration-line`}" actionValue="'underline'"/>
</BuilderRow>
</BuilderContext>
</t>
<t t-name="mass_mailing.DesignGenericButtonOption">
<BuilderContext action="'mass_mailing.CustomizeMailingVariable'">
<BuilderRow label="label" extraLabelClass="'fw-bolder'">
<BuilderNumberInput actionParam="{ variable: `${prefix}font-size` }" unit="'px'" saveUnit="'px'" default="0"/>
<BuilderColorPicker noTransparency="true" title.translate="Text Color" enabledTabs="['solid', 'custom']"
actionParam="{ variable: `${prefix}color` }"/>
<BuilderColorPicker noTransparency="true" title.translate="Background Color" enabledTabs="['solid', 'custom']"
actionParam="{ variable: `${prefix}background-color` }"/>
</BuilderRow>
<BuilderRow label.translate="Padding" level="1">
<BuilderNumberInput title.translate="Y" unit="'px'" saveUnit="'px'" actionParam="{ variable: `${prefix}padding-y` }" default="0"/>
<BuilderNumberInput title.translate="X" unit="'px'" saveUnit="'px'" actionParam="{ variable: `${prefix}padding-x` }" default="0"/>
</BuilderRow>
<BuilderRow label.translate="Font Family" level="1">
<FontFamilyPicker action="'mass_mailing.CustomizeMailingVariable'" actionParam="{ variable: `${prefix}font-family`}"/>
<BuilderButton icon="'fa-fw fa-bold'" actionParam="{ variable: `${prefix}font-weight` }" actionValue="'bolder'"/>
<BuilderButton icon="'fa-fw fa-italic'" actionParam="{ variable: `${prefix}font-style` }" actionValue="'italic'"/>
<BuilderButton icon="'fa-fw fa-underline'" actionParam="{ variable: `${prefix}text-decoration-line`}" actionValue="'underline'"/>
</BuilderRow>
<BuilderRow label.translate="Border" level="1">
<BuilderNumberInput actionParam="{ variable: `${prefix}border-width` }" unit="'px'" saveUnit="'px'" min="0"
default="0" composable="true"/>
<BuilderSelect actionParam="{ variable: `${prefix}border-style` }">
<BuilderSelectItem title.translate="Solid" actionValue="'solid'"><div class="o-hb-border-preview" style="border-style: solid;"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Dashed" actionValue="'dashed'"><div class="o-hb-border-preview" style="border-style: dashed;"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Dotted" actionValue="'dotted'"><div class="o-hb-border-preview" style="border-style: dotted;"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Double" actionValue="'double'"><div class="o-hb-border-preview" style="border-style: double;"/></BuilderSelectItem>
</BuilderSelect>
<BuilderColorPicker actionParam="{ variable: `${prefix}border-color` }"
noTransparency="true"
enabledTabs="['solid', 'custom']"
/>
</BuilderRow>
</BuilderContext>
</t>
<t t-name="mass_mailing.DesignButtonOption">
<t t-call="mass_mailing.DesignGenericButtonOption">
<t t-set="prefix" t-value="`--btn-primary-`"/>
<t t-set="label">Primary Button</t>
</t>
<t t-call="mass_mailing.DesignGenericButtonOption">
<t t-set="prefix" t-value="`--btn-secondary-`"/>
<t t-set="label">Secondary Button</t>
</t>
</t>
<t t-name="mass_mailing.DesignSeparatorOption">
<t t-set="prefix" t-value="`--separator-`"/>
<BuilderContext action="'mass_mailing.CustomizeMailingVariable'">
<BuilderRow label.translate="Separators" extraLabelClass="'fw-bolder'">
<BuilderNumberInput actionParam="{ variable: `${prefix}border-top-width` }" unit="'px'" saveUnit="'px'" min="0"
default="0" composable="true"/>
<BuilderSelect actionParam="{ variable: `${prefix}border-style` }">
<BuilderSelectItem title.translate="Solid" actionValue="'solid'"><div class="o-hb-border-preview" style="border-style: solid;"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Dashed" actionValue="'dashed'"><div class="o-hb-border-preview" style="border-style: dashed;"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Dotted" actionValue="'dotted'"><div class="o-hb-border-preview" style="border-style: dotted;"/></BuilderSelectItem>
<BuilderSelectItem title.translate="Double" actionValue="'double'"><div class="o-hb-border-preview" style="border-style: double;"/></BuilderSelectItem>
</BuilderSelect>
<BuilderColorPicker actionParam="{ variable: `${prefix}border-color` }"
noTransparency="true"
enabledTabs="['solid', 'custom']"
/>
</BuilderRow>
<BuilderRow label.translate="Width" level="1">
<BuilderButtonGroup actionParam="{ variable: `${prefix}width` }">
<BuilderButton actionValue="'25%'" title.translate="Resize Quarter">25%</BuilderButton>
<BuilderButton actionValue="'50%'" title.translate="Resize Half">50%</BuilderButton>
<BuilderButton actionValue="'75%'" title.translate="Resize Three Quarters">75%</BuilderButton>
<BuilderButton actionValue="'100%'" title.translate="Resize Full">100%</BuilderButton>
</BuilderButtonGroup>
</BuilderRow>
</BuilderContext>
</t>
</templates>

View file

@ -1,14 +0,0 @@
/* We want to show system's default font in the mail sent with the basic theme.
And so we remove font-family from basic theme while saving. But by doing so
in readonly mode is not getting proper font in odoo. So we added if from here.
*/
#wrapwrap .o_layout.o_basic_theme {
font-family: -apple-system, "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
}
/*
Make sure that the mail body takes all available space
*/
body.o_readonly.o_in_iframe {
margin: 0;
}

View file

@ -1,21 +0,0 @@
.openerp .oe_kanban_email_template {
width: 360px;
height: 340px;
}
.openerp .oe_kanban_email_template .oe_kanban_content{
height: 320px;
overflow: hidden !important;
}
.kanban_html_preview {
pointer-events: none;
width: 600px;
-webkit-transform: scale(.50);
-ms-transform: scale(.50);
transform: scale(.50);
-webkit-transform-origin: 0 0;
-ms-transform-origin: 0 0;
transform-origin: 0 0;
margin: 0;
}

View file

@ -0,0 +1,25 @@
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";
export class MassMailingContenteditablePlugin extends Plugin {
static id = "massMailingContenteditablePlugin";
resources = {
clean_for_save_handlers: this.cleanForSave.bind(this),
};
setup() {
const layoutEditable = this.editable.querySelector(".o_layout .o_mail_no_options");
if (layoutEditable) {
this.editable.setAttribute("contenteditable", "false");
layoutEditable.setAttribute("contenteditable", "true");
}
}
cleanForSave({ root: clone }) {
clone.querySelector(".o_layout .o_mail_no_options")?.removeAttribute("contenteditable");
}
}
registry
.category("basic-editor-plugins")
.add(MassMailingContenteditablePlugin.id, MassMailingContenteditablePlugin);

View file

@ -0,0 +1,469 @@
import { DYNAMIC_PLACEHOLDER_PLUGINS } from "@html_editor/backend/plugin_sets";
import { htmlField, HtmlField } from "@html_editor/fields/html_field";
import { LocalOverlayContainer } from "@html_editor/local_overlay_container";
import { MAIN_PLUGINS as MAIN_EDITOR_PLUGINS } from "@html_editor/plugin_sets";
import { normalizeHTML, parseHTML } from "@html_editor/utils/html";
import { MassMailingIframe } from "@mass_mailing/iframe/mass_mailing_iframe";
import { ThemeSelector } from "@mass_mailing/themes/theme_selector/theme_selector";
import {
onWillUpdateProps,
status,
toRaw,
useEffect,
useExternalListener,
useRef,
} from "@odoo/owl";
import { loadBundle } from "@web/core/assets";
import { Domain } from "@web/core/domain";
import { registry } from "@web/core/registry";
import { Deferred } from "@web/core/utils/concurrency";
import { effect } from "@web/core/utils/reactive";
import { useChildRef, useService } from "@web/core/utils/hooks";
import { batched } from "@web/core/utils/timing";
import { PowerButtonsPlugin } from "@html_editor/main/power_buttons_plugin";
import { useEmailHtmlConverter } from "@mail/convert_inline/hooks";
export class MassMailingHtmlField extends HtmlField {
static template = "mass_mailing.HtmlField";
static components = {
...HtmlField.components,
LocalOverlayContainer,
MassMailingIframe,
ThemeSelector,
};
static props = {
...HtmlField.props,
inlineField: { type: String },
filterTemplates: { type: Boolean, optional: true },
};
setup() {
// Keep track of the next props before other `onWillUpdateProps`
// callbacks in super can be executed, to be able to compute the next
// activeTheme and next themeSelector display status just before the
// Component is patched.
let props = this.props;
onWillUpdateProps((nextProps) => {
if (nextProps !== this.props) {
props = nextProps;
}
});
super.setup();
this.converter = useEmailHtmlConverter({
bundles: ["mass_mailing.assets_iframe_style"],
});
this.themeService = useService("mass_mailing.themes");
this.ui = useService("ui");
Object.assign(this.state, {
showThemeSelector: this.props.record.isNew,
activeTheme: undefined,
});
if (this.state.showThemeSelector) {
// Preemptively load assets for the html Builder because
// there is a high chance that they will be needed from the
// Theme Selector, no need to wait for the user selection.
loadBundle("mass_mailing.assets_builder");
}
this.resetIframe();
this.iframeRef = useChildRef();
this.iframeWrapperRef = useChildRef();
this.codeViewButtonRef = useRef("codeViewButtonRef");
onWillUpdateProps((nextProps) => {
if (
this.props.readonly !== nextProps.readonly &&
(this.props.readonly || nextProps.readonly)
) {
// Force a full reload for MassMailingIframe on readonly change
this.state.key++;
}
if (nextProps.readonly) {
toRaw(this.state).showThemeSelector = false;
}
});
let currentKey = this.state.key;
effect(
batched((state) => {
if (status(this) === "destroyed") {
return;
}
if (state.key !== currentKey) {
// html value may have been reset from the server:
// - await the new iframe
this.resetIframe();
// - ensure that the activeTheme is up to date with the next
// record.
this.updateActiveTheme(props.record);
// - ensure that the themeSelector is displayed if necessary
// for the next props.
this.updateThemeSelector(props);
currentKey = state.key;
}
}),
[this.state]
);
useEffect(
() => {
if (!this.codeViewRef.el) {
return;
}
// Set the initial textArea height.
this.codeViewRef.el.style.height = this.codeViewRef.el.scrollHeight + "px";
},
() => [this.codeViewRef.el]
);
useExternalListener(window, "pointerdown", this.onPointerDown.bind(this));
}
get withBuilder() {
return this.state.activeTheme !== "basic" && !this.props.readonly;
}
resetIframe() {
this.iframeLoaded = new Deferred();
}
async ensureIframeLoaded() {
const iframeLoaded = this.iframeLoaded;
// iframeInfo is deprecated
const iframeInfo = await iframeLoaded;
return iframeLoaded === this.iframeLoaded ? iframeInfo : undefined;
}
onIframeLoad(iframeLoaded) {
this.iframeLoaded.resolve(iframeLoaded);
}
updateActiveTheme(record = this.props.record) {
// This function is called in an `effect` with a dependency on
// `state.key` which already guarantees that the Component will be
// re-rendered. All further reads on the state should not add
// dependencies to that effect, so it is used raw.
const state = toRaw(this.state);
const getThemeName = () => {
const value = record.data[this.props.name];
if (!value || !value.toString()) {
return;
}
const fragment = parseHTML(document, value);
const layout = fragment.querySelector(".o_layout");
if (!layout) {
return "unknown";
}
return this.themeService.getThemeName(layout.classList) || "unknown";
};
const activeTheme = getThemeName();
if (state.activeTheme !== activeTheme) {
state.activeTheme = activeTheme;
}
}
updateThemeSelector(props = this.props) {
// This function is called in an `effect` with a dependency on
// `state.key` which already guarantees that the Component will be
// re-rendered. All further reads on the state should not add
// dependencies to that effect, so it is used raw.
const state = toRaw(this.state);
if (!state.activeTheme && !state.showThemeSelector && !props.readonly) {
// Show the ThemeSelector when the theme is undefined and the content can be
// changed.
state.showThemeSelector = true;
} else if ((state.activeTheme && state.showThemeSelector) || props.readonly) {
state.showThemeSelector = false;
}
if (state.showThemeSelector && state.showCodeView) {
// Never show the CodeView with the ThemeSelector.
state.showCodeView = false;
}
}
getMassMailingIframeProps() {
const props = {
config: this.getConfig(),
iframeRef: this.iframeRef,
iframeWrapperRef: this.iframeWrapperRef,
onFocus: this.onFocus.bind(this),
onBlur: this.onBlur.bind(this), // deprecated
onEditorLoad: this.onEditorLoad.bind(this),
onIframeLoad: this.onIframeLoad.bind(this),
readonly: this.props.readonly,
showThemeSelector: this.state.showThemeSelector,
showCodeView: this.state.showCodeView,
withBuilder: this.withBuilder,
};
if (this.env.debug) {
Object.assign(props, {
toggleCodeView: () => this.toggleCodeView(),
});
}
return props;
}
/**
* Content reinsertion as done in the super method is not properly supported
* by the editor (corrupted state). This override forces the creation of
* a new editor instead, and all plugins will be instantiated from scratch.
* @override
*/
async toggleCodeView() {
await this.commitChanges();
this.state.showCodeView = !this.state.showCodeView;
this.state.key++;
}
/**
* @override
*/
getConfig() {
if (this.props.readonly) {
return this.getReadonlyConfig();
} else if (this.withBuilder) {
return this.getBuilderConfig();
} else {
return this.getSimpleEditorConfig();
}
}
/**
* @override
*/
getReadonlyConfig() {
const config = super.getReadonlyConfig();
config.value =
config.value && config.value.toString()
? config.value
: this.props.record.data[this.props.inlineField];
return config;
}
getBuilderConfig() {
const config = super.getConfig();
// All plugins for the html Builder are defined in MassMailingBuilder
delete config.Plugins;
return {
...config,
allowChecklist: false,
record: this.props.record,
mobileBreakpoint: "md",
defaultImageMimetype: "image/png",
onEditorReady: () => this.commitChanges(),
};
}
getSimpleEditorConfig() {
const config = super.getConfig();
const codeViewCommand = [config.resources?.user_commands]
.filter(Boolean)
.flat()
.find((cmd) => cmd.id === "codeview");
if (codeViewCommand) {
codeViewCommand.isAvailable = () => this.env.debug;
}
return {
...config,
onEditorReady: () => this.commitChanges(),
Plugins: [
...MAIN_EDITOR_PLUGINS,
...DYNAMIC_PLACEHOLDER_PLUGINS,
...registry.category("basic-editor-plugins").getAll(),
PowerButtonsPlugin,
].filter((P) => !["banner", "prompt"].includes(P.id)),
};
}
getThemeSelectorConfig() {
return {
setThemeHTML: (html) =>
this.mutex.exec(() =>
// The inlineField can not be updated to its final value at
// this point since the editor is needed to process the
// theme template. (i.e. applying the default style).
// It will be updated onEditorReady since it has become empty.
this.props.record
.update({
[this.props.name]: html,
[this.props.inlineField]: "",
})
.catch(() => {})
),
filterTemplates: this.props.filterTemplates,
mailingModelId: this.props.record.data.mailing_model_id.id,
mailingModelName: this.props.record.data.mailing_model_id.display_name || "",
};
}
onChange() {
// Ensure that a change in the edited field will reset the validity
// of the inlineField (since it is most likely invisible and not
// editable directly by the user).
this.props.record.resetFieldValidity(this.props.inlineField);
super.onChange();
}
onFocus() {
this.activeElement = this.iframeWrapperRef.el;
}
/**
* Simulate a tuned down "blur", based around the edition area, comprised
* of the edition iframe and the builder, to avoid committing changes when
* the user is actively interacting inside that zone. Also avoid cases
* where the user clicks inside an overlay or other element inside the
* main component container, because the builder uses a lot of these.
*/
onPointerDown(ev) {
const isTargetOutsideActiveElement =
this.activeElement && !this.activeElement.contains(ev.target);
const ignoredTargetContainer =
isTargetOutsideActiveElement &&
ev.target?.closest(".o-main-components-container, .o_form_status_indicator_buttons");
const shouldIgnoreTarget =
ignoredTargetContainer && !ignoredTargetContainer.contains(this.activeElement);
if (isTargetOutsideActiveElement && !shouldIgnoreTarget) {
this.activeElement = undefined;
this.onBlur();
} else if (this.iframeWrapperRef.el.contains(ev.target)) {
this.activeElement = this.iframeWrapperRef.el;
}
}
onTextareaInput(ev) {
this.onChange();
ev.target.style.height = ev.target.scrollHeight + "px";
}
/**
* Ensure that the emailHtmlConverter is kept alive (in the DOM) until the
* change has been committed to the record (even if this component is
* destroyed in the meantime).
* @override
*/
async commitChanges({ urgent } = {}) {
if (!urgent) {
await this.mutex.exec(() => {
if (this.withBuilder && this.editor && !this.editor.isDestroyed) {
return this.editor.shared.operation.getUnlockedDef();
}
});
}
return super.commitChanges(...arguments);
}
/**
* Ensure that the inlineField has its first value set (in case a template
* was just applied or if the field value was set manually without using
* this widget.
* @override
*/
async _commitChanges({ urgent }) {
if (
this.editor &&
!this.editor.isDestroyed &&
this.props.record.data[this.props.inlineField].toString() === ""
) {
if ((await this.ensureIframeLoaded()) && this.editor && !this.editor.isDestroyed) {
this.isDirty = true;
this.lastValue = undefined;
} else {
return;
}
}
if (!this.state.showCodeView && this.editor?.isDestroyed) {
return;
}
return super._commitChanges({ urgent });
}
/**
* Complete rewrite of `updateValue` to ensure that both the field and the
* inlineField keep consistent values. Depends on the iframe to compute
* the style of the inlineField.
* @override
*/
async updateValue(value) {
const record = this.props.record;
// Ensure the edited value is updated immediately to avoid data loss,
// and reset the inline field (need async computation) to avoid
// transient state where inline data is obsolete.
// If the following computation is aborted, at least it can be
// recovered by reloading the field.
const urgentUpdatePromise = record
.update({
[this.props.name]: value,
[this.props.inlineField]: "",
})
.then(() => {
record.model.bus.trigger("FIELD_IS_DIRTY", false);
});
this.lastValue = normalizeHTML(value, this.clearElementToCompare.bind(this));
const valueFragment = parseHTML(document, value);
let inlineValue;
try {
inlineValue = await this.converter.convertToEmailHtml(valueFragment, {
preProcessCallbacks: [this.preprocessFilterDomains.bind(this)],
});
} catch (error) {
if (status(this) !== "destroyed") {
throw error;
}
inlineValue = null;
}
await urgentUpdatePromise;
if (record.resId !== this.props.record?.resId || inlineValue === null) {
return;
}
this.isDirty = false;
await record
.update({ [this.props.inlineField]: inlineValue })
.catch(() => (this.isDirty = true));
record.model.bus.trigger("FIELD_IS_DIRTY", this.isDirty);
}
/**
* Processes the data-filter-domain to be converted to a t-if that will be interpreted on send
* by QWeb.
* TODO EGGMAIL: move in a convert_inline plugin when they are implemented.
* @param {HTMLElement} htmlEl
*/
preprocessFilterDomains(htmlEl) {
htmlEl.querySelectorAll("[data-filter-domain]").forEach((el) => {
let domain;
try {
domain = new Domain(JSON.parse(el.dataset.filterDomain));
} catch {
el.setAttribute("t-if", "false");
return;
}
el.setAttribute("t-if", `object.filtered_domain(${domain.toString()})`);
});
}
}
export const massMailingHtmlField = {
...htmlField,
component: MassMailingHtmlField,
extractProps({ attrs, options }) {
const props = htmlField.extractProps(...arguments);
props.editorConfig.allowChecklist = false;
props.editorConfig.allowVideo = false;
props.editorConfig.baseContainers = ["P"];
Object.assign(props, {
filterTemplates: options.filterTemplates,
inlineField: options["inline_field"],
migrateHTML: false,
embeddedComponents: false,
isCollaborative: false,
sandboxedPreview: false,
codeview: true,
});
return props;
},
// Deprecated (to be defined in the view)
fieldDependencies: [{ name: "body_html", type: "html", readonly: "false" }],
};
registry.category("fields").add("mass_mailing_html", massMailingHtmlField);

View file

@ -0,0 +1,17 @@
.o_field_mass_mailing_html {
textarea.o_codeview {
font-family: 'Courier New', Courier, monospace;
width: 100%;
outline: none;
resize: none;
right: auto;
height: 100%;
border: none;
overflow: hidden;
}
.o_mass_mailing_code_view {
position: sticky;
top: 50px;
height: fit-content;
}
}

View file

@ -0,0 +1,20 @@
<templates>
<t t-name="mass_mailing.HtmlField">
<t t-if="state.showThemeSelector">
<ThemeSelector config="this.getThemeSelectorConfig()"/>
</t>
<t t-if="state.showCodeView">
<div class="d-flex">
<textarea name="codeView" t-ref="codeView" class="o_codeview" t-att-value="this.value"
t-on-input="onTextareaInput"/>
<div t-if="state.showCodeView" t-ref="codeViewButtonRef"
class="btn-group o_mass_mailing_code_view">
<button class="o_codeview_btn btn btn-primary" t-on-click="toggleCodeView" accesskey="d">
<i class="fa fa-code" />
</button>
</div>
</div>
</t>
<MassMailingIframe t-key="state.key" t-props="this.getMassMailingIframeProps()"/>
</t>
</templates>

View file

@ -0,0 +1,408 @@
import {
Component,
onMounted,
onWillDestroy,
status,
useComponent,
useEffect,
useRef,
useState,
useSubEnv,
} from "@odoo/owl";
import { LazyComponent, loadBundle } from "@web/core/assets";
import { Deferred } from "@web/core/utils/concurrency";
import { uniqueId } from "@web/core/utils/functions";
import { useChildRef, useForwardRefToParent } from "@web/core/utils/hooks";
import { renderToFragment } from "@web/core/utils/render";
import { LocalOverlayContainer } from "@html_editor/local_overlay_container";
import { Editor } from "@html_editor/editor";
import { useThrottleForAnimation } from "@web/core/utils/timing";
import { closestScrollableY } from "@web/core/utils/scrolling";
import { _t } from "@web/core/l10n/translation";
import { localization } from "@web/core/l10n/localization";
import { isBrowserSafari } from "@web/core/browser/feature_detection";
import { loadIframe } from "@mail/convert_inline/iframe_utils";
const IFRAME_VALUE_SELECTOR = ".o_mass_mailing_value";
/**
* The MassMailingIframe will use this modified overlay service that will guarantee:
* 1. Internal ordering of its different overlays
* 2. To not mess up with owl's reconciliation of foreach when adding/removing overlays
* This is a sub-optimal fix to the more general issue of owl displacing nodes that contain
* an iframe, in which the iframe effectively unloads.
*/
export function useOverlayServiceOffset() {
const comp = useComponent();
const originalOverlay = comp.env.services.overlay;
const subServices = Object.create(comp.env.services);
subServices.overlay = Object.create(originalOverlay);
subServices.overlay.add = (C, props, opts = {}) => {
opts = {
...opts,
sequence: (opts.sequence ?? 50) + 1000,
};
return originalOverlay.add(C, props, opts);
};
useSubEnv({ services: subServices });
}
export class MassMailingIframe extends Component {
static template = "mass_mailing.MassMailingIframe";
static components = {
LazyComponent,
LocalOverlayContainer,
};
static props = {
config: { type: Object },
iframeRef: { type: Function },
iframeWrapperRef: { type: Function },
showThemeSelector: { type: Boolean, optional: true },
onIframeLoad: { type: Function, optional: true },
showCodeView: { type: Boolean, optional: true },
toggleCodeView: { type: Function, optional: true },
readonly: { type: Boolean, optional: true },
onEditorLoad: { type: Function, optional: true },
onBlur: { type: Function, optional: true }, // deprecated
onFocus: { type: Function, optional: true },
extraClass: { type: String, optional: true },
withBuilder: { type: Boolean, optional: true },
};
static defaultProps = {
onEditorLoad: () => {},
onFocus: () => {},
};
setup() {
useOverlayServiceOffset();
this.overlayRef = useChildRef();
this.iframeRef = useForwardRefToParent("iframeRef");
this.iframeWrapperRef = useForwardRefToParent("iframeWrapperRef");
this.sidebarRef = useRef("sidebarRef");
this.isRTL = localization.direction === "rtl";
useSubEnv({
localOverlayContainerKey: uniqueId("mass_mailing_iframe"),
});
this.state = useState({
showFullscreen: false,
isMobile: false,
ready: false,
});
this.iframeLoaded = new Deferred();
onMounted(() => {
this.setupIframe();
});
if (!this.props.readonly && !this.props.withBuilder) {
this.editor = new Editor(this.props.config, this.env.services);
this.props.onEditorLoad(this.editor);
onWillDestroy(() => {
this.editor.destroy(true);
});
this.setupBasicEditor();
}
const iframeResize = () => {
const iframe = this.iframeRef.el;
if (this.state.isMobile) {
// aspect-ratio of internal screen of /html_builder/static/img/phone.svg
iframe.style.height = "668px";
iframe.style.width = "367px";
return;
}
iframe.style.width = "";
if (this.state.showFullscreen) {
iframe.style.height = "100%";
} else {
const height = Math.trunc(
iframe.contentDocument.body
.querySelector(IFRAME_VALUE_SELECTOR)
.getBoundingClientRect().height
);
iframe.style.height = height + "px";
}
};
const sidebarResize = () => {
const sidebar = this.sidebarRef.el;
const iframe = this.iframeRef.el;
if (!sidebar) {
return;
}
if (this.state.showFullscreen) {
sidebar.style.top = "0";
sidebar.style.height = "100%";
} else if (this.env.inDialog) {
const scrollableY = closestScrollableY(sidebar);
if (scrollableY) {
const rect = scrollableY.getBoundingClientRect();
sidebar.style.height = `${rect.height}px`;
sidebar.style.top = "0";
}
} else {
const scrollableY = closestScrollableY(sidebar);
let stickyHeight = 0;
let stickyZindex = 0;
if (scrollableY) {
const statusBar = scrollableY.querySelector(".o_form_statusbar");
if (statusBar) {
const statusBarStyle = getComputedStyle(statusBar);
if (statusBarStyle.position === "sticky") {
stickyHeight += statusBar.getBoundingClientRect().height;
}
stickyZindex = parseInt(statusBarStyle.zIndex) || 0;
}
}
const top = scrollableY
? `${
-1 * (parseInt(getComputedStyle(scrollableY).paddingTop) || 0) +
stickyHeight
}px`
: `${stickyHeight}px`;
const maxHeight = this.state.isMobile
? 1000
: iframe.getBoundingClientRect().height;
const offsetHeight =
window.innerHeight -
stickyHeight -
document.querySelector(".o_content").getBoundingClientRect().y;
sidebar.style.height = `${Math.min(maxHeight, offsetHeight)}px`;
sidebar.style.top = top;
if (stickyZindex > 0) {
sidebar.style.zIndex = `${stickyZindex - 1}`;
}
}
};
this.throttledResize = useThrottleForAnimation(() => {
if (status(this) === "destroyed") {
return;
}
iframeResize();
sidebarResize();
});
useEffect(
() => {
this.iframeLoaded.then(() => {
if (status(this) === "destroyed") {
return;
}
this.iframeRef.el.contentDocument.body.classList[
this.state.showFullscreen ? "add" : "remove"
]("o_mass_mailing_iframe_fullscreen");
this.throttledResize();
this.editor?.shared.builderOverlay?.refreshOverlays();
});
},
() => [this.state.showFullscreen]
);
useEffect(
() => {
this.iframeLoaded.then(() => {
if (status(this) === "destroyed") {
return;
}
this.iframeRef.el.contentDocument.body.classList[
this.state.isMobile ? "add" : "remove"
]("o_mass_mailing_iframe_mobile");
this.throttledResize();
this.editor?.shared.builderOverlay?.refreshOverlays();
});
},
() => [this.state.isMobile]
);
}
get isBrowserSafari() {
return isBrowserSafari();
}
getIframeBundles({ readonly, withBuilder } = this.props) {
if (readonly) {
return ["mass_mailing.assets_iframe_style"];
} else if (withBuilder) {
return ["mass_mailing.assets_inside_builder_iframe"];
}
return ["mass_mailing.assets_inside_basic_editor_iframe"];
}
async setupIframe() {
let loadingError;
try {
this.bundleControls = await loadIframe(this.iframeRef.el, (iframe) => {
iframe.contentDocument?.head.appendChild(this.renderHeadContent());
return this.loadIframeAssets();
});
} catch (error) {
loadingError = error;
}
if (status(this) === "destroyed") {
return;
} else if (loadingError) {
throw loadingError;
}
const htmlResizeObserver = new ResizeObserver(this.throttledResize);
this.iframeRef.el.contentDocument.body.classList.add("o_in_iframe");
if (this.props.withBuilder) {
this.iframeRef.el.contentDocument.body.classList.add("o_mass_mailing_with_builder");
} else {
this.iframeRef.el.contentDocument.body.classList.add("bg-white");
}
this.iframeRef.el.contentDocument.body.appendChild(this.renderBodyContent());
htmlResizeObserver.observe(
this.iframeRef.el.contentDocument.body.querySelector(IFRAME_VALUE_SELECTOR)
);
if (this.props.readonly) {
this.retargetLinks(
this.iframeRef.el.contentDocument.body.querySelector(IFRAME_VALUE_SELECTOR)
);
this.fixInlineDynamicPlaceholders(this.iframeRef.el);
}
// Set `ready` symbol for tours
this.iframeRef.el.setAttribute("is-ready", "true");
this.iframeRef.el.contentWindow.addEventListener("beforeUnload", () => {
this.iframeRef.el.removeAttribute("is-ready");
});
this.iframeRef.el.contentWindow.addEventListener("focus", this.props.onFocus.bind(this));
this.iframeLoaded.resolve({
iframe: this.iframeRef.el,
// TODO EGGMAIL: deprecated bundleControls
bundleControls: this.bundleControls,
});
this.props.onIframeLoad?.(this.iframeLoaded);
this.state.ready = true;
}
/**
* As no plugins are loaded in readonly mode, we manually set inlining attributes to
* any t-element that might be present in the document, provided its children are inline
* (which should always be the case for mass_mailing).
* TODO: move this to a readonly plugin once they are implemented
* @param {HTMLElement} iframe
*/
fixInlineDynamicPlaceholders(iframe) {
const checkAllInline = function (el) {
return [...el.children].every((child) => {
if (child.tagName === "T") {
return this.checkAllInline(child);
} else {
return (
child.nodeType !== Node.ELEMENT_NODE ||
iframe.contentWindow.getComputedStyle(child).display === "inline"
);
}
});
};
for (const el of iframe.contentDocument.body.querySelectorAll("t")) {
if (checkAllInline(el)) {
el.setAttribute("data-oe-t-inline", "true");
}
}
}
async setupBasicEditor() {
await this.iframeLoaded;
if (status(this) === "destroyed") {
return;
}
this.editor.config.localOverlayContainers = {
key: this.env.localOverlayContainerKey,
ref: this.overlayRef,
};
this.editor.attachTo(
this.iframeRef.el.contentDocument.body.querySelector(IFRAME_VALUE_SELECTOR)
);
}
/**
* @returns {Object} bundleControls { bundleName: activatorObject }
* TODO EGGMAIL: bundleControls are deprecated (unused)
*/
async loadIframeAssets() {
const bundleEntryPromises = this.getIframeBundles().map(async (bundle) => {
const targets = (
await loadBundle(bundle, {
targetDoc: this.iframeRef.el.contentDocument,
css: true,
js: false,
})
).map((bundleEvent) => bundleEvent.target);
const iframe = this.iframeRef.el;
return [
bundle,
{
toggle(enable = false) {
if (!iframe?.isConnected) {
return;
}
for (const target of targets) {
if (enable && !iframe.contentDocument.head.contains(target)) {
iframe.contentDocument.head.appendChild(target);
} else if (!enable && iframe.contentDocument.head.contains(target)) {
target.remove();
}
}
},
},
];
});
return Object.fromEntries(await Promise.all(bundleEntryPromises));
}
/**
* @deprecated
*/
onBlur(ev) {
if (!this.props.readonly) {
this.props.onBlur(ev);
}
}
renderHeadContent() {
return renderToFragment("mass_mailing.IframeHead", this);
}
renderBodyContent() {
return renderToFragment("mass_mailing.IframeBody", this);
}
getBuilderProps() {
return {
overlayRef: this.overlayRef,
// TODO EGGMAIL: iframeInfo is deprecated (should resolve to iframe directly)
iframeLoaded: this.iframeLoaded.then((iframeInfo) => iframeInfo.iframe),
snippetsName: "mass_mailing.email_designer_snippets",
config: this.props.config,
isMobile: this.state.isMobile,
toggleMobile: () => {
this.iframeRef.el.contentDocument.body.scrollTop = 0;
this.state.isMobile = !this.state.isMobile;
},
editableSelector: IFRAME_VALUE_SELECTOR,
onEditorLoad: (editor) => {
if (this.editor) {
this.editor.destroy();
}
this.editor = editor;
this.props.onEditorLoad(editor);
},
getThemeTab: () =>
odoo.loader.modules.get("@mass_mailing/builder/tabs/design_tab").DesignTab,
themeTabDisplayName: _t("Design"),
};
}
/**
* Ensure all links are opened in a new tab.
*/
retargetLinks(container) {
for (const link of container.querySelectorAll("a")) {
this.retargetLink(link);
}
}
retargetLink(link) {
link.setAttribute("target", "_blank");
link.setAttribute("rel", "noreferrer");
}
toggleFullScreen() {
this.state.showFullscreen = !this.state.showFullscreen;
}
}

View file

@ -0,0 +1,40 @@
.o_mass_mailing_iframe_wrapper {
&.o_mass_mailing_fullscreen {
display: block !important;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 100vw !important;
height: 100vh !important;
overflow: hidden !important;
transform: none !important;
z-index: ($zindex-fixed + $zindex-modal-backdrop) / 2;
background-color: $o-view-background-color;
.o_is_mobile {
margin: auto;
}
}
.o_is_mobile {
background-image: url("/html_builder/static/img/phone.svg");
width: fit-content;
margin-left: auto;
margin-right: auto;
padding-bottom: 30px;
padding-top: 60px;
border-radius: 2rem;
// Width and height of phone.svg. Needed for the builder to recompute values
// when switching to mobile preview, otherwise the width is 0 for a moment.
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15),
16px 12px 32px rgba(0, 0, 0, 0.15),
64px 0 64px rgba(0, 0, 0, 0.15);
iframe {
min-height: 0;
}
}
.o-snippets-menu {
.nav {
background-color: inherit;
padding: 0;
}
}
}

View file

@ -0,0 +1,58 @@
<templates>
<t t-name="mass_mailing.MassMailingIframe">
<div class="o_mass_mailing_iframe_wrapper"
t-ref="iframeWrapperRef"
t-att-class="{
'o_mass_mailing_fullscreen': state.showFullscreen,
[props.extraClass]: props.extraClass,
}">
<div class="d-flex w-100 h-100">
<div class="flex-grow-1" t-att-class="{'align-self-center': this.state.isMobile}">
<LocalOverlayContainer localOverlay="overlayRef" identifier="env.localOverlayContainerKey"/>
<div t-att-class="{ 'o_is_mobile': this.state.isMobile, 'h-100': !this.state.isMobile }">
<iframe t-att-sandbox="this.isBrowserSafari ? 'allow-same-origin allow-scripts' : 'allow-same-origin'"
t-att-scrolling="this.state.isMobile ? '' : 'no'"
t-att-class="{ 'd-none': props.showThemeSelector or props.showCodeView }"
t-ref="iframeRef"/>
</div>
</div>
<div t-if="!props.readonly and props.withBuilder and !props.showThemeSelector and !props.showCodeView">
<div class="position-sticky o_mass_mailing-builder_sidebar border-start border-dark o_builder_sidebar_open"
t-att-class="{ 'd-none': this.env.isSmall }" t-ref="sidebarRef">
<LazyComponent t-if="state.ready" Component="'mass_mailing.MassMailingBuilder'"
props="() => ({
builderProps: this.getBuilderProps(),
toggleCodeView: this.props.toggleCodeView,
toggleFullScreen: () => this.toggleFullScreen(),
})"
bundle="'mass_mailing.assets_builder'"/>
</div>
</div>
</div>
</div>
</t>
<t t-name="mass_mailing.IframeHead">
<meta http-equiv="Content-Security-Policy" content="script-src 'none';"/>
<meta charset="utf-8"/>
<!-- Deprecated, useless element -->
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
</t>
<t t-name="mass_mailing.IframeBody">
<div class="o_mass_mailing_value"
t-att-class="{ 'o_readonly': props.readonly, 'note-editable': !props.readonly, 'o_rtl': isRTL }">
<t t-if="props.readonly">
<t t-out="props.config.value"/>
</t>
</div>
<!-- Deprecated, unused element -->
<div class="o_mass_mailing_processing_container" style="
position: absolute;
top: -9999px;
left: -9999px;
visibility: hidden;
pointer-events: none;
min-width: 100%;
" aria-hidden="true"/>
</t>
</templates>

View file

@ -0,0 +1,74 @@
html:has(.o_layout, .o_basic_theme) {
&:has(body:not(.o_mass_mailing_iframe_fullscreen)) {
height: auto !important;
}
body:not(.o_mass_mailing_iframe_fullscreen, .o_mass_mailing_iframe_mobile) {
height: auto !important;
.note-editable {
overflow: visible;
height: auto;
.o_layout {
min-height: 0 !important;
}
}
}
body {
&.o_mass_mailing_iframe_fullscreen, &.o_mass_mailing_iframe_mobile {
.note-editable {
overflow: auto;
height: 100%;
}
}
&.o_mass_mailing_iframe_fullscreen {
.o_layout {
display: grid;
align-items: center;
}
.o_layout > .container {
padding-bottom: 2%;
}
}
&.o_mass_mailing_with_builder {
background-color: transparent;
}
.note-editable {
padding: 0;
border: none;
}
.o_mass_mailing_value ~ .o_loading_screen {
display: none !important;
}
}
.container {
padding-left: 0;
padding-right: 0;
}
}
html:has(.o_layout) {
.editor_enable .o_mail_wrapper_td.oe_empty:empty {
&:not(:focus) {
&:before {
content: attr(data-editor-message);
pointer-events: none;
color: white;
}
background-color: rgba(1, 186, 210, 0.5) !important;
}
&:focus {
color: black;
}
text-align: center;
font-size: 20px;
display: block;
width: 96%;
padding: 12px 0;
margin: 20px 2%;
border-radius: 0.375rem;
outline: 2px dashed #01bad2;
outline-offset: -2px;
}
}

View file

@ -0,0 +1,26 @@
.o_layout .o_mail_wrapper {
hr {
// override necessary because bootstrap opacity is 0.25 by default
// depending on the modules installed.
opacity: 1;
}
.s_badge {
--badge-color: var(--color);
background: var(--badge-bg, var(--background-color)) !important;
color: var(--badge-color, var(--color)) !important;
border: $border-width solid var(--badge-border-color) !important;
@each $-color, $-value in $theme-colors {
&.text-bg-#{$-color} {
--badge-bg: #{tint-color($-value, 90%)};
--badge-color: #{increase-contrast($-value, tint-color($-value, 90%))};
--badge-color-hover: #{color-contrast($-value, $min-contrast-ratio: 3)};
--badge-border-color: #{$-value};
}
}
* {
color: unset !important;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View file

@ -0,0 +1,36 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="82" height="60" viewBox="0 0 82 60">
<defs>
<linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%">
<stop offset="0%" stop-color="#00A09D"/>
<stop offset="100%" stop-color="#00E2FF"/>
</linearGradient>
<rect id="path-2" width="12" height="2" x="10" y="3"/>
<filter id="filter-3" width="108.3%" height="200%" x="-4.2%" y="-25%" filterUnits="objectBoundingBox">
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1"/>
<feComposite in="shadowOffsetOuter1" in2="SourceAlpha" operator="out" result="shadowOffsetOuter1"/>
<feColorMatrix in="shadowOffsetOuter1" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.4 0"/>
</filter>
<circle id="path-4" cx="4" cy="4" r="2"/>
<filter id="filter-5" width="125%" height="150%" x="-12.5%" y="-12.5%" filterUnits="objectBoundingBox">
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1"/>
<feComposite in="shadowOffsetOuter1" in2="SourceAlpha" operator="out" result="shadowOffsetOuter1"/>
<feColorMatrix in="shadowOffsetOuter1" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.4 0"/>
</filter>
</defs>
<g fill="none" fill-rule="evenodd" class="snippets_thumbs">
<g class="s_badge">
<rect width="82" height="60" class="bg"/>
<g class="group_2" transform="translate(28 26)">
<rect width="27" height="8" fill="url(#linearGradient-1)" class="rectangle" opacity=".4" rx="1"/>
<g class="rectangle">
<use fill="#000" filter="url(#filter-3)" xlink:href="#path-2"/>
<use fill="#FFF" fill-opacity=".95" xlink:href="#path-2"/>
</g>
<g class="oval">
<use fill="#000" filter="url(#filter-5)" xlink:href="#path-4"/>
<use fill="#FFF" fill-opacity=".95" xlink:href="#path-4"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -0,0 +1,48 @@
<svg width="82" height="60" viewBox="0 0 82 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_i_312_63)">
<path d="M53.0004 32.5002C53.0061 32.8294 52.9442 33.1563 52.8187 33.4608C52.6931 33.7652 52.5065 34.0407 52.2704 34.2702C52.0409 34.5063 51.7654 34.6929 51.461 34.8185C51.1565 34.944 50.8296 35.0059 50.5004 35.0002C50.1711 35.0059 49.8442 34.944 49.5398 34.8185C49.2353 34.6929 48.9599 34.5063 48.7304 34.2702C48.4942 34.0407 48.3076 33.7652 48.182 33.4608C48.0565 33.1563 47.9947 32.8294 48.0004 32.5002C48.0004 31.8062 48.2434 31.2152 48.7304 30.7302C48.9599 30.494 49.2353 30.3074 49.5398 30.1819C49.8442 30.0563 50.1711 29.9945 50.5004 30.0002C50.8296 29.9945 51.1565 30.0563 51.461 30.1819C51.7654 30.3074 52.0409 30.494 52.2704 30.7302C52.5065 30.9597 52.6931 31.2351 52.8187 31.5396C52.9442 31.844 53.0061 32.1709 53.0004 32.5002ZM58.9984 34.1532C59.0085 34.2608 58.9951 34.3693 58.959 34.4712C58.9229 34.5731 58.865 34.6659 58.7894 34.7432C58.7189 34.8269 58.6304 34.8935 58.5304 34.938C58.4305 34.9825 58.3217 35.0038 58.2124 35.0002H56.5554C56.3597 35.0036 56.1703 34.9308 56.0274 34.7972C55.882 34.6659 55.794 34.4827 55.7824 34.2872C55.6024 32.4142 54.8474 30.8122 53.5174 29.4822C52.1874 28.1522 50.5864 27.3972 48.7124 27.2172C48.5167 27.2053 48.3335 27.1169 48.2024 26.9712C48.0691 26.828 47.9967 26.6387 48.0004 26.4432V24.7862C48.0004 24.5482 48.0864 24.3562 48.2584 24.2092C48.3274 24.1401 48.4099 24.0859 48.5007 24.05C48.5915 24.0141 48.6887 23.9971 48.7864 24.0002H48.8464C50.1564 24.1062 51.4084 24.4362 52.6034 24.9882C53.7884 25.534 54.8653 26.2891 55.7824 27.2172C56.7101 28.1347 57.4648 29.2119 58.0104 30.3972C58.5597 31.5807 58.8942 32.8525 58.9984 34.1532ZM64.9984 34.1912C65.0074 34.2961 64.9925 34.4017 64.955 34.5C64.9174 34.5984 64.858 34.687 64.7814 34.7592C64.712 34.8377 64.6263 34.8999 64.5302 34.9416C64.4341 34.9832 64.33 35.0032 64.2254 35.0002H62.5004C62.3005 35.0038 62.1073 34.9279 61.9634 34.7892C61.8916 34.7239 61.8337 34.6448 61.7931 34.5567C61.7526 34.4686 61.7302 34.3731 61.7274 34.2762C61.6366 32.5694 61.2226 30.8954 60.5074 29.3432C59.7924 27.7862 58.8604 26.4332 57.7134 25.2872C56.5664 24.1402 55.2144 23.2072 53.6574 22.4912C52.1048 21.7761 50.4319 21.3586 48.7254 21.2602C48.6285 21.2574 48.5331 21.2352 48.445 21.1949C48.3568 21.1545 48.2777 21.0968 48.2124 21.0252C48.1444 20.9557 48.0907 20.8734 48.0545 20.7832C48.0183 20.6929 48.0002 20.5964 48.0014 20.4992V18.7732C48.0014 18.5472 48.0814 18.3632 48.2424 18.2172C48.3115 18.1466 48.3944 18.0909 48.4859 18.0535C48.5774 18.0162 48.6756 17.9981 48.7744 18.0002H48.8104C50.9012 18.1006 52.9546 18.5921 54.8644 19.4492C56.7817 20.3037 58.5233 21.5076 60.0004 22.9992C61.492 24.4765 62.6959 26.2185 63.5504 28.1362C64.4071 30.0463 64.8982 32.1001 64.9984 34.1912Z" fill="black"/>
</g>
<path d="M53.0004 32.5002C53.0061 32.8294 52.9442 33.1563 52.8187 33.4608C52.6931 33.7652 52.5065 34.0407 52.2704 34.2702C52.0409 34.5063 51.7654 34.6929 51.461 34.8185C51.1565 34.944 50.8296 35.0059 50.5004 35.0002C50.1711 35.0059 49.8442 34.944 49.5398 34.8185C49.2353 34.6929 48.9599 34.5063 48.7304 34.2702C48.4942 34.0407 48.3076 33.7652 48.182 33.4608C48.0565 33.1563 47.9947 32.8294 48.0004 32.5002C48.0004 31.8062 48.2434 31.2152 48.7304 30.7302C48.9599 30.494 49.2353 30.3074 49.5398 30.1819C49.8442 30.0563 50.1711 29.9945 50.5004 30.0002C50.8296 29.9945 51.1565 30.0563 51.461 30.1819C51.7654 30.3074 52.0409 30.494 52.2704 30.7302C52.5065 30.9597 52.6931 31.2351 52.8187 31.5396C52.9442 31.844 53.0061 32.1709 53.0004 32.5002ZM58.9984 34.1532C59.0085 34.2608 58.9951 34.3693 58.959 34.4712C58.9229 34.5731 58.865 34.6659 58.7894 34.7432C58.7189 34.8269 58.6304 34.8935 58.5304 34.938C58.4305 34.9825 58.3217 35.0038 58.2124 35.0002H56.5554C56.3597 35.0036 56.1703 34.9308 56.0274 34.7972C55.882 34.6659 55.794 34.4827 55.7824 34.2872C55.6024 32.4142 54.8474 30.8122 53.5174 29.4822C52.1874 28.1522 50.5864 27.3972 48.7124 27.2172C48.5167 27.2053 48.3335 27.1169 48.2024 26.9712C48.0691 26.828 47.9967 26.6387 48.0004 26.4432V24.7862C48.0004 24.5482 48.0864 24.3562 48.2584 24.2092C48.3274 24.1401 48.4099 24.0859 48.5007 24.05C48.5915 24.0141 48.6887 23.9971 48.7864 24.0002H48.8464C50.1564 24.1062 51.4084 24.4362 52.6034 24.9882C53.7884 25.534 54.8653 26.2891 55.7824 27.2172C56.7101 28.1347 57.4648 29.2119 58.0104 30.3972C58.5597 31.5807 58.8942 32.8525 58.9984 34.1532ZM64.9984 34.1912C65.0074 34.2961 64.9925 34.4017 64.955 34.5C64.9174 34.5984 64.858 34.687 64.7814 34.7592C64.712 34.8377 64.6263 34.8999 64.5302 34.9416C64.4341 34.9832 64.33 35.0032 64.2254 35.0002H62.5004C62.3005 35.0038 62.1073 34.9279 61.9634 34.7892C61.8916 34.7239 61.8337 34.6448 61.7931 34.5567C61.7526 34.4686 61.7302 34.3731 61.7274 34.2762C61.6366 32.5694 61.2226 30.8954 60.5074 29.3432C59.7924 27.7862 58.8604 26.4332 57.7134 25.2872C56.5664 24.1402 55.2144 23.2072 53.6574 22.4912C52.1048 21.7761 50.4319 21.3586 48.7254 21.2602C48.6285 21.2574 48.5331 21.2352 48.445 21.1949C48.3568 21.1545 48.2777 21.0968 48.2124 21.0252C48.1444 20.9557 48.0907 20.8734 48.0545 20.7832C48.0183 20.6929 48.0002 20.5964 48.0014 20.4992V18.7732C48.0014 18.5472 48.0814 18.3632 48.2424 18.2172C48.3115 18.1466 48.3944 18.0909 48.4859 18.0535C48.5774 18.0162 48.6756 17.9981 48.7744 18.0002H48.8104C50.9012 18.1006 52.9546 18.5921 54.8644 19.4492C56.7817 20.3037 58.5233 21.5076 60.0004 22.9992C61.492 24.4765 62.6959 26.2185 63.5504 28.1362C64.4071 30.0463 64.8982 32.1001 64.9984 34.1912Z" fill="white" fill-opacity="0.95"/>
<path d="M34 18H19V30H34V18Z" fill="white"/>
<path d="M33.7101 18.2793H19.2871V29.7213H33.7101V18.2793Z" fill="#79D1F2"/>
<mask id="mask0_312_63" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="19" y="18" width="15" height="12">
<path d="M33.7101 18.2793H19.2871V29.7213H33.7101V18.2793Z" fill="white"/>
</mask>
<g mask="url(#mask0_312_63)">
<path d="M30.3935 23.3032C31.5881 23.3032 32.5565 22.3661 32.5565 21.2102C32.5565 20.0543 31.5881 19.1172 30.3935 19.1172C29.1989 19.1172 28.2305 20.0543 28.2305 21.2102C28.2305 22.3661 29.1989 23.3032 30.3935 23.3032Z" fill="#F3EC60"/>
</g>
<mask id="mask1_312_63" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="19" y="18" width="15" height="12">
<path d="M33.7101 18.2793H19.2871V29.7213H33.7101V18.2793Z" fill="white"/>
</mask>
<g mask="url(#mask1_312_63)">
<path d="M33.8532 35.0224C37.5972 35.0224 40.6322 33.1483 40.6322 30.8364C40.6322 28.5245 37.5972 26.6504 33.8532 26.6504C30.1093 26.6504 27.0742 28.5245 27.0742 30.8364C27.0742 33.1483 30.1093 35.0224 33.8532 35.0224Z" fill="url(#paint0_linear_312_63)"/>
</g>
<mask id="mask2_312_63" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="19" y="18" width="15" height="12">
<path d="M33.7101 18.2793H19.2871V29.7213H33.7101V18.2793Z" fill="white"/>
</mask>
<g mask="url(#mask2_312_63)">
<path d="M19.4303 37.5359C25.4043 37.5359 30.2473 34.5998 30.2473 30.9779C30.2473 27.356 25.4043 24.4199 19.4303 24.4199C13.4562 24.4199 8.61328 27.356 8.61328 30.9779C8.61328 34.5998 13.4562 37.5359 19.4303 37.5359Z" fill="url(#paint1_linear_312_63)"/>
</g>
<path fill-rule="evenodd" clip-rule="evenodd" d="M34 18V30H19V18H34ZM33 19H20V29H33V19Z" fill="white"/>
<path d="M34 33V35H19V33H34Z" fill="white" fill-opacity="0.78"/>
<defs>
<filter id="filter0_i_312_63" x="48" y="18" width="17" height="18" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="2"/>
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.4 0"/>
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_312_63"/>
</filter>
<linearGradient id="paint0_linear_312_63" x1="1015.11" y1="415.404" x2="650.22" y2="188.081" gradientUnits="userSpaceOnUse">
<stop stop-color="#008374"/>
<stop offset="1" stop-color="#006A59"/>
</linearGradient>
<linearGradient id="paint1_linear_312_63" x1="1923.59" y1="539.171" x2="1182.52" y2="880.45" gradientUnits="userSpaceOnUse">
<stop stop-color="#00AA89"/>
<stop offset="1" stop-color="#009989"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 8.2 KiB

View file

@ -0,0 +1,31 @@
<svg xmlns="http://www.w3.org/2000/svg" width="82" height="60" fill="none">
<path fill="#1C1C1C" stroke="#fff" d="M63 24H18v13h45V24Z" opacity=".703"/>
<g filter="url(#a)">
<path fill="#000" d="M65.22 39.566c.15.145.183.312.1.5-.081.194-.224.29-.427.29h-2.771l1.458 3.454a.47.47 0 0 1-.247.61l-1.284.544a.47.47 0 0 1-.61-.247l-1.385-3.28-2.263 2.264a.447.447 0 0 1-.5.102c-.194-.082-.291-.225-.291-.428v-10.91c0-.204.097-.347.29-.43a.45.45 0 0 1 .5.103l7.43 7.428Z"/>
</g>
<path fill="#fff" d="M65.22 39.566c.15.145.183.312.1.5-.081.194-.224.29-.427.29h-2.771l1.458 3.454a.47.47 0 0 1-.247.61l-1.284.544a.47.47 0 0 1-.61-.247l-1.385-3.28-2.263 2.264a.447.447 0 0 1-.5.102c-.194-.082-.291-.225-.291-.428v-10.91c0-.204.097-.347.29-.43a.45.45 0 0 1 .5.103l7.43 7.428Z"/>
<g filter="url(#b)">
<path fill="#000" d="M53 28H29v5h24v-5Z"/>
</g>
<path fill="#fff" fill-opacity=".95" d="M53 28H29v5h24v-5Z"/>
<defs>
<filter id="a" width="8.364" height="13.999" x="57" y="32" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="1"/>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
<feBlend in2="BackgroundImageFix" result="effect1_dropShadow_6_2"/>
<feBlend in="SourceGraphic" in2="effect1_dropShadow_6_2" result="shape"/>
</filter>
<filter id="b" width="24" height="6" x="29" y="28" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="1"/>
<feGaussianBlur stdDeviation="2"/>
<feComposite in2="hardAlpha" k2="-1" k3="1" operator="arithmetic"/>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.4 0"/>
<feBlend in2="shape" result="effect1_innerShadow_6_2"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -0,0 +1,46 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="82" height="60" viewBox="0 0 82 60">
<defs>
<linearGradient id="linearGradient-1" x1="50%" x2="50%" y1="0%" y2="100%">
<stop offset="0%" stop-color="#00A09D"/>
<stop offset="100%" stop-color="#00E2FF"/>
</linearGradient>
<linearGradient id="linearGradient-2" x1="50%" x2="50%" y1="0%" y2="100%">
<stop offset="0%" stop-color="#00A09D"/>
<stop offset="100%" stop-color="#00E2FF"/>
</linearGradient>
<linearGradient id="linearGradient-3" x1="50%" x2="50%" y1="0%" y2="100%">
<stop offset="0%" stop-color="#00A09D"/>
<stop offset="100%" stop-color="#00E2FF"/>
</linearGradient>
<linearGradient id="linearGradient-4" x1="50%" x2="50%" y1="0%" y2="100%">
<stop offset="0%" stop-color="#00A09D"/>
<stop offset="100%" stop-color="#00E2FF"/>
</linearGradient>
<linearGradient id="linearGradient-5" x1="50%" x2="50%" y1="0%" y2="100%">
<stop offset="0%" stop-color="#00A09D"/>
<stop offset="100%" stop-color="#00E2FF"/>
</linearGradient>
<rect id="path-6" width="22" height="2" x="0" y="0"/>
<filter id="filter-7" width="104.5%" height="200%" x="-2.3%" y="-25%" filterUnits="objectBoundingBox">
<feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1"/>
<feComposite in="shadowOffsetOuter1" in2="SourceAlpha" operator="out" result="shadowOffsetOuter1"/>
<feColorMatrix in="shadowOffsetOuter1" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.4 0"/>
</filter>
</defs>
<g fill="none" fill-rule="evenodd" class="snippets_thumbs">
<g class="s_chart">
<rect width="82" height="60" class="bg"/>
<g class="group_2" transform="translate(22 22)">
<rect width="6" height="12" y="5" fill="url(#linearGradient-1)" class="rectangle" rx="1"/>
<rect width="6" height="7" x="8" y="10" fill="url(#linearGradient-2)" class="rectangle" rx="1"/>
<rect width="6" height="9" x="16" y="8" fill="url(#linearGradient-3)" class="rectangle" rx="1"/>
<rect width="6" height="4" x="25" y="13" fill="url(#linearGradient-4)" class="rectangle" rx="1"/>
<rect width="6" height="13" x="33" y="4" fill="url(#linearGradient-5)" class="rectangle" rx="1"/>
<g class="rectangle">
<use fill="#000" filter="url(#filter-7)" xlink:href="#path-6"/>
<use fill="#FFF" fill-opacity=".95" xlink:href="#path-6"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -0,0 +1,16 @@
<svg width="82" height="60" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#a)">
<path d="M56.887 24H25.405a6.559 6.559 0 0 0 0 13.118h31.482a6.559 6.559 0 0 0 0-13.118Z" fill="url(#b)"/>
<path d="M58.25 29.25v1.5H34.188v-1.5H58.25ZM60.22 41.566c.15.145.183.312.1.5-.081.194-.224.29-.427.29h-2.771l1.458 3.454a.47.47 0 0 1-.247.61l-1.284.544a.47.47 0 0 1-.61-.247l-1.385-3.28-2.263 2.264a.447.447 0 0 1-.5.102c-.194-.082-.291-.225-.291-.428v-10.91c0-.204.097-.347.29-.43a.45.45 0 0 1 .5.103l7.43 7.428Z" fill="#fff"/>
<path d="M25.5 34a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Z" fill="#fff" fill-opacity=".95"/>
</g>
<defs>
<linearGradient id="b" x1="18.846" y1="29.991" x2="60.203" y2="42.153" gradientUnits="userSpaceOnUse">
<stop stop-color="#00A09D"/>
<stop offset="1" stop-color="#00C0D9"/>
</linearGradient>
<clipPath id="a">
<path fill="#fff" d="M0 0h82v60H0z"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 965 B

View file

@ -0,0 +1,3 @@
<svg width="82" height="60" viewBox="0 0 82 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30.3377 29.4669L35.6689 19.8708L41 29.4669H30.3377ZM35.6689 40.1292C34.496 40.1292 33.492 39.7115 32.6568 38.8763C31.8216 38.0411 31.404 37.0371 31.404 35.8642C31.404 34.6914 31.8216 33.6874 32.6568 32.8522C33.492 32.0169 34.496 31.5993 35.6689 31.5993C36.8417 31.5993 37.8457 32.0169 38.681 32.8522C39.5162 33.6874 39.9338 34.6914 39.9338 35.8642C39.9338 37.0371 39.5162 38.0411 38.681 38.8763C37.8457 39.7115 36.8417 40.1292 35.6689 40.1292ZM42.0662 40.1292V31.5993H50.596V40.1292H42.0662ZM46.3311 29.4669C45.3182 28.6139 44.4697 27.8942 43.7855 27.3078C43.1014 26.7214 42.5549 26.206 42.1462 25.7618C41.7375 25.3175 41.4443 24.8999 41.2666 24.5089C41.0889 24.118 41 23.7004 41 23.2561C41 22.4564 41.2799 21.7812 41.8397 21.2303C42.3994 20.6794 43.0969 20.404 43.9321 20.404C44.4119 20.404 44.8606 20.515 45.2782 20.7372C45.6958 20.9593 46.0468 21.2658 46.3311 21.6568C46.6155 21.2658 46.9664 20.9593 47.384 20.7372C47.8016 20.515 48.2503 20.404 48.7301 20.404C49.5654 20.404 50.2628 20.6794 50.8226 21.2303C51.3824 21.7812 51.6623 22.4564 51.6623 23.2561C51.6623 23.7004 51.5734 24.118 51.3957 24.5089C51.218 24.8999 50.9248 25.3175 50.5161 25.7618C50.1074 26.206 49.5609 26.7214 48.8767 27.3078C48.1926 27.8942 47.344 28.6139 46.3311 29.4669Z" fill="#D9D9D9"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,44 @@
<svg xmlns="http://www.w3.org/2000/svg" width="82" height="60" fill="none">
<g clip-path="url(#a)" opacity=".5">
<path fill="#79D1F2" d="M82 0H0v60h82V0Z"/>
<mask id="b" width="82" height="60" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:luminance">
<path fill="#F3EC60" d="M82 0H0v60h82V0Z"/>
</mask>
<g mask="url(#b)">
<path fill="#F3EC60" d="M65.5 19a7.5 7.5 0 1 0 0-15 7.5 7.5 0 0 0 0 15Z"/>
</g>
<mask id="d" width="82" height="60" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:luminance">
<path fill="url(#c)" d="M82 0H0v60h82V0Z"/>
</mask>
<g mask="url(#d)">
<path fill="url(#e)" d="M68.5 82C83.135 82 95 73.046 95 62S83.135 42 68.5 42C53.864 42 42 50.954 42 62s11.864 20 26.5 20Z"/>
</g>
<mask id="g" width="82" height="60" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:luminance">
<path fill="url(#f)" d="M82 0H0v60h82V0Z"/>
</mask>
<g mask="url(#g)">
<path fill="url(#h)" d="M18 99c28.166 0 51-14.327 51-32 0-17.673-22.834-32-51-32s-51 14.327-51 32c0 17.673 22.834 32 51 32Z"/>
</g>
</g>
<defs>
<linearGradient id="c" x1="5975.75" x2="3780.14" y1="2680.44" y2="956.274" gradientUnits="userSpaceOnUse">
<stop stop-color="#008374"/>
<stop offset="1" stop-color="#006A59"/>
</linearGradient>
<linearGradient id="e" x1="3904.37" x2="2451.99" y1="1828.96" y2="723.21" gradientUnits="userSpaceOnUse">
<stop stop-color="#008374"/>
<stop offset="1" stop-color="#006A59"/>
</linearGradient>
<linearGradient id="f" x1="7258.39" x2="4310.04" y1="2308.86" y2="3513.91" gradientUnits="userSpaceOnUse">
<stop stop-color="#00AA89"/>
<stop offset="1" stop-color="#009989"/>
</linearGradient>
<linearGradient id="h" x1="8995.73" x2="5507.96" y1="2497.78" y2="4160.17" gradientUnits="userSpaceOnUse">
<stop stop-color="#00AA89"/>
<stop offset="1" stop-color="#009989"/>
</linearGradient>
<clipPath id="a">
<path fill="#fff" d="M0 0h82v60H0z"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -0,0 +1,47 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 82 60">
<g clip-path="url(#a)">
<g opacity=".5">
<path fill="#79D1F2" d="M82 0H0v60h82V0Z"/>
<mask id="b" width="82" height="60" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:luminance">
<path fill="#F3EC60" d="M82 0H0v60h82V0Z"/>
</mask>
<g mask="url(#b)">
<path fill="#F3EC60" d="M65.5 19a7.5 7.5 0 1 0 0-15 7.5 7.5 0 0 0 0 15Z"/>
</g>
<mask id="d" width="82" height="60" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:luminance">
<path fill="url(#c)" d="M82 0H0v60h82V0Z"/>
</mask>
<g mask="url(#d)">
<path fill="url(#e)" d="M68.5 82C83.14 82 95 73.05 95 62S83.14 42 68.5 42 42 50.95 42 62s11.86 20 26.5 20Z"/>
</g>
<mask id="g" width="82" height="60" x="0" y="0" maskUnits="userSpaceOnUse" style="mask-type:luminance">
<path fill="url(#f)" d="M82 0H0v60h82V0Z"/>
</mask>
<g mask="url(#g)">
<path fill="url(#h)" d="M18 99c28.17 0 51-14.33 51-32S46.17 35 18 35s-51 14.33-51 32 22.83 32 51 32Z"/>
</g>
</g>
<path fill="#fff" d="M39 34.5v-9l6 4.5m-4-10a10 10 0 1 0 0 20 10 10 0 0 0 0-20Z"/>
</g>
<defs>
<linearGradient id="c" x1="5975.75" x2="3780.14" y1="2680.44" y2="956.27" gradientUnits="userSpaceOnUse">
<stop stop-color="#008374"/>
<stop offset="1" stop-color="#006A59"/>
</linearGradient>
<linearGradient id="e" x1="3904.37" x2="2451.99" y1="1828.96" y2="723.21" gradientUnits="userSpaceOnUse">
<stop stop-color="#008374"/>
<stop offset="1" stop-color="#006A59"/>
</linearGradient>
<linearGradient id="f" x1="7258.39" x2="4310.04" y1="2308.86" y2="3513.91" gradientUnits="userSpaceOnUse">
<stop stop-color="#00AA89"/>
<stop offset="1" stop-color="#009989"/>
</linearGradient>
<linearGradient id="h" x1="8995.73" x2="5507.96" y1="2497.78" y2="4160.17" gradientUnits="userSpaceOnUse">
<stop stop-color="#00AA89"/>
<stop offset="1" stop-color="#009989"/>
</linearGradient>
<clipPath id="a">
<path fill="#fff" d="M0 0h82v60H0z"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 78 KiB

Before After
Before After

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

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