Merge branch 'staging' into soon

pull/1/head
ansuz 3 years ago
commit 4b91f01b78

@ -1,3 +1,94 @@
# 4.11.0 (WIP)
## Goals
## Update notes
* warning about lack of support for internet explorer
* existing support will get worse over time. please update.
* we only support IE for the home page and related info pages. Apps with complex functionality assume you are using a regularly updated browser.
* this release includes new clientside dependencies. Don't forget to run `bower update`
To update from 4.10.0 to 4.11.0:
1. Stop your server
2. Get the latest code with git
3. Install the latest dependencies with `bower update` and `npm i`
4. Restart your server
5. Confirm that your instance is passing all the tests included on the `/checkup/` page (on whatever devices you intend to support)
## Features
* unify unregistered/non-registered/anonymous terminology as 'guest'
* support
* prompt users that need support to subscribe
* refactor debugging data generation to easily show users what data is included
* form improvements
* include bar graphs for multiple-answer form questions
* move the tally of empty responses to the top of each question's summary (rather than the bottom)
* conditionally displayed sections depending on the state of previous answers
* nicer participant view without CryptPad toolbar or popups
* response page to with customizable message to thank those that have responded
* more granular form controls and clearer text
* anonymization settings for answers
* optional restriction of a form to registered users only
* real-time form authorship.
* changes are saved as you type, so you no longer need to "save" each question.
* co-author surveys with other users and edit the same question concurrently.
* avoid redrawing active parts of the UI when other authors make a change (datepicker UI, dropdowns, etc.)
* redraw no more than once every 500ms for performance reasons
* preserve current scroll position when other users make changes
* easier access to basic for form authors in the left sidebar:
* preview a form
* copy the participant link
* view existing responses
* more intuitive display of answers
* bar charts throughout, wherever applicable
* options with no answers are still displayed with zero results in the summary rather than not being displayed at all
* options are displayed according to the order of their appearance in the original question, rather than according to the order in which participants chose them
* the number of empty answers is displayed above the scrollable section of each answer's summary rather than at the bottom
* more intuitive controls and default options
* placeholders for text inputs instead of pre-filled fields
* "enter" creates a new field
* "esc" clears an empty field
* easy navigation using the tab key
* convert between related question types:
* radio, checkbox, ranked choices
* multi-radio, multi-check
* more form validation options:
* required questions
* validated question types
* summarize invalid answers at the bottom of the form. jump to the relevant question when clicked.
* CryptPad logo displayed at the bottom of the participant page which links to the home page
* we've pre-filled some options in our "simple scheduling poll" template.
* bar charts on the admin page's 'Performance' tab
* enhancements for guest users and registered users without names or avatars
* two initials for users with a custom name but no avatar (previously one initial, always capitalized)
* animal avatars as defaults instead of indistinguishable initials (A for Anonymous, G for Guest)
* configurable via `AppConfig.emojiAvatars = []`
* authorship data for guests in rich text comments, code editor author data
* emojis in cursor tooltips for guests (rich text, code, slide, kanban)
* emojis in the share and access modals for contacts with empty names
* script to identify unnecessary duplication of translations
* improvements to upload and media-tag UI
* support for adding descriptive text at upload time
* preview of uploaded media in the upload modal
* our link creation UI from 4.9.0 now highlights the URL input field as you type to indicate whether the current URL value is valid
* the share menu now makes its primary actions more clear, with explicit text ("copy link" instead of just "copy") on its main buttons, as well as icons that better match button UI on the rest of the platform.
* we're working towards better accessibility for screen readers with better alt-text and `aria-` attributes to suppress descriptions of strictly visual UI features.
## Bug fixes
* fix empty name fields in various places across the platform where we did not fall back to "anonymous/guest"
* teams
* contacts
* ???
* clarified a comment in the nginx config about _professional support_
* handled an edge case in ICS import to calendars where DTEND was not defined (use duration or consider it an "all-day" event
* links shared by contacts could be previewed in a modal when viewing their notification. The color of the previewed link was overridden by some bootstrap styles. we now use a better color.
* better validation for team invite links where badly formed invite content could have triggered a type error.
# 4.10.0 # 4.10.0
## Goals ## Goals

@ -30,7 +30,7 @@
"secure-fabric.js": "secure-v1.7.9", "secure-fabric.js": "secure-v1.7.9",
"hyperjson": "~1.4.0", "hyperjson": "~1.4.0",
"chainpad-crypto": "^0.2.0", "chainpad-crypto": "^0.2.0",
"chainpad-listmap": "^0.10.0", "chainpad-listmap": "^1.0.0",
"chainpad": "^5.2.0", "chainpad": "^5.2.0",
"file-saver": "1.3.1", "file-saver": "1.3.1",
"alertifyjs": "1.0.11", "alertifyjs": "1.0.11",

@ -7,28 +7,28 @@
<font-face units-per-em="1024" ascent="960" descent="-64" /> <font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" /> <missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" /> <glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe900;" glyph-name="folder-no-color" d="M194.559 846.275c-77.457-0.137-140.211-62.89-140.348-140.334v-515.869c0.137-77.457 62.892-140.211 140.336-140.348h634.893c77.457 0.137 140.211 62.892 140.348 140.336v396.602c0 77.561-62.808 140.453-140.336 140.59h-296.852l-47.104 62.885c-25.923 34.066-66.407 55.898-112 56.139h-178.937zM194.553 787.607h178.906c26.48-0.030 50.004-12.656 64.908-32.207l0.146-0.199 47.104-62.766 17.709-24.094h326.113c45.125-0.069 81.68-36.665 81.68-81.799v-396.471c-0.042-27.788-13.947-52.311-35.156-67.064l-725.621 651.525c12.744 8.239 27.912 13.050 44.211 13.074zM115.25 725.406l687.184-617.014h-607.875c-45.083 0.068-81.61 36.598-81.678 81.674v515.861c0.010 6.714 0.834 13.236 2.369 19.479z" /> <glyph unicode="&#xe900;" glyph-name="form-conditional" horiz-adv-x="1094" d="M300.535 78.617c0 3.87-1.548 7.739-4.335 10.525l-45.506 45.507 45.507 45.507c2.787 2.786 4.335 6.656 4.335 10.525s-1.548 7.739-4.335 10.525l-21.051 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-45.507-45.507-45.507 45.507c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l45.507-45.507-45.507-45.507c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.74 4.335-10.525l21.051-21.051c2.787-2.787 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l45.507 45.507 45.507-45.507c2.787-2.787 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l21.051 21.051c2.787 2.787 4.335 6.656 4.335 10.525zM999.093 190.682c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.787 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM514.273 890.273v-260.273h-332.955v-277.227h65.364v211.955h600.546v-211.955h65.273v277.227h-332.955v260.273z" />
<glyph unicode="&#xe901;" glyph-name="whiteboard" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM446.333 524.286c-17.277 0.517-34.937-1.027-52.952-4.571-22.15-4.43-42.984-11.806-62.476-22.143-19.492-10.632-37.062-23.776-52.714-39.429-15.357-15.357-28.321-32.794-38.952-52.286-10.632-19.196-18.189-39.85-22.619-62-7.974-41.346-5.87-79.57 6.238-114.714 12.404-35.144 30.421-65.145 54.048-89.952 23.626-24.512 50.629-42.977 81.048-55.381 30.714-12.108 60.087-15.954 88.143-11.524 18.31 2.658 31.188 12.718 38.571 30.143 7.679 17.72 7.364 34.709-0.905 50.952-10.337 20.082-9.623 39.575 2.19 58.476 11.813 19.196 29.117 28.762 51.857 28.762h70.429c15.948 0 29.539 5.635 40.762 16.857 11.222 11.518 16.81 25.243 16.81 41.19 0 34.849-7.51 67.353-22.571 97.476-14.766 29.828-34.707 55.089-59.809 75.762-24.808 20.673-53.599 35.559-86.381 44.714-16.538 4.578-33.438 7.15-50.714 7.667zM439 467.476c7.974 0 14.636-2.817 19.952-8.429 5.611-5.316 8.429-11.979 8.429-19.952s-2.817-14.77-8.429-20.381c-5.316-5.316-11.978-7.952-19.952-7.952s-14.77 2.636-20.381 7.952c-5.316 5.611-7.952 12.407-7.952 20.381s2.636 14.636 7.952 19.952c5.611 5.611 12.407 8.429 20.381 8.429zM325.619 410.762c7.974 0 14.589-2.817 19.905-8.429 5.611-5.316 8.429-11.979 8.429-19.952s-2.817-14.77-8.429-20.381c-5.316-5.316-11.931-7.952-19.905-7.952s-14.77 2.636-20.381 7.952c-5.316 5.611-8 12.407-8 20.381s2.684 14.636 8 19.952c5.611 5.611 12.407 8.429 20.381 8.429zM552.429 410.762c7.974 0 14.636-2.817 19.952-8.429 5.611-5.316 8.381-11.979 8.381-19.952s-2.77-14.77-8.381-20.381c-5.316-5.316-11.978-7.952-19.952-7.952s-14.77 2.636-20.381 7.952c-5.316 5.611-7.952 12.407-7.952 20.381s2.636 14.636 7.952 19.952c5.611 5.611 12.407 8.429 20.381 8.429zM297.238 297.333c7.974 0 14.636-2.77 19.952-8.381 5.611-5.316 8.429-11.978 8.429-19.952s-2.817-14.77-8.429-20.381c-5.316-5.316-11.979-8-19.952-8s-14.722 2.684-20.333 8c-5.316 5.611-8 12.407-8 20.381s2.684 14.636 8 19.952c5.611 5.611 12.359 8.381 20.333 8.381z" /> <glyph unicode="&#xe901;" glyph-name="folder-no-color" d="M194.559 846.275c-77.457-0.137-140.211-62.89-140.348-140.334v-515.869c0.137-77.457 62.892-140.211 140.336-140.348h634.893c77.457 0.137 140.211 62.892 140.348 140.336v396.602c0 77.561-62.808 140.453-140.336 140.59h-296.852l-47.104 62.885c-25.923 34.066-66.407 55.898-112 56.139h-178.937zM194.553 787.607h178.906c26.48-0.030 50.004-12.656 64.908-32.207l0.146-0.199 47.104-62.766 17.709-24.094h326.113c45.125-0.069 81.68-36.665 81.68-81.799v-396.471c-0.042-27.788-13.947-52.311-35.156-67.064l-725.621 651.525c12.744 8.239 27.912 13.050 44.211 13.074zM115.25 725.406l687.184-617.014h-607.875c-45.083 0.068-81.61 36.598-81.678 81.674v515.861c0.010 6.714 0.834 13.236 2.369 19.479z" />
<glyph unicode="&#xe902;" glyph-name="new-template" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM414.476 490.857c-12.963 0-23.476-10.514-23.476-23.476v-101.762h-101.762c-12.963 0-23.476-10.514-23.476-23.476v-46.952c0-12.963 10.514-23.476 23.476-23.476h101.762v-101.762c0-12.963 10.514-23.476 23.476-23.476h46.952c12.963 0 23.476 10.514 23.476 23.476v101.762h101.762c12.963 0 23.476 10.514 23.476 23.476v46.952c0 12.963-10.514 23.476-23.476 23.476h-101.762v101.762c0 12.963-10.514 23.476-23.476 23.476h-46.952z" /> <glyph unicode="&#xe902;" glyph-name="whiteboard" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM446.333 524.286c-17.277 0.517-34.937-1.027-52.952-4.571-22.15-4.43-42.984-11.806-62.476-22.143-19.492-10.632-37.062-23.776-52.714-39.429-15.357-15.357-28.321-32.794-38.952-52.286-10.632-19.196-18.189-39.85-22.619-62-7.974-41.346-5.87-79.57 6.238-114.714 12.404-35.144 30.421-65.145 54.048-89.952 23.626-24.512 50.629-42.977 81.048-55.381 30.714-12.108 60.087-15.954 88.143-11.524 18.31 2.658 31.188 12.718 38.571 30.143 7.679 17.72 7.364 34.709-0.905 50.952-10.337 20.082-9.623 39.575 2.19 58.476 11.813 19.196 29.117 28.762 51.857 28.762h70.429c15.948 0 29.539 5.635 40.762 16.857 11.222 11.518 16.81 25.243 16.81 41.19 0 34.849-7.51 67.353-22.571 97.476-14.766 29.828-34.707 55.089-59.809 75.762-24.808 20.673-53.599 35.559-86.381 44.714-16.538 4.578-33.438 7.15-50.714 7.667zM439 467.476c7.974 0 14.636-2.817 19.952-8.429 5.611-5.316 8.429-11.979 8.429-19.952s-2.817-14.77-8.429-20.381c-5.316-5.316-11.978-7.952-19.952-7.952s-14.77 2.636-20.381 7.952c-5.316 5.611-7.952 12.407-7.952 20.381s2.636 14.636 7.952 19.952c5.611 5.611 12.407 8.429 20.381 8.429zM325.619 410.762c7.974 0 14.589-2.817 19.905-8.429 5.611-5.316 8.429-11.979 8.429-19.952s-2.817-14.77-8.429-20.381c-5.316-5.316-11.931-7.952-19.905-7.952s-14.77 2.636-20.381 7.952c-5.316 5.611-8 12.407-8 20.381s2.684 14.636 8 19.952c5.611 5.611 12.407 8.429 20.381 8.429zM552.429 410.762c7.974 0 14.636-2.817 19.952-8.429 5.611-5.316 8.381-11.979 8.381-19.952s-2.77-14.77-8.381-20.381c-5.316-5.316-11.978-7.952-19.952-7.952s-14.77 2.636-20.381 7.952c-5.316 5.611-7.952 12.407-7.952 20.381s2.636 14.636 7.952 19.952c5.611 5.611 12.407 8.429 20.381 8.429zM297.238 297.333c7.974 0 14.636-2.77 19.952-8.381 5.611-5.316 8.429-11.978 8.429-19.952s-2.817-14.77-8.429-20.381c-5.316-5.316-11.979-8-19.952-8s-14.722 2.684-20.333 8c-5.316 5.611-8 12.407-8 20.381s2.684 14.636 8 19.952c5.611 5.611 12.359 8.381 20.333 8.381z" />
<glyph unicode="&#xe903;" glyph-name="shared-folder" d="M829.44 727.251h-296.84l-47.104 62.886c-25.923 34.066-66.406 55.898-111.999 56.139h-178.938c-77.457-0.137-140.211-62.891-140.348-140.335v-515.868c0.137-77.457 62.891-140.211 140.335-140.348h634.893c77.457 0.137 140.211 62.891 140.348 140.335v396.482c0 0.036 0 0.078 0 0.121 0 77.561-62.807 140.452-140.335 140.589h-0.013zM911.119 190.072c-0.068-45.083-36.597-81.611-81.673-81.679h-634.887c-45.083 0.068-81.611 36.597-81.679 81.673v515.862c0.068 45.083 36.597 81.611 81.673 81.679h178.906c26.48-0.030 50.004-12.656 64.908-32.207l0.146-0.199 47.104-62.765 17.709-24.094h326.114c45.125-0.069 81.679-36.665 81.679-81.799 0 0 0 0 0 0v0zM614.4 451.132c0.071 0 0.156 0 0.24 0 34.132 0 61.801 27.669 61.801 61.801s-27.669 61.801-61.801 61.801c-34.047 0-61.664-27.532-61.801-61.547v-0.013c0-0.018 0-0.040 0-0.061 0-7.309 1.235-14.33 3.508-20.865l-0.135 0.446-103.966-60.235c-0.474 0.655-1.031 1.213-1.665 1.672l-0.021 0.015c-10.785 9.46-25.010 15.231-40.582 15.231-34.065 0-61.681-27.615-61.681-61.681 0-11.035 2.898-21.393 7.974-30.355l-0.16 0.307c11.046-18 30.619-29.824 52.953-29.824 16.92 0 32.255 6.786 43.431 17.785l-0.008-0.008 103.966-60.235c-2.138-5.921-3.374-12.754-3.374-19.876 0-0.085 0-0.171 0.001-0.256v0.013c-0.003-0.217-0.005-0.474-0.005-0.731 0-7.409 1.417-14.486 3.994-20.977l-0.135 0.384c8.944-23.66 31.407-40.178 57.728-40.178 33.999 0 61.56 27.562 61.56 61.56 0 28.833-19.822 53.036-46.582 59.725l-0.424 0.090c-4.366 1.539-9.418 2.572-14.664 2.884l-0.154 0.007c-19.639 0-37.082-9.398-48.078-23.943l-0.11-0.152-101.798 59.031c3.729 7.764 5.908 16.879 5.908 26.504s-2.179 18.74-6.070 26.88l0.162-0.376 101.798 58.79c11.336-14.332 28.681-23.481 48.167-23.612h0.022z" /> <glyph unicode="&#xe903;" glyph-name="new-template" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM414.476 490.857c-12.963 0-23.476-10.514-23.476-23.476v-101.762h-101.762c-12.963 0-23.476-10.514-23.476-23.476v-46.952c0-12.963 10.514-23.476 23.476-23.476h101.762v-101.762c0-12.963 10.514-23.476 23.476-23.476h46.952c12.963 0 23.476 10.514 23.476 23.476v101.762h101.762c12.963 0 23.476 10.514 23.476 23.476v46.952c0 12.963-10.514 23.476-23.476 23.476h-101.762v101.762c0 12.963-10.514 23.476-23.476 23.476h-46.952z" />
<glyph unicode="&#xe904;" glyph-name="file-upload" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM438.857 487.905c-8.019 0-15.814-3.102-21.238-8.762l-153.524-153.524c-5.66-5.66-8.952-13.457-8.952-21.476s3.292-15.53 8.952-21.19l17.667-17.714c5.424-5.66 13.219-8.952 21.238-8.952s15.814 3.292 21.238 8.952l69.333 69.095v-166c0-16.981 14.153-27.619 30.19-27.619h30.19c16.038 0 30.19 10.638 30.19 27.619v166l69.333-69.095c5.424-5.66 13.219-8.952 21.238-8.952s15.816 3.292 21.476 8.952l17.667 17.714c5.425 5.66 8.714 13.172 8.714 21.19s-3.29 15.816-8.714 21.476l-153.524 153.524c-5.66 5.66-13.457 8.762-21.476 8.762z" /> <glyph unicode="&#xe904;" glyph-name="shared-folder" d="M829.44 727.251h-296.84l-47.104 62.886c-25.923 34.066-66.406 55.898-111.999 56.139h-178.938c-77.457-0.137-140.211-62.891-140.348-140.335v-515.868c0.137-77.457 62.891-140.211 140.335-140.348h634.893c77.457 0.137 140.211 62.891 140.348 140.335v396.482c0 0.036 0 0.078 0 0.121 0 77.561-62.807 140.452-140.335 140.589h-0.013zM911.119 190.072c-0.068-45.083-36.597-81.611-81.673-81.679h-634.887c-45.083 0.068-81.611 36.597-81.679 81.673v515.862c0.068 45.083 36.597 81.611 81.673 81.679h178.906c26.48-0.030 50.004-12.656 64.908-32.207l0.146-0.199 47.104-62.765 17.709-24.094h326.114c45.125-0.069 81.679-36.665 81.679-81.799 0 0 0 0 0 0v0zM614.4 451.132c0.071 0 0.156 0 0.24 0 34.132 0 61.801 27.669 61.801 61.801s-27.669 61.801-61.801 61.801c-34.047 0-61.664-27.532-61.801-61.547v-0.013c0-0.018 0-0.040 0-0.061 0-7.309 1.235-14.33 3.508-20.865l-0.135 0.446-103.966-60.235c-0.474 0.655-1.031 1.213-1.665 1.672l-0.021 0.015c-10.785 9.46-25.010 15.231-40.582 15.231-34.065 0-61.681-27.615-61.681-61.681 0-11.035 2.898-21.393 7.974-30.355l-0.16 0.307c11.046-18 30.619-29.824 52.953-29.824 16.92 0 32.255 6.786 43.431 17.785l-0.008-0.008 103.966-60.235c-2.138-5.921-3.374-12.754-3.374-19.876 0-0.085 0-0.171 0.001-0.256v0.013c-0.003-0.217-0.005-0.474-0.005-0.731 0-7.409 1.417-14.486 3.994-20.977l-0.135 0.384c8.944-23.66 31.407-40.178 57.728-40.178 33.999 0 61.56 27.562 61.56 61.56 0 28.833-19.822 53.036-46.582 59.725l-0.424 0.090c-4.366 1.539-9.418 2.572-14.664 2.884l-0.154 0.007c-19.639 0-37.082-9.398-48.078-23.943l-0.11-0.152-101.798 59.031c3.729 7.764 5.908 16.879 5.908 26.504s-2.179 18.74-6.070 26.88l0.162-0.376 101.798 58.79c11.336-14.332 28.681-23.481 48.167-23.612h0.022z" />
<glyph unicode="&#xe905;" glyph-name="template" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM535.524 513.905c-63.766 0-115.619-51.901-115.619-115.667s51.854-115.619 115.619-115.619c48.792 0 92.974 31.714 109.238 77.667 2.84 8.261 5.905 18.862 5.905 27.381 0 5.163-3.075 9.048-8.238 9.048s-65.052-37.714-73.571-42.619l-49.857 27.619v57.857l75.667 43.619c2.323 1.549 4.143 4.398 4.143 7.238 0 3.098-1.562 5.431-4.143 7.238-15.748 10.585-40.297 16.238-59.143 16.238zM412.667 349.714l-175.81-175.81c-6.196-6.196-9.81-14.699-9.81-23.476s3.614-17.3 9.81-23.238l27.333-27.905c6.196-5.938 14.746-9.524 23.524-9.524s17.3 3.586 23.238 9.524l176.048 176.095c-33.819 13.424-60.909 40.514-74.333 74.333zM304.238 183.476c9.036 0 16.524-7.488 16.524-16.524s-7.488-16.524-16.524-16.524c-9.036 0-16.524 7.488-16.524 16.524s7.488 16.524 16.524 16.524z" /> <glyph unicode="&#xe905;" glyph-name="file-upload" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM438.857 487.905c-8.019 0-15.814-3.102-21.238-8.762l-153.524-153.524c-5.66-5.66-8.952-13.457-8.952-21.476s3.292-15.53 8.952-21.19l17.667-17.714c5.424-5.66 13.219-8.952 21.238-8.952s15.814 3.292 21.238 8.952l69.333 69.095v-166c0-16.981 14.153-27.619 30.19-27.619h30.19c16.038 0 30.19 10.638 30.19 27.619v166l69.333-69.095c5.424-5.66 13.219-8.952 21.238-8.952s15.816 3.292 21.476 8.952l17.667 17.714c5.425 5.66 8.714 13.172 8.714 21.19s-3.29 15.816-8.714 21.476l-153.524 153.524c-5.66 5.66-13.457 8.762-21.476 8.762z" />
<glyph unicode="&#xe906;" glyph-name="poll" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM569.762 482.524v-349.238h162.714v349.238h-162.714zM358.238 385.476v-252.19h162.714v252.19h-162.714zM146.667 277.381v-144.095h162.762v144.095h-162.762z" /> <glyph unicode="&#xe906;" glyph-name="template" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM535.524 513.905c-63.766 0-115.619-51.901-115.619-115.667s51.854-115.619 115.619-115.619c48.792 0 92.974 31.714 109.238 77.667 2.84 8.261 5.905 18.862 5.905 27.381 0 5.163-3.075 9.048-8.238 9.048s-65.052-37.714-73.571-42.619l-49.857 27.619v57.857l75.667 43.619c2.323 1.549 4.143 4.398 4.143 7.238 0 3.098-1.562 5.431-4.143 7.238-15.748 10.585-40.297 16.238-59.143 16.238zM412.667 349.714l-175.81-175.81c-6.196-6.196-9.81-14.699-9.81-23.476s3.614-17.3 9.81-23.238l27.333-27.905c6.196-5.938 14.746-9.524 23.524-9.524s17.3 3.586 23.238 9.524l176.048 176.095c-33.819 13.424-60.909 40.514-74.333 74.333zM304.238 183.476c9.036 0 16.524-7.488 16.524-16.524s-7.488-16.524-16.524-16.524c-9.036 0-16.524 7.488-16.524 16.524s7.488 16.524 16.524 16.524z" />
<glyph unicode="&#xe907;" glyph-name="slide" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM142.286 550.714v-255.238h133.19v-109.762h133.143v-109.81h326.809v255.381h-133.143v109.81h-133.143v109.619h-326.857zM191.048 501.905h229.286v-60.81h-144.857v-96.81h-84.429v157.619zM324.238 392.333h229.286v-61.048h-144.905v-96.81h-84.381v157.857zM457.381 282.524h229.286v-157.81h-229.286v157.81z" /> <glyph unicode="&#xe907;" glyph-name="poll" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM569.762 482.524v-349.238h162.714v349.238h-162.714zM358.238 385.476v-252.19h162.714v252.19h-162.714zM146.667 277.381v-144.095h162.762v144.095h-162.762z" />
<glyph unicode="&#xe908;" glyph-name="sheet" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM141.286 532.571v-463.81h598.429v463.81h-598.429zM190.048 483.762h134.429v-158.714h-134.429v158.714zM373.286 483.762h134.429v-158.714h-134.429v158.714zM556.524 483.762h134.429v-158.714h-134.429v158.714zM190.048 276.286h134.429v-158.762h-134.429v158.762zM373.286 276.286h134.429v-158.762h-134.429v158.762zM556.524 276.286h134.429v-158.762h-134.429v158.762z" /> <glyph unicode="&#xe908;" glyph-name="slide" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM142.286 550.714v-255.238h133.19v-109.762h133.143v-109.81h326.809v255.381h-133.143v109.81h-133.143v109.619h-326.857zM191.048 501.905h229.286v-60.81h-144.857v-96.81h-84.429v157.619zM324.238 392.333h229.286v-61.048h-144.905v-96.81h-84.381v157.857zM457.381 282.524h229.286v-157.81h-229.286v157.81z" />
<glyph unicode="&#xe909;" glyph-name="folder-open" d="M100.232 590.035h828.717c-5.175 69.899-63.091 124.668-133.829 124.808h-283.843l-44.936 60.235c-24.766 32.712-63.599 53.649-107.326 53.73h-170.599c-0.036 0-0.078 0-0.121 0-73.968 0-133.946-59.894-134.084-133.83v-213.366l10.12 76.74c2.295 17.95 17.476 31.684 35.865 31.684 0.012 0 0.025 0 0.037 0h-0.002zM929.19 541.606h-805.948c-13.269-0.004-24.238-9.848-26.006-22.632l-0.016-0.137-43.008-317.801c-0.002-0.261-0.003-0.569-0.003-0.877 0-6.111 0.483-12.11 1.413-17.96l-0.085 0.646c0.904-6.888 2.169-12.966 3.837-18.875l-0.223 0.925c16.563-56.812 68.138-97.63 129.257-97.702h606.698c61.093 0.086 112.628 40.906 128.907 96.752l0.237 0.95c1.459 5.065 2.725 11.228 3.544 17.531l0.070 0.66c0.844 5.201 1.327 11.196 1.327 17.304 0 0.227-0.001 0.454-0.002 0.681v-0.035l40.237 295.755c0.219 1.556 0.344 3.354 0.344 5.18 0 21.624-17.529 39.153-39.153 39.153-0.036 0-0.073 0-0.109 0h0.006z" /> <glyph unicode="&#xe909;" glyph-name="sheet" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM141.286 532.571v-463.81h598.429v463.81h-598.429zM190.048 483.762h134.429v-158.714h-134.429v158.714zM373.286 483.762h134.429v-158.714h-134.429v158.714zM556.524 483.762h134.429v-158.714h-134.429v158.714zM190.048 276.286h134.429v-158.762h-134.429v158.762zM373.286 276.286h134.429v-158.762h-134.429v158.762zM556.524 276.286h134.429v-158.762h-134.429v158.762z" />
<glyph unicode="&#xe90a;" glyph-name="kanban" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM146.667 493.81v-90.143h162.762v90.143h-162.762zM358.238 493.81v-90.143h162.714v90.143h-162.714zM569.762 493.81v-90.143h162.714v90.143h-162.714zM146.667 358.619v-90.143h162.762v90.143h-162.762zM569.762 358.619v-90.143h162.714v90.143h-162.714zM146.667 223.429v-90.143h162.762v90.143h-162.762z" /> <glyph unicode="&#xe90a;" glyph-name="folder-open" d="M100.232 590.035h828.717c-5.175 69.899-63.091 124.668-133.829 124.808h-283.843l-44.936 60.235c-24.766 32.712-63.599 53.649-107.326 53.73h-170.599c-0.036 0-0.078 0-0.121 0-73.968 0-133.946-59.894-134.084-133.83v-213.366l10.12 76.74c2.295 17.95 17.476 31.684 35.865 31.684 0.012 0 0.025 0 0.037 0h-0.002zM929.19 541.606h-805.948c-13.269-0.004-24.238-9.848-26.006-22.632l-0.016-0.137-43.008-317.801c-0.002-0.261-0.003-0.569-0.003-0.877 0-6.111 0.483-12.11 1.413-17.96l-0.085 0.646c0.904-6.888 2.169-12.966 3.837-18.875l-0.223 0.925c16.563-56.812 68.138-97.63 129.257-97.702h606.698c61.093 0.086 112.628 40.906 128.907 96.752l0.237 0.95c1.459 5.065 2.725 11.228 3.544 17.531l0.070 0.66c0.844 5.201 1.327 11.196 1.327 17.304 0 0.227-0.001 0.454-0.002 0.681v-0.035l40.237 295.755c0.219 1.556 0.344 3.354 0.344 5.18 0 21.624-17.529 39.153-39.153 39.153-0.036 0-0.073 0-0.109 0h0.006z" />
<glyph unicode="&#xe90b;" glyph-name="folder" d="M373.459 846.276h-178.899c-77.457-0.137-140.211-62.891-140.348-140.335v-515.868c0.137-77.457 62.891-140.211 140.335-140.348h634.893c77.457 0.137 140.211 62.891 140.348 140.335v396.482c0 0.036 0 0.078 0 0.121 0 77.561-62.807 140.452-140.335 140.589h-296.853l-47.104 62.886c-25.923 34.066-66.406 55.898-111.999 56.139h-0.039z" /> <glyph unicode="&#xe90b;" glyph-name="kanban" horiz-adv-x="878" d="M65.524 945.762c-29.444 0-53.333-23.889-53.333-53.333v-888.857c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.206 70.54-37.762 91.095l-173.333 173.333c-20.556 20.556-61.698 37.762-91.143 37.762h-497.762zM83.286 874.667h426.667v-231.095c0-29.444 23.889-53.333 53.333-53.333h231.143v-568.905h-711.143v853.333zM581.095 870.238c9.444-3.333 18.873-8.349 22.762-12.238l173.905-173.905c3.889-3.889 8.857-13.317 12.19-22.762h-208.857v208.905zM146.667 493.81v-90.143h162.762v90.143h-162.762zM358.238 493.81v-90.143h162.714v90.143h-162.714zM569.762 493.81v-90.143h162.714v90.143h-162.714zM146.667 358.619v-90.143h162.762v90.143h-162.762zM569.762 358.619v-90.143h162.714v90.143h-162.714zM146.667 223.429v-90.143h162.762v90.143h-162.762z" />
<glyph unicode="&#xe90c;" glyph-name="shared-folder-open" d="M98.424 593.288h797.274c-4.8 67.457-60.657 120.376-128.894 120.471h-272.876l-43.249 57.705c-23.816 31.47-61.17 51.611-103.232 51.682h-164.213c-0.036 0-0.079 0-0.121 0-71.191 0-128.904-57.712-128.904-128.904 0-0.17 0-0.339 0.001-0.508v0.026-204.8l9.638 73.487c2.062 17.437 16.753 30.833 34.574 30.84h0.001zM900.759 255.608l33.973 248.049c0.196 1.447 0.308 3.12 0.308 4.819 0 20.873-16.906 37.797-37.772 37.828h-776.797c-12.746-0.016-23.272-9.5-24.923-21.796l-0.014-0.129-41.321-304.791c-0.002-0.25-0.003-0.546-0.003-0.843 0-5.87 0.483-11.628 1.412-17.235l-0.083 0.609c0.793-6.689 1.977-12.655 3.576-18.449l-0.203 0.861c15.92-54.648 65.53-93.912 124.319-93.967h583.566c0.061 0 0.133 0 0.205 0 16.48 0 32.227 3.14 46.675 8.853l-0.86-0.3c16.639-15.985 39.283-25.829 64.225-25.829 51.231 0 92.762 41.531 92.762 92.762 0 42.798-28.984 78.827-68.394 89.528l-0.65 0.15zM766.795 148.51h-583.56c-32.265 0.073-59.5 21.523-68.297 50.935l-0.13 0.506c-0.742 2.66-1.376 5.889-1.775 9.19l-0.032 0.327v1.566c0 1.566 0 3.373 0 5.301l36.382 272.023h724.751l-32.407-236.845c-1.82-0.63-3.331-1.281-4.788-2.025l0.21 0.097c-16.682-8.067-30.192-20.454-39.403-35.727l-0.232-0.415c-1.574-2.381-3.028-5.115-4.218-7.987l-0.119-0.325c-5.551-11.368-8.797-24.735-8.797-38.86 0-0.23 0.001-0.46 0.003-0.689v0.035c0-0.017 0-0.037 0-0.057 0-5.166 0.394-10.241 1.154-15.195l-0.070 0.554c-5.405-1.532-11.612-2.412-18.026-2.412-0.228 0-0.455 0.001-0.682 0.003h0.035zM877.026 84.781c-20.129 0.108-38.483 7.622-52.493 19.954l0.089-0.077c-14.994 12.543-25.212 30.362-27.788 50.568l-0.041 0.392c-0.537 3.145-0.844 6.769-0.844 10.463 0 0.091 0 0.182 0.001 0.273v-0.014c-0.001 0.109-0.001 0.239-0.001 0.368 0 12.484 2.89 24.293 8.038 34.794l-0.207-0.466c1.278 2.771 2.523 5.062 3.896 7.265l-0.161-0.278c7.898 12.884 18.884 23.175 31.958 30.024l0.449 0.214c0.692 0.493 1.491 0.902 2.346 1.186l0.064 0.018c10.065 4.991 21.914 7.922 34.445 7.951h0.010c0.046 0 0.1 0 0.154 0 7.802 0 15.336-1.144 22.444-3.275l-0.553 0.142c35.119-9.412 60.555-40.954 60.555-78.437 0-44.777-36.299-81.077-81.077-81.077-0.451 0-0.902 0.004-1.351 0.011l0.068-0.001zM906.059 183.206c9.581 0 17.348 7.767 17.348 17.348s-7.767 17.348-17.348 17.348v0c-0.002 0-0.004 0-0.007 0-9.411 0-17.072-7.495-17.341-16.841l-0.001-0.025c-0.004-0.12-0.006-0.262-0.006-0.404 0-1.849 0.356-3.615 1.003-5.232l-0.034 0.095-29.274-16.986c-3.089 3.105-7.328 5.063-12.025 5.18h-0.022c-9.003-0.772-16.019-8.271-16.019-17.408s7.015-16.636 15.954-17.404l0.065-0.004c4.719 0.117 8.958 2.075 12.046 5.179l0.001 0.001 12.047-7.228 16.504-9.638c-0.536-1.568-0.846-3.375-0.846-5.255 0-0.101 0.001-0.202 0.003-0.302v0.015c0-9.581 7.767-17.348 17.348-17.348s17.348 7.767 17.348 17.348c0 9.581-7.767 17.348-17.348 17.348v0c-5.563-0.038-10.508-2.653-13.705-6.709l-0.028-0.037-16.143 9.397-12.047 7.228c1.007 2.155 1.621 4.672 1.686 7.326v0.023c-0.052 2.758-0.667 5.36-1.736 7.712l0.050-0.122 28.672 16.625c3.116-4.367 8.151-7.19 13.848-7.228h0.006z" /> <glyph unicode="&#xe90c;" glyph-name="folder" d="M373.459 846.276h-178.899c-77.457-0.137-140.211-62.891-140.348-140.335v-515.868c0.137-77.457 62.891-140.211 140.335-140.348h634.893c77.457 0.137 140.211 62.891 140.348 140.335v396.482c0 0.036 0 0.078 0 0.121 0 77.561-62.807 140.452-140.335 140.589h-296.853l-47.104 62.886c-25.923 34.066-66.406 55.898-111.999 56.139h-0.039z" />
<glyph unicode="&#xe90d;" glyph-name="code" horiz-adv-x="878" d="M827.746 734.667l-173.333 173.333c-20.556 20.556-61.667 37.778-91.111 37.778h-497.778c-29.444 0-53.333-23.889-53.333-53.333v-888.889c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.222 70.556-37.778 91.111zM581.079 870.222c9.444-3.333 18.889-8.333 22.778-12.222l173.889-173.889c3.889-3.889 8.889-13.333 12.222-22.778h-208.889zM794.413 21.333h-711.111v853.333h426.667v-231.111c0-29.444 23.889-53.333 53.333-53.333h231.111zM278.857 519.111l-125.556-167.222c-4.444-6.111-4.444-15 0-21.111l125.556-167.222c6.111-7.778 17.222-9.444 25-3.333l28.333 21.111c7.778 6.111 9.444 17.222 3.333 25l-101.111 135 101.111 135c6.111 7.778 4.444 18.889-3.333 25l-28.333 21.111c-7.777 6.111-18.889 4.444-25-3.333zM724.413 351.889l-125.556 167.222c-6.111 7.778-17.222 9.444-25 3.333l-28.333-21.111c-7.777-6.111-9.444-17.222-3.333-25l101.111-135-101.111-135c-6.111-7.778-4.444-18.889 3.333-25l28.333-21.111c7.778-6.111 18.889-4.444 25 3.333l125.556 167.222c4.444 6.111 4.444 15 0 21.111zM379.968 95.778l35-5.556c9.444-1.667 18.889 4.444 20.556 14.444l76.667 461.667c1.667 9.444-4.444 18.889-14.444 20.556l-35 5.556c-9.444 1.667-18.889-4.444-20.556-14.444l-76.667-461.667c-1.667-9.444 4.444-18.889 14.444-20.556z" /> <glyph unicode="&#xe90d;" glyph-name="shared-folder-open" d="M98.424 593.288h797.274c-4.8 67.457-60.657 120.376-128.894 120.471h-272.876l-43.249 57.705c-23.816 31.47-61.17 51.611-103.232 51.682h-164.213c-0.036 0-0.079 0-0.121 0-71.191 0-128.904-57.712-128.904-128.904 0-0.17 0-0.339 0.001-0.508v0.026-204.8l9.638 73.487c2.062 17.437 16.753 30.833 34.574 30.84h0.001zM900.759 255.608l33.973 248.049c0.196 1.447 0.308 3.12 0.308 4.819 0 20.873-16.906 37.797-37.772 37.828h-776.797c-12.746-0.016-23.272-9.5-24.923-21.796l-0.014-0.129-41.321-304.791c-0.002-0.25-0.003-0.546-0.003-0.843 0-5.87 0.483-11.628 1.412-17.235l-0.083 0.609c0.793-6.689 1.977-12.655 3.576-18.449l-0.203 0.861c15.92-54.648 65.53-93.912 124.319-93.967h583.566c0.061 0 0.133 0 0.205 0 16.48 0 32.227 3.14 46.675 8.853l-0.86-0.3c16.639-15.985 39.283-25.829 64.225-25.829 51.231 0 92.762 41.531 92.762 92.762 0 42.798-28.984 78.827-68.394 89.528l-0.65 0.15zM766.795 148.51h-583.56c-32.265 0.073-59.5 21.523-68.297 50.935l-0.13 0.506c-0.742 2.66-1.376 5.889-1.775 9.19l-0.032 0.327v1.566c0 1.566 0 3.373 0 5.301l36.382 272.023h724.751l-32.407-236.845c-1.82-0.63-3.331-1.281-4.788-2.025l0.21 0.097c-16.682-8.067-30.192-20.454-39.403-35.727l-0.232-0.415c-1.574-2.381-3.028-5.115-4.218-7.987l-0.119-0.325c-5.551-11.368-8.797-24.735-8.797-38.86 0-0.23 0.001-0.46 0.003-0.689v0.035c0-0.017 0-0.037 0-0.057 0-5.166 0.394-10.241 1.154-15.195l-0.070 0.554c-5.405-1.532-11.612-2.412-18.026-2.412-0.228 0-0.455 0.001-0.682 0.003h0.035zM877.026 84.781c-20.129 0.108-38.483 7.622-52.493 19.954l0.089-0.077c-14.994 12.543-25.212 30.362-27.788 50.568l-0.041 0.392c-0.537 3.145-0.844 6.769-0.844 10.463 0 0.091 0 0.182 0.001 0.273v-0.014c-0.001 0.109-0.001 0.239-0.001 0.368 0 12.484 2.89 24.293 8.038 34.794l-0.207-0.466c1.278 2.771 2.523 5.062 3.896 7.265l-0.161-0.278c7.898 12.884 18.884 23.175 31.958 30.024l0.449 0.214c0.692 0.493 1.491 0.902 2.346 1.186l0.064 0.018c10.065 4.991 21.914 7.922 34.445 7.951h0.010c0.046 0 0.1 0 0.154 0 7.802 0 15.336-1.144 22.444-3.275l-0.553 0.142c35.119-9.412 60.555-40.954 60.555-78.437 0-44.777-36.299-81.077-81.077-81.077-0.451 0-0.902 0.004-1.351 0.011l0.068-0.001zM906.059 183.206c9.581 0 17.348 7.767 17.348 17.348s-7.767 17.348-17.348 17.348v0c-0.002 0-0.004 0-0.007 0-9.411 0-17.072-7.495-17.341-16.841l-0.001-0.025c-0.004-0.12-0.006-0.262-0.006-0.404 0-1.849 0.356-3.615 1.003-5.232l-0.034 0.095-29.274-16.986c-3.089 3.105-7.328 5.063-12.025 5.18h-0.022c-9.003-0.772-16.019-8.271-16.019-17.408s7.015-16.636 15.954-17.404l0.065-0.004c4.719 0.117 8.958 2.075 12.046 5.179l0.001 0.001 12.047-7.228 16.504-9.638c-0.536-1.568-0.846-3.375-0.846-5.255 0-0.101 0.001-0.202 0.003-0.302v0.015c0-9.581 7.767-17.348 17.348-17.348s17.348 7.767 17.348 17.348c0 9.581-7.767 17.348-17.348 17.348v0c-5.563-0.038-10.508-2.653-13.705-6.709l-0.028-0.037-16.143 9.397-12.047 7.228c1.007 2.155 1.621 4.672 1.686 7.326v0.023c-0.052 2.758-0.667 5.36-1.736 7.712l0.050-0.122 28.672 16.625c3.116-4.367 8.151-7.19 13.848-7.228h0.006z" />
<glyph unicode="&#xe90e;" glyph-name="richtext" horiz-adv-x="878" d="M827.746 734.667l-173.333 173.333c-20.556 20.556-61.667 37.778-91.111 37.778h-497.778c-29.444 0-53.333-23.889-53.333-53.333v-888.889c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.222 70.556-37.778 91.111zM581.079 870.222c9.444-3.333 18.889-8.333 22.778-12.222l173.889-173.889c3.889-3.889 8.889-13.333 12.222-22.778h-208.889zM794.413 21.333h-711.111v853.333h426.667v-231.111c0-29.444 23.889-53.333 53.333-53.333h231.111zM225.524 501.333v-35.556c0-10 7.778-17.778 17.778-17.778h391.111c10 0 17.778 7.778 17.778 17.778v35.556c0 10-7.778 17.778-17.778 17.778h-391.111c-10 0-17.778-7.778-17.778-17.778zM634.413 376.889h-391.111c-10 0-17.778-7.778-17.778-17.778v-35.556c0-10 7.778-17.778 17.778-17.778h391.111c10 0 17.778 7.778 17.778 17.778v35.556c0 10-7.778 17.778-17.778 17.778zM634.413 234.667h-391.111c-10 0-17.778-7.778-17.778-17.778v-35.556c0-10 7.778-17.778 17.778-17.778h391.111c10 0 17.778 7.778 17.778 17.778v35.556c0 10-7.778 17.778-17.778 17.778z" /> <glyph unicode="&#xe90e;" glyph-name="code" horiz-adv-x="878" d="M827.746 734.667l-173.333 173.333c-20.556 20.556-61.667 37.778-91.111 37.778h-497.778c-29.444 0-53.333-23.889-53.333-53.333v-888.889c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.222 70.556-37.778 91.111zM581.079 870.222c9.444-3.333 18.889-8.333 22.778-12.222l173.889-173.889c3.889-3.889 8.889-13.333 12.222-22.778h-208.889zM794.413 21.333h-711.111v853.333h426.667v-231.111c0-29.444 23.889-53.333 53.333-53.333h231.111zM278.857 519.111l-125.556-167.222c-4.444-6.111-4.444-15 0-21.111l125.556-167.222c6.111-7.778 17.222-9.444 25-3.333l28.333 21.111c7.778 6.111 9.444 17.222 3.333 25l-101.111 135 101.111 135c6.111 7.778 4.444 18.889-3.333 25l-28.333 21.111c-7.777 6.111-18.889 4.444-25-3.333zM724.413 351.889l-125.556 167.222c-6.111 7.778-17.222 9.444-25 3.333l-28.333-21.111c-7.777-6.111-9.444-17.222-3.333-25l101.111-135-101.111-135c-6.111-7.778-4.444-18.889 3.333-25l28.333-21.111c7.778-6.111 18.889-4.444 25 3.333l125.556 167.222c4.444 6.111 4.444 15 0 21.111zM379.968 95.778l35-5.556c9.444-1.667 18.889 4.444 20.556 14.444l76.667 461.667c1.667 9.444-4.444 18.889-14.444 20.556l-35 5.556c-9.444 1.667-18.889-4.444-20.556-14.444l-76.667-461.667c-1.667-9.444 4.444-18.889 14.444-20.556z" />
<glyph unicode="&#xe90f;" glyph-name="file" horiz-adv-x="878" d="M827.745 734.666l-173.333 173.333c-20.556 20.556-61.667 37.778-91.111 37.778h-497.777c-29.444 0-53.333-23.889-53.333-53.333v-888.887c0-29.444 23.889-53.333 53.333-53.333h746.665c29.444 0 53.333 23.889 53.333 53.333v639.999c0 29.444-17.222 70.555-37.778 91.111zM581.079 870.221c9.444-3.333 18.889-8.333 22.778-12.222l173.889-173.889c3.889-3.889 8.889-13.333 12.222-22.778h-208.889zM794.412 21.334h-711.11v853.332h426.666v-231.111c0-29.444 23.889-53.333 53.333-53.333h231.111z" /> <glyph unicode="&#xe90f;" glyph-name="richtext" horiz-adv-x="878" d="M827.746 734.667l-173.333 173.333c-20.556 20.556-61.667 37.778-91.111 37.778h-497.778c-29.444 0-53.333-23.889-53.333-53.333v-888.889c0-29.444 23.889-53.333 53.333-53.333h746.667c29.444 0 53.333 23.889 53.333 53.333v640c0 29.444-17.222 70.556-37.778 91.111zM581.079 870.222c9.444-3.333 18.889-8.333 22.778-12.222l173.889-173.889c3.889-3.889 8.889-13.333 12.222-22.778h-208.889zM794.413 21.333h-711.111v853.333h426.667v-231.111c0-29.444 23.889-53.333 53.333-53.333h231.111zM225.524 501.333v-35.556c0-10 7.778-17.778 17.778-17.778h391.111c10 0 17.778 7.778 17.778 17.778v35.556c0 10-7.778 17.778-17.778 17.778h-391.111c-10 0-17.778-7.778-17.778-17.778zM634.413 376.889h-391.111c-10 0-17.778-7.778-17.778-17.778v-35.556c0-10 7.778-17.778 17.778-17.778h391.111c10 0 17.778 7.778 17.778 17.778v35.556c0 10-7.778 17.778-17.778 17.778zM634.413 234.667h-391.111c-10 0-17.778-7.778-17.778-17.778v-35.556c0-10 7.778-17.778 17.778-17.778h391.111c10 0 17.778 7.778 17.778 17.778v35.556c0 10-7.778 17.778-17.778 17.778z" />
<glyph unicode="&#xe910;" glyph-name="form-poll" horiz-adv-x="1094" d="M667.572 771.752c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM964.853 659.687c0 3.87-1.548 7.739-4.335 10.525l-45.506 45.507 45.507 45.507c2.787 2.786 4.335 6.656 4.335 10.525s-1.548 7.739-4.335 10.525l-21.051 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-45.507-45.507-45.507 45.507c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l45.507-45.507-45.507-45.507c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l21.051-21.051c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l45.507 45.507 45.507-45.507c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l21.051 21.051c2.787 2.786 4.335 6.656 4.335 10.525zM300.535 659.687c0 3.87-1.548 7.739-4.335 10.525l-45.506 45.507 45.507 45.507c2.787 2.786 4.335 6.656 4.335 10.525s-1.548 7.739-4.335 10.525l-21.051 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-45.507-45.507-45.507 45.507c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l45.507-45.507-45.507-45.507c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l21.051-21.051c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l45.507 45.507 45.507-45.507c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l21.051 21.051c2.787 2.786 4.335 6.656 4.335 10.525zM330.094 505.894c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM665.995 505.894c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM665.995 237.227c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM999.093 237.227c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM832.205 352.915h-31.571q-16.264 26.256-24.024 49.855-7.76 23.705-7.76 46.985t7.76 47.091q7.866 23.918 24.024 49.961h31.571q-13.606-25.193-20.41-49.323-6.803-24.024-6.803-47.516t6.697-47.623q6.803-24.13 20.516-49.43zM913.617 352.915q13.607 25.3 20.41 49.43t6.804 47.623-6.804 47.516q-6.803 24.13-20.41 49.323h31.571q16.158-26.044 23.918-49.961 7.866-23.811 7.866-47.091t-7.76-46.985q-7.76-23.599-24.024-49.855zM169.429 84.249h-31.571q-16.264 26.256-24.024 49.855-7.76 23.705-7.76 46.985t7.76 47.091q7.866 23.918 24.024 49.961h31.571q-13.606-25.193-20.41-49.323-6.803-24.024-6.803-47.516t6.697-47.623q6.803-24.13 20.516-49.43zM250.84 84.249q13.607 25.3 20.41 49.43t6.804 47.623-6.804 47.516q-6.803 24.13-20.41 49.323h31.571q16.158-26.044 23.918-49.961 7.866-23.811 7.866-47.091t-7.76-46.985q-7.76-23.599-24.024-49.855z" /> <glyph unicode="&#xe910;" glyph-name="form-poll" horiz-adv-x="1094" d="M667.572 771.752c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM964.853 659.687c0 3.87-1.548 7.739-4.335 10.525l-45.506 45.507 45.507 45.507c2.787 2.786 4.335 6.656 4.335 10.525s-1.548 7.739-4.335 10.525l-21.051 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-45.507-45.507-45.507 45.507c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l45.507-45.507-45.507-45.507c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l21.051-21.051c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l45.507 45.507 45.507-45.507c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l21.051 21.051c2.787 2.786 4.335 6.656 4.335 10.525zM300.535 659.687c0 3.87-1.548 7.739-4.335 10.525l-45.506 45.507 45.507 45.507c2.787 2.786 4.335 6.656 4.335 10.525s-1.548 7.739-4.335 10.525l-21.051 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-45.507-45.507-45.507 45.507c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l45.507-45.507-45.507-45.507c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l21.051-21.051c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l45.507 45.507 45.507-45.507c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l21.051 21.051c2.787 2.786 4.335 6.656 4.335 10.525zM330.094 505.894c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM665.995 505.894c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM665.995 237.227c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM999.093 237.227c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM832.205 352.915h-31.571q-16.264 26.256-24.024 49.855-7.76 23.705-7.76 46.985t7.76 47.091q7.866 23.918 24.024 49.961h31.571q-13.606-25.193-20.41-49.323-6.803-24.024-6.803-47.516t6.697-47.623q6.803-24.13 20.516-49.43zM913.617 352.915q13.607 25.3 20.41 49.43t6.804 47.623-6.804 47.516q-6.803 24.13-20.41 49.323h31.571q16.158-26.044 23.918-49.961 7.866-23.811 7.866-47.091t-7.76-46.985q-7.76-23.599-24.024-49.855zM169.429 84.249h-31.571q-16.264 26.256-24.024 49.855-7.76 23.705-7.76 46.985t7.76 47.091q7.866 23.918 24.024 49.961h31.571q-13.606-25.193-20.41-49.323-6.803-24.024-6.803-47.516t6.697-47.623q6.803-24.13 20.516-49.43zM250.84 84.249q13.607 25.3 20.41 49.43t6.804 47.623-6.804 47.516q-6.803 24.13-20.41 49.323h31.571q16.158-26.044 23.918-49.961 7.866-23.811 7.866-47.091t-7.76-46.985q-7.76-23.599-24.024-49.855z" />
<glyph unicode="&#xe911;" glyph-name="palette" d="M408.6 950c-198.8-38.8-359-198.6-398.2-396.8-74-374 263.4-652.8 517.6-613.4 82.4 12.8 122.8 109.2 85 183.4-46.2 90.8 19.8 196.8 121.8 196.8h159.4c71.6 0 129.6 59.2 129.8 130.6-1 315.2-287.8 563.2-615.4 499.4zM192 320c-35.4 0-64 28.6-64 64s28.6 64 64 64 64-28.6 64-64-28.6-64-64-64zM256 576c-35.4 0-64 28.6-64 64s28.6 64 64 64 64-28.6 64-64-28.6-64-64-64zM512 704c-35.4 0-64 28.6-64 64s28.6 64 64 64 64-28.6 64-64-28.6-64-64-64zM768 576c-35.4 0-64 28.6-64 64s28.6 64 64 64 64-28.6 64-64-28.6-64-64-64z" /> <glyph unicode="&#xe911;" glyph-name="file" horiz-adv-x="878" d="M827.745 734.666l-173.333 173.333c-20.556 20.556-61.667 37.778-91.111 37.778h-497.777c-29.444 0-53.333-23.889-53.333-53.333v-888.887c0-29.444 23.889-53.333 53.333-53.333h746.665c29.444 0 53.333 23.889 53.333 53.333v639.999c0 29.444-17.222 70.555-37.778 91.111zM581.079 870.221c9.444-3.333 18.889-8.333 22.778-12.222l173.889-173.889c3.889-3.889 8.889-13.333 12.222-22.778h-208.889zM794.412 21.334h-711.11v853.332h426.666v-231.111c0-29.444 23.889-53.333 53.333-53.333h231.111z" />
<glyph unicode="&#xe912;" glyph-name="folder-upload" d="M829.44 727.251h-296.84l-47.104 62.886c-25.923 34.066-66.406 55.898-111.999 56.139h-178.938c-77.457-0.137-140.211-62.891-140.348-140.335v-515.868c0.137-77.457 62.891-140.211 140.335-140.348h634.893c77.457 0.137 140.211 62.891 140.348 140.335v396.482c0 0.036 0 0.078 0 0.121 0 77.561-62.807 140.452-140.335 140.589h-0.013zM911.119 190.072c-0.068-45.083-36.597-81.611-81.673-81.679h-634.887c-45.083 0.068-81.611 36.597-81.679 81.673v515.862c0.068 45.083 36.597 81.611 81.673 81.679h178.906c26.48-0.030 50.004-12.656 64.908-32.207l0.146-0.199 47.104-62.765 17.709-24.094h326.114c45.125-0.069 81.679-36.665 81.679-81.799 0 0 0 0 0 0v0zM562.838 166.883h-102.039v203.957h-72.523l123.723 214.076 123.723-214.076h-72.885v-203.957z" /> <glyph unicode="&#xe912;" glyph-name="palette" d="M408.6 950c-198.8-38.8-359-198.6-398.2-396.8-74-374 263.4-652.8 517.6-613.4 82.4 12.8 122.8 109.2 85 183.4-46.2 90.8 19.8 196.8 121.8 196.8h159.4c71.6 0 129.6 59.2 129.8 130.6-1 315.2-287.8 563.2-615.4 499.4zM192 320c-35.4 0-64 28.6-64 64s28.6 64 64 64 64-28.6 64-64-28.6-64-64-64zM256 576c-35.4 0-64 28.6-64 64s28.6 64 64 64 64-28.6 64-64-28.6-64-64-64zM512 704c-35.4 0-64 28.6-64 64s28.6 64 64 64 64-28.6 64-64-28.6-64-64-64zM768 576c-35.4 0-64 28.6-64 64s28.6 64 64 64 64-28.6 64-64-28.6-64-64-64z" />
<glyph unicode="&#xe913;" glyph-name="add-bottom" d="M108.793 271.501c-15.312 0-27.996 12.684-27.996 27.996v55.992c0 15.312 12.684 28.006 27.996 28.006h225.414v-111.993zM108.793 495.478c-15.312 0-27.996 12.694-27.996 28.006v55.992c0 15.312 12.684 27.996 27.996 27.996h403.491v-111.993zM108.793 719.465c-15.312 0-27.996 12.694-27.996 28.006v55.992c0 15.312 12.684 27.996 27.996 27.996h615.968c15.312 0 27.996-12.684 27.996-27.996v-55.992c0-15.312-12.684-28.006-27.996-28.006zM943.202 287.839c0-19.465-15.792-35.257-35.258-35.257h-152.782v-152.782c0-19.465-15.792-35.257-35.258-35.257h-70.515c-19.465 0-35.257 15.792-35.257 35.257v152.782h-152.782c-19.465 0-35.257 15.792-35.257 35.257v70.515c0 19.465 15.792 35.258 35.257 35.258h152.782v152.782c0 19.465 15.792 35.258 35.257 35.258h70.515c19.465 0 35.258-15.792 35.258-35.258v-152.782h152.782c19.465 0 35.258-15.792 35.258-35.258z" /> <glyph unicode="&#xe913;" glyph-name="folder-upload" d="M829.44 727.251h-296.84l-47.104 62.886c-25.923 34.066-66.406 55.898-111.999 56.139h-178.938c-77.457-0.137-140.211-62.891-140.348-140.335v-515.868c0.137-77.457 62.891-140.211 140.335-140.348h634.893c77.457 0.137 140.211 62.891 140.348 140.335v396.482c0 0.036 0 0.078 0 0.121 0 77.561-62.807 140.452-140.335 140.589h-0.013zM911.119 190.072c-0.068-45.083-36.597-81.611-81.673-81.679h-634.887c-45.083 0.068-81.611 36.597-81.679 81.673v515.862c0.068 45.083 36.597 81.611 81.673 81.679h178.906c26.48-0.030 50.004-12.656 64.908-32.207l0.146-0.199 47.104-62.765 17.709-24.094h326.114c45.125-0.069 81.679-36.665 81.679-81.799 0 0 0 0 0 0v0zM562.838 166.883h-102.039v203.957h-72.523l123.723 214.076 123.723-214.076h-72.885v-203.957z" />
<glyph unicode="&#xe914;" glyph-name="add-top" d="M108.793 624.499c-15.312 0-27.996-12.684-27.996-27.996v-55.992c0-15.312 12.684-28.006 27.996-28.006h225.414v111.993zM108.793 400.522c-15.312 0-27.996-12.694-27.996-28.006v-55.992c0-15.312 12.684-27.996 27.996-27.996h403.491v111.993zM108.793 176.535c-15.312 0-27.996-12.694-27.996-28.006v-55.992c0-15.312 12.684-27.996 27.996-27.996h615.968c15.312 0 27.996 12.684 27.996 27.996v55.992c0 15.312-12.684 28.006-27.996 28.006zM943.202 608.161c0 19.465-15.792 35.257-35.258 35.257h-152.782v152.782c0 19.465-15.792 35.257-35.258 35.257h-70.515c-19.465 0-35.257-15.792-35.257-35.257v-152.782h-152.782c-19.465 0-35.257-15.792-35.257-35.257v-70.515c0-19.465 15.792-35.258 35.257-35.258h152.782v-152.782c0-19.465 15.792-35.258 35.257-35.258h70.515c19.465 0 35.258 15.792 35.258 35.258v152.782h152.782c19.465 0 35.258 15.792 35.258 35.258z" /> <glyph unicode="&#xe914;" glyph-name="add-bottom" d="M108.793 271.501c-15.312 0-27.996 12.684-27.996 27.996v55.992c0 15.312 12.684 28.006 27.996 28.006h225.414v-111.993zM108.793 495.478c-15.312 0-27.996 12.694-27.996 28.006v55.992c0 15.312 12.684 27.996 27.996 27.996h403.491v-111.993zM108.793 719.465c-15.312 0-27.996 12.694-27.996 28.006v55.992c0 15.312 12.684 27.996 27.996 27.996h615.968c15.312 0 27.996-12.684 27.996-27.996v-55.992c0-15.312-12.684-28.006-27.996-28.006zM943.202 287.839c0-19.465-15.792-35.257-35.258-35.257h-152.782v-152.782c0-19.465-15.792-35.257-35.258-35.257h-70.515c-19.465 0-35.257 15.792-35.257 35.257v152.782h-152.782c-19.465 0-35.257 15.792-35.257 35.257v70.515c0 19.465 15.792 35.258 35.257 35.258h152.782v152.782c0 19.465 15.792 35.258 35.257 35.258h70.515c19.465 0 35.258-15.792 35.258-35.258v-152.782h152.782c19.465 0 35.258-15.792 35.258-35.258z" />
<glyph unicode="&#xe915;" glyph-name="destroy" horiz-adv-x="1094" d="M191.671 946.511c-28.024 0-50.742-22.731-50.742-50.756v-399.384h-74.822c-29.561-0.003-53.524-23.966-53.527-53.527 0.025-29.545 23.982-53.484 53.527-53.487h174.773l-88.853-95.929 95.929-104.66-95.835-104.524 121.3-132.182 43.855 55.423-70.369 76.813 95.781 104.471-95.687 104.364 89.122 96.225h190.445l-88.853-95.929 95.929-104.66-95.781-104.524 121.246-132.182 43.855 55.423-70.369 76.813 95.781 104.471-95.687 104.364 89.122 96.225h190.445l-88.853-95.929 95.983-104.66-95.835-104.524 121.286-132.182 43.815 55.423-70.383 76.759 95.835 104.524-95.727 104.417 89.122 96.171h117.318c29.55-0.004 53.515 23.936 53.54 53.487-0.003 29.566-23.974 53.531-53.54 53.527h-71.728v162.501c0 28.024-16.394 67.15-35.958 86.714l-164.966 164.966c-19.564 19.564-58.69 35.958-86.714 35.958zM208.607 878.832h406.073v-219.96c0-28.024 22.745-50.769 50.769-50.769h219.96v-111.732h-676.802zM682.359 874.608c8.989-3.172 17.984-7.936 21.685-11.636l165.505-165.505c3.702-3.7 8.463-12.696 11.636-21.685h-198.826z" /> <glyph unicode="&#xe915;" glyph-name="add-top" d="M108.793 624.499c-15.312 0-27.996-12.684-27.996-27.996v-55.992c0-15.312 12.684-28.006 27.996-28.006h225.414v111.993zM108.793 400.522c-15.312 0-27.996-12.694-27.996-28.006v-55.992c0-15.312 12.684-27.996 27.996-27.996h403.491v111.993zM108.793 176.535c-15.312 0-27.996-12.694-27.996-28.006v-55.992c0-15.312 12.684-27.996 27.996-27.996h615.968c15.312 0 27.996 12.684 27.996 27.996v55.992c0 15.312-12.684 28.006-27.996 28.006zM943.202 608.161c0 19.465-15.792 35.257-35.258 35.257h-152.782v152.782c0 19.465-15.792 35.257-35.258 35.257h-70.515c-19.465 0-35.257-15.792-35.257-35.257v-152.782h-152.782c-19.465 0-35.257-15.792-35.257-35.257v-70.515c0-19.465 15.792-35.258 35.257-35.258h152.782v-152.782c0-19.465 15.792-35.258 35.257-35.258h70.515c19.465 0 35.258 15.792 35.258 35.258v152.782h152.782c19.465 0 35.258 15.792 35.258 35.258z" />
<glyph unicode="&#xe916;" glyph-name="form-list-check" horiz-adv-x="1094" d="M1012.362 763.843c0 8.831-7.792 16.623-16.623 16.623h-631.687c-8.831 0-16.623-7.792-16.623-16.623v-99.74c0-8.831 7.792-16.623 16.623-16.623h631.687c8.831 0 16.623 7.792 16.623 16.623zM1012.362 497.87c0 8.831-7.792 16.623-16.623 16.623h-631.687c-8.831 0-16.623-7.792-16.623-16.623v-99.74c0-8.831 7.792-16.623 16.623-16.623h631.687c8.831 0 16.623 7.792 16.623 16.623zM1012.362 231.897c0 8.831-7.792 16.623-16.623 16.623h-631.687c-8.831 0-16.623-7.792-16.623-16.623v-99.74c0-8.831 7.792-16.623 16.623-16.623h631.687c8.831 0 16.623 7.792 16.623 16.623zM279.136 239.834c0 22.077-17.911 39.988-39.988 39.988h-115.521c-22.077 0-39.988-17.911-39.988-39.988v-115.521c0-22.077 17.911-39.988 39.988-39.988h115.521c22.077 0 39.988 17.911 39.988 39.988zM307.396 779.338c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM307.396 513.228c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525z" /> <glyph unicode="&#xe916;" glyph-name="form-list-check" horiz-adv-x="1094" d="M1012.362 763.843c0 8.831-7.792 16.623-16.623 16.623h-631.687c-8.831 0-16.623-7.792-16.623-16.623v-99.74c0-8.831 7.792-16.623 16.623-16.623h631.687c8.831 0 16.623 7.792 16.623 16.623zM1012.362 497.87c0 8.831-7.792 16.623-16.623 16.623h-631.687c-8.831 0-16.623-7.792-16.623-16.623v-99.74c0-8.831 7.792-16.623 16.623-16.623h631.687c8.831 0 16.623 7.792 16.623 16.623zM1012.362 231.897c0 8.831-7.792 16.623-16.623 16.623h-631.687c-8.831 0-16.623-7.792-16.623-16.623v-99.74c0-8.831 7.792-16.623 16.623-16.623h631.687c8.831 0 16.623 7.792 16.623 16.623zM279.136 239.834c0 22.077-17.911 39.988-39.988 39.988h-115.521c-22.077 0-39.988-17.911-39.988-39.988v-115.521c0-22.077 17.911-39.988 39.988-39.988h115.521c22.077 0 39.988 17.911 39.988 39.988zM307.396 779.338c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM307.396 513.228c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525z" />
<glyph unicode="&#xe917;" glyph-name="form-grid-check" horiz-adv-x="1094" d="M645.063 506.257c0 22.077-17.911 39.988-39.988 39.988h-115.521c-22.077 0-39.988-17.911-39.988-39.988v-115.521c0-22.077 17.911-39.988 39.988-39.988h115.521c22.077 0 39.988 17.911 39.988 39.988zM1011.782 771.036c0 22.077-17.911 39.988-39.988 39.988h-115.521c-22.077 0-39.988-17.911-39.988-39.988v-115.521c0-22.077 17.911-39.988 39.988-39.988h115.521c22.077 0 39.988 17.911 39.988 39.988zM279.090 506.257c0 22.077-17.911 39.988-39.988 39.988h-115.521c-22.077 0-39.988-17.911-39.988-39.988v-115.521c0-22.077 17.911-39.988 39.988-39.988h115.521c22.077 0 39.988 17.911 39.988 39.988zM279.136 239.834c0 22.077-17.911 39.988-39.988 39.988h-115.521c-22.077 0-39.988-17.911-39.988-39.988v-115.521c0-22.077 17.911-39.988 39.988-39.988h115.521c22.077 0 39.988 17.911 39.988 39.988zM1011.753 239.834c0 22.077-17.911 39.988-39.988 39.988h-115.521c-22.077 0-39.988-17.911-39.988-39.988v-115.521c0-22.077 17.911-39.988 39.988-39.988h115.521c22.077 0 39.988 17.911 39.988 39.988zM1047.594 513.673c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM676.789 238.106c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM676.789 771.743c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM318.428 771.743c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525z" /> <glyph unicode="&#xe917;" glyph-name="form-grid-check" horiz-adv-x="1094" d="M645.063 506.257c0 22.077-17.911 39.988-39.988 39.988h-115.521c-22.077 0-39.988-17.911-39.988-39.988v-115.521c0-22.077 17.911-39.988 39.988-39.988h115.521c22.077 0 39.988 17.911 39.988 39.988zM1011.782 771.036c0 22.077-17.911 39.988-39.988 39.988h-115.521c-22.077 0-39.988-17.911-39.988-39.988v-115.521c0-22.077 17.911-39.988 39.988-39.988h115.521c22.077 0 39.988 17.911 39.988 39.988zM279.090 506.257c0 22.077-17.911 39.988-39.988 39.988h-115.521c-22.077 0-39.988-17.911-39.988-39.988v-115.521c0-22.077 17.911-39.988 39.988-39.988h115.521c22.077 0 39.988 17.911 39.988 39.988zM279.136 239.834c0 22.077-17.911 39.988-39.988 39.988h-115.521c-22.077 0-39.988-17.911-39.988-39.988v-115.521c0-22.077 17.911-39.988 39.988-39.988h115.521c22.077 0 39.988 17.911 39.988 39.988zM1011.753 239.834c0 22.077-17.911 39.988-39.988 39.988h-115.521c-22.077 0-39.988-17.911-39.988-39.988v-115.521c0-22.077 17.911-39.988 39.988-39.988h115.521c22.077 0 39.988 17.911 39.988 39.988zM1047.594 513.673c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM676.789 238.106c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM676.789 771.743c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525zM318.428 771.743c0 3.87-1.548 7.739-4.335 10.525l-21.050 21.051c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-101.54-101.694-45.507 45.662c-2.787 2.786-6.655 4.334-10.525 4.334s-7.739-1.548-10.525-4.334l-21.051-21.051c-2.787-2.786-4.335-6.656-4.335-10.525s1.548-7.739 4.335-10.525l77.083-77.083c2.787-2.786 6.655-4.334 10.525-4.334s7.739 1.548 10.525 4.334l133.116 133.116c2.787 2.786 4.335 6.656 4.335 10.525z" />
<glyph unicode="&#xe918;" glyph-name="form-grid-radio" horiz-adv-x="1094" d="M181.227 823.091c-60.1 0-109.091-48.991-109.091-109.091s48.991-109.091 109.091-109.091c60.1 0 108.955 48.991 108.955 109.091s-48.855 109.091-108.955 109.091zM545.091 823.091c-60.1 0-109.091-48.991-109.091-109.091s48.991-109.091 109.091-109.091c60.1 0 109.091 48.991 109.091 109.091s-48.991 109.091-109.091 109.091zM908.955 823.091c-60.1 0-109.091-48.991-109.091-109.091s48.991-109.091 109.091-109.091c60.1 0 109.091 48.991 109.091 109.091s-48.991 109.091-109.091 109.091zM181.227 747.318c19.623 0 33.364-13.695 33.364-33.318 0-19.583-13.943-33.5-33.364-33.5-19.381 0-33.5 14.119-33.5 33.5 0 19.421 13.917 33.318 33.5 33.318zM181.227 556.955c-60.1 0-109.091-48.809-109.091-108.909s48.991-109.091 109.091-109.091c60.1 0 108.955 48.991 108.955 109.091s-48.855 108.909-108.955 108.909zM545.091 556.955c-60.1 0-109.091-48.809-109.091-108.909s48.991-109.091 109.091-109.091c60.1 0 109.091 48.991 109.091 109.091s-48.991 108.909-109.091 108.909zM908.955 556.955c-60.1 0-109.091-48.809-109.091-108.909s48.991-109.091 109.091-109.091c60.1 0 109.091 48.991 109.091 109.091s-48.991 108.909-109.091 108.909zM909.045 481.364c19.623 0 33.318-13.74 33.318-33.364 0-19.583-13.897-33.5-33.318-33.5-19.381 0-33.5 14.119-33.5 33.5 0 19.421 13.917 33.364 33.5 33.364zM181.227 291.045c-60.1 0-109.091-48.855-109.091-108.955s48.991-109.091 109.091-109.091c60.1 0 108.955 48.991 108.955 109.091s-48.855 108.955-108.955 108.955zM545.091 291.045c-60.1 0-109.091-48.855-109.091-108.955s48.991-109.091 109.091-109.091c60.1 0 109.091 48.991 109.091 109.091s-48.991 108.955-109.091 108.955zM908.955 291.045c-60.1 0-109.091-48.855-109.091-108.955s48.991-109.091 109.091-109.091c60.1 0 109.091 48.991 109.091 109.091s-48.991 108.955-109.091 108.955zM545.318 214c19.623 0 33.318-13.695 33.318-33.318 0-19.583-13.897-33.5-33.318-33.5-19.381 0-33.5 14.119-33.5 33.5 0 19.421 13.917 33.318 33.5 33.318z" /> <glyph unicode="&#xe918;" glyph-name="form-grid-radio" horiz-adv-x="1094" d="M181.227 823.091c-60.1 0-109.091-48.991-109.091-109.091s48.991-109.091 109.091-109.091c60.1 0 108.955 48.991 108.955 109.091s-48.855 109.091-108.955 109.091zM545.091 823.091c-60.1 0-109.091-48.991-109.091-109.091s48.991-109.091 109.091-109.091c60.1 0 109.091 48.991 109.091 109.091s-48.991 109.091-109.091 109.091zM908.955 823.091c-60.1 0-109.091-48.991-109.091-109.091s48.991-109.091 109.091-109.091c60.1 0 109.091 48.991 109.091 109.091s-48.991 109.091-109.091 109.091zM181.227 747.318c19.623 0 33.364-13.695 33.364-33.318 0-19.583-13.943-33.5-33.364-33.5-19.381 0-33.5 14.119-33.5 33.5 0 19.421 13.917 33.318 33.5 33.318zM181.227 556.955c-60.1 0-109.091-48.809-109.091-108.909s48.991-109.091 109.091-109.091c60.1 0 108.955 48.991 108.955 109.091s-48.855 108.909-108.955 108.909zM545.091 556.955c-60.1 0-109.091-48.809-109.091-108.909s48.991-109.091 109.091-109.091c60.1 0 109.091 48.991 109.091 109.091s-48.991 108.909-109.091 108.909zM908.955 556.955c-60.1 0-109.091-48.809-109.091-108.909s48.991-109.091 109.091-109.091c60.1 0 109.091 48.991 109.091 109.091s-48.991 108.909-109.091 108.909zM909.045 481.364c19.623 0 33.318-13.74 33.318-33.364 0-19.583-13.897-33.5-33.318-33.5-19.381 0-33.5 14.119-33.5 33.5 0 19.421 13.917 33.364 33.5 33.364zM181.227 291.045c-60.1 0-109.091-48.855-109.091-108.955s48.991-109.091 109.091-109.091c60.1 0 108.955 48.991 108.955 109.091s-48.855 108.955-108.955 108.955zM545.091 291.045c-60.1 0-109.091-48.855-109.091-108.955s48.991-109.091 109.091-109.091c60.1 0 109.091 48.991 109.091 109.091s-48.991 108.955-109.091 108.955zM908.955 291.045c-60.1 0-109.091-48.855-109.091-108.955s48.991-109.091 109.091-109.091c60.1 0 109.091 48.991 109.091 109.091s-48.991 108.955-109.091 108.955zM545.318 214c19.623 0 33.318-13.695 33.318-33.318 0-19.583-13.897-33.5-33.318-33.5-19.381 0-33.5 14.119-33.5 33.5 0 19.421 13.917 33.318 33.5 33.318z" />
@ -38,4 +38,5 @@
<glyph unicode="&#xe91c;" glyph-name="form-text" horiz-adv-x="1094" d="M1012.362 481.247c0 18.182-15.065 33.247-33.247 33.247h-864.413c-18.182 0-33.247-15.065-33.247-33.247v-66.493c0-18.182 15.065-33.247 33.247-33.247h864.413c18.182 0 33.247 15.065 33.247 33.247z" /> <glyph unicode="&#xe91c;" glyph-name="form-text" horiz-adv-x="1094" d="M1012.362 481.247c0 18.182-15.065 33.247-33.247 33.247h-864.413c-18.182 0-33.247-15.065-33.247-33.247v-66.493c0-18.182 15.065-33.247 33.247-33.247h864.413c18.182 0 33.247 15.065 33.247 33.247z" />
<glyph unicode="&#xe91d;" glyph-name="form-list-ordered" horiz-adv-x="1094" d="M279.377 71.897c0 35.844-22.857 62.857-57.662 71.169l49.351 59.74v45.714h-172.987v-78.961h55.065v27.532c16.623 0 33.766 1.039 50.389 1.039v-0.52c-22.338-20.259-39.48-46.753-58.182-70.649l13.506-29.091c21.299 1.558 54.545 0 54.545-29.091 0-20.779-19.221-29.61-37.402-29.61-19.74 0-41.039 10.39-55.065 23.376l-29.61-45.714c23.377-23.377 56.623-34.286 89.35-34.286 54.026 0 98.701 32.208 98.701 89.35zM280.416 397.611h-54.545v-31.169h-65.974c1.558 40.519 114.285 57.662 114.285 134.545 0 51.428-41.558 80-89.87 80-39.48 0-74.805-20.26-91.948-56.104l44.156-30.649c8.831 14.545 23.896 30.13 42.078 30.13 17.143 0 28.052-9.351 28.052-27.013 0-43.636-117.402-58.182-117.402-154.285 0-9.351 1.558-18.701 3.117-28.052h188.051zM1012.362 231.897c0 9.351-7.792 16.623-16.623 16.623h-631.687c-9.351 0-16.623-7.273-16.623-16.623v-99.74c0-8.831 7.273-16.623 16.623-16.623h631.687c8.831 0 16.623 7.792 16.623 16.623zM280.936 698.908h-56.104v209.87h-55.065l-70.649-65.974 36.883-39.48c9.87 8.831 20.26 16.623 25.974 28.052h1.039v-6.234c0-42.078-0.52-84.156-0.52-126.233h-55.584v-51.428h174.025zM1012.362 497.87c0 9.351-7.792 16.623-16.623 16.623h-631.687c-9.351 0-16.623-7.273-16.623-16.623v-99.74c0-8.831 7.273-16.623 16.623-16.623h631.687c8.831 0 16.623 7.792 16.623 16.623zM1012.362 763.843c0 8.831-7.792 16.623-16.623 16.623h-631.687c-9.351 0-16.623-7.792-16.623-16.623v-99.74c0-8.831 7.273-16.623 16.623-16.623h631.687c8.831 0 16.623 7.792 16.623 16.623z" /> <glyph unicode="&#xe91d;" glyph-name="form-list-ordered" horiz-adv-x="1094" d="M279.377 71.897c0 35.844-22.857 62.857-57.662 71.169l49.351 59.74v45.714h-172.987v-78.961h55.065v27.532c16.623 0 33.766 1.039 50.389 1.039v-0.52c-22.338-20.259-39.48-46.753-58.182-70.649l13.506-29.091c21.299 1.558 54.545 0 54.545-29.091 0-20.779-19.221-29.61-37.402-29.61-19.74 0-41.039 10.39-55.065 23.376l-29.61-45.714c23.377-23.377 56.623-34.286 89.35-34.286 54.026 0 98.701 32.208 98.701 89.35zM280.416 397.611h-54.545v-31.169h-65.974c1.558 40.519 114.285 57.662 114.285 134.545 0 51.428-41.558 80-89.87 80-39.48 0-74.805-20.26-91.948-56.104l44.156-30.649c8.831 14.545 23.896 30.13 42.078 30.13 17.143 0 28.052-9.351 28.052-27.013 0-43.636-117.402-58.182-117.402-154.285 0-9.351 1.558-18.701 3.117-28.052h188.051zM1012.362 231.897c0 9.351-7.792 16.623-16.623 16.623h-631.687c-9.351 0-16.623-7.273-16.623-16.623v-99.74c0-8.831 7.273-16.623 16.623-16.623h631.687c8.831 0 16.623 7.792 16.623 16.623zM280.936 698.908h-56.104v209.87h-55.065l-70.649-65.974 36.883-39.48c9.87 8.831 20.26 16.623 25.974 28.052h1.039v-6.234c0-42.078-0.52-84.156-0.52-126.233h-55.584v-51.428h174.025zM1012.362 497.87c0 9.351-7.792 16.623-16.623 16.623h-631.687c-9.351 0-16.623-7.273-16.623-16.623v-99.74c0-8.831 7.273-16.623 16.623-16.623h631.687c8.831 0 16.623 7.792 16.623 16.623zM1012.362 763.843c0 8.831-7.792 16.623-16.623 16.623h-631.687c-9.351 0-16.623-7.792-16.623-16.623v-99.74c0-8.831 7.273-16.623 16.623-16.623h631.687c8.831 0 16.623 7.792 16.623 16.623z" />
<glyph unicode="&#xe91e;" glyph-name="form-poll-maybe" horiz-adv-x="1094" d="M856.492 569.333c0 9.987-3.996 19.973-11.187 27.163l-54.325 54.327c-7.191 7.191-17.175 11.185-27.163 11.185s-19.972-3.995-27.163-11.185l-262.048-262.447-117.442 117.841c-7.191 7.19-17.175 11.185-27.163 11.185s-19.972-3.995-27.163-11.185l-54.327-54.327c-7.191-7.191-11.187-17.177-11.187-27.163s3.995-19.973 11.187-27.163l198.932-198.932c7.191-7.191 17.175-11.185 27.163-11.185s19.972 3.995 27.163 11.185l343.538 343.537c7.192 7.191 11.187 17.177 11.187 27.163zM65.903 444.364q0 120.454 35 225.454 35.454 105 101.818 184.090h73.636q-65.454-87.727-98.636-192.727-32.727-105-32.727-215.908 0-109.091 33.636-213.181t96.818-189.999h-72.727q-66.818 77.273-101.818 180.454t-35 221.818zM1027.916 444.364q0-119.545-35.454-222.727-35-103.182-101.363-179.545h-72.727q63.182 85.454 96.818 189.545 33.636 104.545 33.636 213.636 0 110.909-33.182 215.908-32.727 105-98.182 192.727h73.636q66.818-79.545 101.818-184.999 35-105 35-224.545z" /> <glyph unicode="&#xe91e;" glyph-name="form-poll-maybe" horiz-adv-x="1094" d="M856.492 569.333c0 9.987-3.996 19.973-11.187 27.163l-54.325 54.327c-7.191 7.191-17.175 11.185-27.163 11.185s-19.972-3.995-27.163-11.185l-262.048-262.447-117.442 117.841c-7.191 7.19-17.175 11.185-27.163 11.185s-19.972-3.995-27.163-11.185l-54.327-54.327c-7.191-7.191-11.187-17.177-11.187-27.163s3.995-19.973 11.187-27.163l198.932-198.932c7.191-7.191 17.175-11.185 27.163-11.185s19.972 3.995 27.163 11.185l343.538 343.537c7.192 7.191 11.187 17.177 11.187 27.163zM65.903 444.364q0 120.454 35 225.454 35.454 105 101.818 184.090h73.636q-65.454-87.727-98.636-192.727-32.727-105-32.727-215.908 0-109.091 33.636-213.181t96.818-189.999h-72.727q-66.818 77.273-101.818 180.454t-35 221.818zM1027.916 444.364q0-119.545-35.454-222.727-35-103.182-101.363-179.545h-72.727q63.182 85.454 96.818 189.545 33.636 104.545 33.636 213.636 0 110.909-33.182 215.908-32.727 105-98.182 192.727h73.636q66.818-79.545 101.818-184.999 35-105 35-224.545z" />
<glyph unicode="&#xe91f;" glyph-name="destroy" horiz-adv-x="1094" d="M191.671 946.511c-28.024 0-50.742-22.731-50.742-50.756v-399.384h-74.822c-29.561-0.003-53.524-23.966-53.527-53.527 0.025-29.545 23.982-53.484 53.527-53.487h174.773l-88.853-95.929 95.929-104.66-95.835-104.524 121.3-132.182 43.855 55.423-70.369 76.813 95.781 104.471-95.687 104.364 89.122 96.225h190.445l-88.853-95.929 95.929-104.66-95.781-104.524 121.246-132.182 43.855 55.423-70.369 76.813 95.781 104.471-95.687 104.364 89.122 96.225h190.445l-88.853-95.929 95.983-104.66-95.835-104.524 121.286-132.182 43.815 55.423-70.383 76.759 95.835 104.524-95.727 104.417 89.122 96.171h117.318c29.55-0.004 53.515 23.936 53.54 53.487-0.003 29.566-23.974 53.531-53.54 53.527h-71.728v162.501c0 28.024-16.394 67.15-35.958 86.714l-164.966 164.966c-19.564 19.564-58.69 35.958-86.714 35.958zM208.607 878.832h406.073v-219.96c0-28.024 22.745-50.769 50.769-50.769h219.96v-111.732h-676.802zM682.359 874.608c8.989-3.172 17.984-7.936 21.685-11.636l165.505-165.505c3.702-3.7 8.463-12.696 11.636-21.685h-198.826z" />
</font></defs></svg> </font></defs></svg>

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 40 KiB

@ -1,10 +1,10 @@
@font-face { @font-face {
font-family: 'cptools'; font-family: 'cptools';
src: url('fonts/cptools.eot?chd5a1'); src: url('fonts/cptools.eot?6tk5ck');
src: url('fonts/cptools.eot?chd5a1#iefix') format('embedded-opentype'), src: url('fonts/cptools.eot?6tk5ck#iefix') format('embedded-opentype'),
url('fonts/cptools.ttf?chd5a1') format('truetype'), url('fonts/cptools.ttf?6tk5ck') format('truetype'),
url('fonts/cptools.woff?chd5a1') format('woff'), url('fonts/cptools.woff?6tk5ck') format('woff'),
url('fonts/cptools.svg?chd5a1#cptools') format('svg'); url('fonts/cptools.svg?6tk5ck#cptools') format('svg');
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
font-display: block; font-display: block;
@ -14,7 +14,7 @@
/* use !important to prevent issues with browser extensions that change fonts */ /* use !important to prevent issues with browser extensions that change fonts */
font-family: 'cptools' !important; font-family: 'cptools' !important;
display: inline-block; display: inline-block;
speak: none; speak: never;
font-style: normal; font-style: normal;
font-weight: normal; font-weight: normal;
font-variant: normal; font-variant: normal;
@ -26,6 +26,9 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.cptools-form-conditional:before {
content: "\e900";
}
.cptools-form-poll:before { .cptools-form-poll:before {
content: "\e910"; content: "\e910";
} }
@ -57,65 +60,65 @@
content: "\e91d"; content: "\e91d";
} }
.cptools-folder-no-color:before { .cptools-folder-no-color:before {
content: "\e900"; content: "\e901";
} }
.cptools-whiteboard:before { .cptools-whiteboard:before {
content: "\e901"; content: "\e902";
} }
.cptools-new-template:before { .cptools-new-template:before {
content: "\e902"; content: "\e903";
} }
.cptools-shared-folder:before { .cptools-shared-folder:before {
content: "\e903"; content: "\e904";
} }
.cptools-file-upload:before { .cptools-file-upload:before {
content: "\e904"; content: "\e905";
} }
.cptools-template:before { .cptools-template:before {
content: "\e905"; content: "\e906";
} }
.cptools-poll:before { .cptools-poll:before {
content: "\e906"; content: "\e907";
} }
.cptools-slide:before { .cptools-slide:before {
content: "\e907"; content: "\e908";
} }
.cptools-sheet:before { .cptools-sheet:before {
content: "\e908"; content: "\e909";
} }
.cptools-folder-open:before { .cptools-folder-open:before {
content: "\e909"; content: "\e90a";
} }
.cptools-kanban:before { .cptools-kanban:before {
content: "\e90a"; content: "\e90b";
} }
.cptools-folder:before { .cptools-folder:before {
content: "\e90b"; content: "\e90c";
} }
.cptools-shared-folder-open:before { .cptools-shared-folder-open:before {
content: "\e90c"; content: "\e90d";
} }
.cptools-code:before { .cptools-code:before {
content: "\e90d"; content: "\e90e";
} }
.cptools-richtext:before { .cptools-richtext:before {
content: "\e90e"; content: "\e90f";
} }
.cptools-file:before { .cptools-file:before {
content: "\e90f"; content: "\e911";
} }
.cptools-palette:before { .cptools-palette:before {
content: "\e911"; content: "\e912";
} }
.cptools-folder-upload:before { .cptools-folder-upload:before {
content: "\e912"; content: "\e913";
} }
.cptools-add-bottom:before { .cptools-add-bottom:before {
content: "\e913"; content: "\e914";
} }
.cptools-add-top:before { .cptools-add-top:before {
content: "\e914"; content: "\e915";
} }
.cptools-destroy:before { .cptools-destroy:before {
content: "\e915"; content: "\e91f";
} }

@ -1,6 +1,6 @@
define([ define([
'jquery', 'jquery',
'/bower_components/chainpad-listmap/chainpad-listmap.js', 'chainpad-listmap',
'/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad-crypto/crypto.js',
'/common/common-util.js', '/common/common-util.js',
'/common/outer/network-config.js', '/common/outer/network-config.js',

@ -105,7 +105,7 @@ define([
var imprintUrl = AppConfig.imprint && (typeof(AppConfig.imprint) === "boolean" ? var imprintUrl = AppConfig.imprint && (typeof(AppConfig.imprint) === "boolean" ?
'/imprint.html' : AppConfig.imprint); '/imprint.html' : AppConfig.imprint);
Pages.versionString = "v4.10.0"; Pages.versionString = "v4.11.0";
// used for the about menu // used for the about menu

@ -166,6 +166,9 @@
color: @cryptpad_text_col; color: @cryptpad_text_col;
text-decoration: underline; text-decoration: underline;
} }
pre.cp-link-preview {
color: @cryptpad_text_col;
}
.cp-info-menu-container { .cp-info-menu-container {
.logo-block { .logo-block {
text-align: center; text-align: center;

@ -4,7 +4,11 @@
@width: 30px @width: 30px
) { ) {
@avatar-width: @width; @avatar-width: @width;
@avatar-font-size: @width / 1.2; @avatar-font-size: @width / 1.8;
// scale animal avatar to be somewhat larger, because:
// 1. emojis are wider than most latin characters
// 2. they should occupy the width of two average characters
@avatar-font-size-animal: @avatar-font-size * (6/5);
} }
.avatar_main(@width: 30px) { .avatar_main(@width: 30px) {
--LessLoader_require: LessLoader_currentFile(); --LessLoader_require: LessLoader_currentFile();
@ -40,7 +44,9 @@
color: @cp_avatar-fg; color: @cp_avatar-fg;
font-size: @avatar-font-size; font-size: @avatar-font-size;
font-size: var(--avatar-font-size); font-size: var(--avatar-font-size);
text-transform: capitalize; .animal {
font-size: @avatar-font-size-animal;
}
} }
media-tag { media-tag {
min-height: @avatar-width; min-height: @avatar-width;

@ -50,4 +50,56 @@
} }
} }
} }
.cp-charts-cell {
border: 1px solid @cp_form-border;
display: table-cell;
padding: 5px 10px;
background: @cp_form-bg2;
}
.cp-form-results-type-radio {
.cp-form-results-type-multiradio-data {
display: flex;
flex-flow: column;
}
.cp-form-results-type-radio-data {
display: table-row;
border: 1px solid @cp_form-border;
& > span {
.cp-charts-cell();
}
}
}
.cp-charts.cp-bar-table, .cp-charts.cp-text-table {
display: table;
width: 100%;
.cp-charts-row {
display: table-row;
border: 1px solid @cp_form-border;
&.full {
display: flex;
flex-flow: column;
}
& > span {
.cp-charts-cell();
display: table-cell;
&.cp-value {
min-width: 200px;
}
&.cp-bar-container {
width: 99%;
padding: 0px;
position: relative;
.cp-bar {
position: absolute;
background: @cryptpad_color_brand;
height: 100%;
}
}
}
}
}
} }

@ -68,6 +68,25 @@
@cryptpad_color_yellow_fader: fade(#FFE69C, 15%); // not in light theme @cryptpad_color_yellow_fader: fade(#FFE69C, 15%); // not in light theme
@cryptpad_color_lighter_blue: #d2e1f2; @cryptpad_color_lighter_blue: #d2e1f2;
@cp_palette:
#FFD4D4,
#FFDECA,
#FFE69C,
#DBFFB7,
#AFFDC2,
#C9FFFE,
#C8D6FF,
#E4CAFF;
@cp_palette-dark:
darken(desaturate(extract(@cp_palette, 1),60%), 60%),
darken(desaturate(extract(@cp_palette, 2),60%), 60%),
darken(desaturate(extract(@cp_palette, 3),55%), 60%),
darken(desaturate(extract(@cp_palette, 4),55%), 70%),
darken(desaturate(extract(@cp_palette, 5),60%), 65%),
darken(desaturate(extract(@cp_palette, 6),60%), 70%),
darken(desaturate(extract(@cp_palette, 7),60%), 60%),
darken(desaturate(extract(@cp_palette, 8),70%), 60%);
@cryptpad_color_link:@cryptpad_color_brand_300; @cryptpad_color_link:@cryptpad_color_brand_300;
// Premium plans colors // Premium plans colors
@ -353,15 +372,7 @@
@cp_kanban-add-hover: fade(@cryptpad_color_black, 10%); @cp_kanban-add-hover: fade(@cryptpad_color_black, 10%);
@cp_kanban-trash-bg: @cryptpad_color_warn_red; @cp_kanban-trash-bg: @cryptpad_color_warn_red;
@cp_kanban-color0: @cryptpad_color_grey_600; @cp_kanban-color0: @cryptpad_color_grey_600;
@cp_kanban-colors: @cp_kanban-colors: @cp_palette-dark;
darken(desaturate(#FFD4D4,60%), 60%),
darken(desaturate(#FFDECA,60%), 60%),
darken(desaturate(#FFE69C,55%), 60%),
darken(desaturate(#DBFFB7,55%), 70%),
darken(desaturate(#AFFDC2,60%), 65%),
darken(desaturate(#C9FFFE,60%), 70%),
darken(desaturate(#C8D6FF,60%), 60%),
darken(desaturate(#E4CAFF,70%), 60%);
// Notifications // Notifications
@cp_notif-hover: fade(@cryptpad_color_black, 10%); @cp_notif-hover: fade(@cryptpad_color_black, 10%);
@ -438,3 +449,5 @@
@cp_form-poll-maybe: @cryptpad_color_grey_700; @cp_form-poll-maybe: @cryptpad_color_grey_700;
@cp_form-poll-yes-color: @cryptpad_color_green; @cp_form-poll-yes-color: @cryptpad_color_green;
@cp_form-invalid: @cryptpad_color_light_red; @cp_form-invalid: @cryptpad_color_light_red;
@cp_form-palette: @cp_palette-dark;
@cp_form-palette2: @cp_palette;

@ -67,6 +67,25 @@
@cryptpad_color_yellow_fade: fade(#FFE69C, 50%); // different from dark @cryptpad_color_yellow_fade: fade(#FFE69C, 50%); // different from dark
@cryptpad_color_lighter_blue: #d2e1f2; @cryptpad_color_lighter_blue: #d2e1f2;
@cp_palette:
#FFD4D4,
#FFDECA,
#FFE69C,
#DBFFB7,
#AFFDC2,
#C9FFFE,
#C8D6FF,
#E4CAFF;
@cp_palette-dark:
darken(extract(@cp_palette, 1), 50%),
darken(extract(@cp_palette, 2), 51%),
darken(extract(@cp_palette, 3), 52%),
darken(extract(@cp_palette, 4), 61%),
darken(extract(@cp_palette, 5), 57%),
darken(extract(@cp_palette, 6), 65%),
darken(extract(@cp_palette, 7), 50%),
darken(extract(@cp_palette, 8), 50%);
@cryptpad_color_link: @cryptpad_color_brand; @cryptpad_color_link: @cryptpad_color_brand;
// Premium plans colors // Premium plans colors
@ -299,7 +318,7 @@
@cp_usergrid-selected-fg: @cryptpad_color_white; @cp_usergrid-selected-fg: @cryptpad_color_white;
// Other // Other
@cp_shadow-color: fade(@cryptpad_color_black, 40%); @cp_shadow-color: fade(@cryptpad_color_black, 30%);
// Apps // Apps
@cp_app-bg: @cryptpad_color_grey_100; @cp_app-bg: @cryptpad_color_grey_100;
@ -352,15 +371,7 @@
@cp_kanban-add-hover: fade(@cryptpad_color_black, 10%); @cp_kanban-add-hover: fade(@cryptpad_color_black, 10%);
@cp_kanban-trash-bg: @cryptpad_color_warn_red; @cp_kanban-trash-bg: @cryptpad_color_warn_red;
@cp_kanban-color0: @cryptpad_color_grey_400; @cp_kanban-color0: @cryptpad_color_grey_400;
@cp_kanban-colors: @cp_kanban-colors: @cp_palette;
#FFD4D4,
#FFDECA,
#FFE69C,
#DBFFB7,
#AFFDC2,
#C9FFFE,
#C8D6FF,
#E4CAFF;
// Notifications // Notifications
@cp_notif-hover: fade(@cryptpad_color_black, 10%); @cp_notif-hover: fade(@cryptpad_color_black, 10%);
@ -428,8 +439,8 @@
@cp_calendar-now-fg: @cryptpad_color_grey_200; @cp_calendar-now-fg: @cryptpad_color_grey_200;
// Forms // Forms
@cp_form-bg1: @cryptpad_color_grey_200; @cp_form-bg1: @cryptpad_color_grey_50;
@cp_form-bg2: @cryptpad_color_grey_100; @cp_form-bg2: @cryptpad_color_grey_200;
@cp_form-border: @cryptpad_color_grey_200; @cp_form-border: @cryptpad_color_grey_200;
@cp_form-poll-color: @cryptpad_color_grey_800; @cp_form-poll-color: @cryptpad_color_grey_800;
@cp_form-poll-no: fade(@cryptpad_color_light_red, 75%); @cp_form-poll-no: fade(@cryptpad_color_light_red, 75%);
@ -437,3 +448,5 @@
@cp_form-poll-maybe: @cryptpad_color_grey_300; @cp_form-poll-maybe: @cryptpad_color_grey_300;
@cp_form-poll-yes-color: @cryptpad_color_green; @cp_form-poll-yes-color: @cryptpad_color_green;
@cp_form-invalid: @cryptpad_color_red; @cp_form-invalid: @cryptpad_color_red;
@cp_form-palette: @cp_palette;
@cp_form-palette2: @cp_palette-dark;

@ -364,9 +364,9 @@
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
min-height: 20px; min-height: 25px;
height: 20px; height: 25px;
line-height: 20px; line-height: 25px;
max-width: 100%; max-width: 100%;
} }
.fa, .cptools { .fa, .cptools {

@ -112,8 +112,10 @@
border-radius: 0; border-radius: 0;
transition: none; transition: none;
.fa, .cptools { i, .fa, .cptools {
margin-right: 5px; &:not(.nomargin) {
margin-right: 5px;
}
} }
.cptools { .cptools {
vertical-align: middle; vertical-align: middle;

@ -273,4 +273,29 @@
} }
} }
} }
#cp-upload-preview-container {
max-width: 100%;
max-height: 300px;
overflow: auto;
margin-bottom: 15px;
// FIXME these styles yield weird results for tall, thin images
// maybe img { object-fit: contain; } or scale-down are options
// but they have problems too
media-tag {
max-width: 100%;
iframe {
// pdfs don't take the full width unless we tell them to
width: 100%;
}
& > * {
max-width: 100%;
}
}
}
input#cp-app-drive-link-url {
&.cp-input-invalid {
border: 2px solid @cryptpad_color_red;
color: @cp_form-invalid;
}
}
} }

@ -69,7 +69,6 @@
background: @cp_sidebar-right-bg; background: @cp_sidebar-right-bg;
color: @cp_sidebar-right-fg; color: @cp_sidebar-right-fg;
overflow: auto; overflow: auto;
padding-bottom: 200px;
// Following rules are only in settings // Following rules are only in settings
.cp-sidebarlayout-element { .cp-sidebarlayout-element {

@ -532,7 +532,13 @@
&> button { &> button {
height: @toolbar_line-height; height: @toolbar_line-height;
width: @toolbar_line-height; width: @toolbar_line-height;
span { font-size: unset; } span {
.avatar_vars(36px);
font-size: @avatar-font-size;
.animal {
font-size: @avatar-font-size-animal;
}
}
} }
&> button.cp-avatar.cp-avatar { &> button.cp-avatar.cp-avatar {
media-tag { media-tag {
@ -855,10 +861,14 @@
span { span {
text-align: center; text-align: center;
width: 100%; width: 100%;
font-size: 48px; .avatar_vars(72px);
font-size: @avatar-font-size;
display: inline-flex; display: inline-flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
.animal {
font-size: @avatar-font-size-animal;
}
} }
&.cp-avatar { &.cp-avatar {
.avatar_main(64px); .avatar_main(64px);

@ -2,7 +2,7 @@
# to work with CryptPad. This example WILL NOT WORK AS IS. For best results, # to work with CryptPad. This example WILL NOT WORK AS IS. For best results,
# compare the sections of this configuration file against a working CryptPad # compare the sections of this configuration file against a working CryptPad
# installation (http server by the Nodejs process). If you are using CryptPad # installation (http server by the Nodejs process). If you are using CryptPad
# in production, contact sales@cryptpad.fr # in production and require professional support please contact sales@cryptpad.fr
server { server {
listen 443 ssl http2; listen 443 ssl http2;

2
package-lock.json generated

@ -1,6 +1,6 @@
{ {
"name": "cryptpad", "name": "cryptpad",
"version": "4.10.0", "version": "4.11.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

@ -1,7 +1,7 @@
{ {
"name": "cryptpad", "name": "cryptpad",
"description": "realtime collaborative visual editor with zero knowlege server", "description": "realtime collaborative visual editor with zero knowlege server",
"version": "4.10.0", "version": "4.11.0",
"license": "AGPL-3.0+", "license": "AGPL-3.0+",
"repository": { "repository": {
"type": "git", "type": "git",
@ -45,8 +45,8 @@
"lint:js": "jshint --config .jshintrc --exclude-path .jshintignore .", "lint:js": "jshint --config .jshintrc --exclude-path .jshintignore .",
"lint:server": "jshint --config .jshintrc lib", "lint:server": "jshint --config .jshintrc lib",
"lint:less": "./node_modules/lesshint/bin/lesshint -c ./.lesshintrc ./customize.dist/src/less2/", "lint:less": "./node_modules/lesshint/bin/lesshint -c ./.lesshintrc ./customize.dist/src/less2/",
"lint:translations": "node ./scripts/lint-translations.js", "lint:translations": "node ./scripts/translations/lint-translations.js",
"unused-translations": "node ./scripts/unused-translations.js", "unused-translations": "node ./scripts/translations/unused-translations.js",
"test": "node scripts/TestSelenium.js", "test": "node scripts/TestSelenium.js",
"test-rpc": "cd scripts/tests && node test-rpc", "test-rpc": "cd scripts/tests && node test-rpc",
"template": "cd customize.dist/src && for page in ../index.html ../privacy.html ../terms.html ../contact.html ../what-is-cryptpad.html ../features.html ../../www/login/index.html ../../www/register/index.html ../../www/user/index.html;do echo $page; cp template.html $page; done;", "template": "cd customize.dist/src && for page in ../index.html ../privacy.html ../terms.html ../contact.html ../what-is-cryptpad.html ../features.html ../../www/login/index.html ../../www/register/index.html ../../www/user/index.html;do echo $page; cp template.html $page; done;",

@ -0,0 +1,111 @@
var Assert = require("assert");
var Util = require("../../lib/common-util");
var addIfAbsent = function (A, e) {
if (A.includes(e)) { return; }
A.push(e);
};
var findDuplicates = function (map) {
var keys = Object.keys(map);
var duplicates = {};
var markDuplicate = function (value, key1, key2) {
//console.log("[%s] === [%s] (%s)", key1, key2, value);
if (!Array.isArray(duplicates[value])) {
duplicates[value] = [];
}
addIfAbsent(duplicates[value], key1);
addIfAbsent(duplicates[value], key2);
};
keys.forEach(function (key) {
var value = map[key];
//var duplicates = [];
keys.forEach(function (key2) {
if (key === key2) { return; }
var value2 = map[key2];
if (value === value2) {
markDuplicate(value, key, key2);
}
});
});
var temp = {};
// sort keys and construct a new index using the first key in the sorted array
Object.keys(duplicates).forEach(function (key) {
var val = duplicates[key]; // should be an array
val.sort(); // default js sort
var new_key = val[0];
temp[new_key] = val;
});
var canonical = {};
Object.keys(temp).sort().forEach(function (key) {
canonical[key] = temp[key];
});
return canonical;
};
/*
var logDuplicates = function (duplicates) {
// indicate which strings are duplicated and could potentially be changed to use one key
Object.keys(duplicates).forEach(function (val) {
console.log('\"%s\" => %s', val, JSON.stringify(duplicates[val]));
});
};
*/
var FULL_LANGUAGES = {
EN: Util.clone(require("../../www/common/translations/messages.json")),
FR: Util.clone(require("../../www/common/translations/messages.fr.json")),
DE: Util.clone(require("../../www/common/translations/messages.de.json")),
JP: Util.clone(require("../../www/common/translations/messages.ja.json")),
};
var DUPLICATES = {};
Object.keys(FULL_LANGUAGES).forEach(function (code) {
DUPLICATES[code] = findDuplicates(FULL_LANGUAGES[code]);
});
var extraneousKeys = 0;
// 1) check whether the same mapping exists across languages
// ie. English has "Open" (verb) and "Open" (adjective)
// while French has "Ouvrir" and "Ouvert(s)"
// such keys should not be simplified/deduplicated
Object.keys(DUPLICATES.EN).forEach(function (key) {
var reference = DUPLICATES.EN[key];
if (!['FR', 'DE', 'JP'].every(function (code) {
try {
Assert.deepEqual(reference, DUPLICATES[code][key]);
} catch (err) {
return false;
}
return true;
})) {
return;
}
console.log("The key [%s] (\"%s\") is duplicated identically across all fully supported languages", key, FULL_LANGUAGES.EN[key]);
console.log("Values:", JSON.stringify(['EN', 'FR', 'DE', 'JP'].map(function (code) {
return FULL_LANGUAGES[code][key];
})));
console.log("Keys:", JSON.stringify(reference));
console.log();
extraneousKeys += reference.length - 1;
//console.log("\n" + code + "\n==\n");
//logDuplicates(map);
});
console.log("Total extraneous keys: %s", extraneousKeys);
// TODO
// find instances where
// one of the duplicated keys is not translated
// perhaps we could automatically use the translated one everywhere
// and improve the completeness of translations

@ -1,4 +1,4 @@
var EN = require("../www/common/translations/messages.json"); var EN = require("../../www/common/translations/messages.json");
var simpleTags = [ var simpleTags = [
'<br>', '<br>',
@ -118,7 +118,7 @@ processLang(EN, 'en', true);
'zh', 'zh',
].forEach(function (lang) { ].forEach(function (lang) {
try { try {
var map = require("../www/common/translations/messages." + lang + ".json"); var map = require("../../www/common/translations/messages." + lang + ".json");
if (!Object.keys(map).length) { return; } if (!Object.keys(map).length) { return; }
processLang(map, lang); processLang(map, lang);
} catch (err) { } catch (err) {

@ -1,4 +1,4 @@
var Messages = require("../www/common/translations/messages.json"); var Messages = require("../../www/common/translations/messages.json");
var Exec = require("child_process").exec; var Exec = require("child_process").exec;
var ignoreLines = function (source, pattern) { var ignoreLines = function (source, pattern) {

@ -1,12 +1,14 @@
@import (reference) '../../customize/src/less2/include/framework.less'; @import (reference) '../../customize/src/less2/include/framework.less';
@import (reference) '../../customize/src/less2/include/sidebar-layout.less'; @import (reference) '../../customize/src/less2/include/sidebar-layout.less';
@import (reference) '../../customize/src/less2/include/support.less'; @import (reference) '../../customize/src/less2/include/support.less';
@import (reference) '../../customize/src/less2/include/charts.less';
&.cp-app-admin { &.cp-app-admin {
.framework_min_main(); .framework_min_main();
.sidebar-layout_main(); .sidebar-layout_main();
.support_main(); .support_main();
.charts_main();
.cp-hidden { .cp-hidden {
display: none !important; display: none !important;
@ -294,5 +296,27 @@
} }
} }
} }
span.cp-bar.profiling-percentage {
text-align: center;
padding: 5px;
}
span.profiling-label {
position: absolute;
z-index: 1;
width: 100%;
text-align: center;
padding: 5px;
}
#profiling-chart {
.cp-bar-container {
max-width: 400px;
}
}
.width-constrained {
max-width: 800px;
}
.cp-charts-row.heading {
font-weight: bold;
}
} }

@ -1673,34 +1673,51 @@ define([
var $div = makeBlock('performance-profiling'); // Msg.admin_performanceProfilingHint, .admin_performanceProfilingTitle var $div = makeBlock('performance-profiling'); // Msg.admin_performanceProfilingHint, .admin_performanceProfilingTitle
var onRefresh = function () { var onRefresh = function () {
var body = h('tbody'); var createBody = function () {
return h('div#profiling-chart.cp-charts.cp-bar-table', [
h('span.cp-charts-row.heading', [
h('span', Messages.admin_performanceKeyHeading),
h('span', Messages.admin_performanceTimeHeading),
h('span', Messages.admin_performancePercentHeading),
//h('span', ''), //Messages.admin_performancePercentHeading),
]),
]);
};
var table = h('table#cp-performance-table', [ var body = createBody();
h('thead', [ var appendRow = function (key, time, percent, scaled) {
h('th', Messages.admin_performanceKeyHeading), //console.log("[%s] %ss running time (%s%)", key, time, percent);
h('th', Messages.admin_performanceTimeHeading), body.appendChild(h('span.cp-charts-row', [
h('th', Messages.admin_performancePercentHeading), h('span', key),
]), h('span', time),
body, //h('span', percent),
]); h('span.cp-bar-container', [
var appendRow = function (key, time, percent) { h('span.cp-bar.profiling-percentage', {
console.log("[%s] %ss running time (%s%)", key, time, percent); style: 'width: ' + scaled + '%',
body.appendChild(h('tr', [ key, time, percent ].map(function (x) { }, ' ' ),
return h('td', x); h('span.profiling-label', percent + '%'),
}))); ]),
]));
}; };
var process = function (_o) { var process = function (_o) {
$('#profiling-chart').remove();
body = createBody();
var o = _o[0]; var o = _o[0];
var sorted = Object.keys(o).sort(function (a, b) { var sorted = Object.keys(o).sort(function (a, b) {
if (o[b] - o[a] <= 0) { return -1; } if (o[b] - o[a] <= 0) { return -1; }
return 1; return 1;
}); });
var values = sorted.map(function (k) { return o[k]; });
var total = 0; var total = 0;
sorted.forEach(function (k) { total += o[k]; }); values.forEach(function (value) { total += value; });
var max = Math.max.apply(null, values);
sorted.forEach(function (k) { sorted.forEach(function (k) {
var percent = Math.floor((o[k] / total) * 1000) / 10; var percent = Math.floor((o[k] / total) * 1000) / 10;
appendRow(k, o[k], percent); appendRow(k, o[k], percent, (o[k] / max) * 100);
}); });
$div.append(h('div.width-constrained', body));
}; };
sFrameChan.query('Q_ADMIN_RPC', { sFrameChan.query('Q_ADMIN_RPC', {
@ -1710,10 +1727,7 @@ define([
UI.warn(Messages.error); UI.warn(Messages.error);
return void console.error(e, data); return void console.error(e, data);
} }
//console.info(data);
$div.find("table").remove();
process(data); process(data);
$div.append(table);
}); });
}; };

@ -566,7 +566,7 @@ define([
attributes: { attributes: {
'class': 'fa fa-trash-o', 'class': 'fa fa-trash-o',
}, },
content: h('span', Messages.kanban_delete), content: h('span', Messages.poll_remove),
action: function (e) { action: function (e) {
e.stopPropagation(); e.stopPropagation();
var cal = APP.calendars[id]; var cal = APP.calendars[id];
@ -586,8 +586,9 @@ define([
}, function (err) { }, function (err) {
if (err) { if (err) {
console.error(err); console.error(err);
UI.warn(Messages.error); return void UI.warn(Messages.error);
} }
renderCalendar();
}); });
}); });
} }
@ -722,7 +723,7 @@ define([
if (!calendars.length) { return; } if (!calendars.length) { return; }
var team = privateData.teams[teamId]; var team = privateData.teams[teamId];
var avatar = h('span.cp-avatar'); var avatar = h('span.cp-avatar');
common.displayAvatar($(avatar), team.avatar, team.displayName); common.displayAvatar($(avatar), team.avatar, team.displayName || team.name);
APP.$calendars.append(h('div.cp-calendar-team', [ APP.$calendars.append(h('div.cp-calendar-team', [
avatar, avatar,
h('span.cp-name', {title: team.name}, team.name) h('span.cp-name', {title: team.name}, team.name)

@ -3,7 +3,9 @@ define([
'/common/sframe-common-codemirror.js', '/common/sframe-common-codemirror.js',
'/customize/messages.js', '/customize/messages.js',
'/bower_components/chainpad/chainpad.dist.js', '/bower_components/chainpad/chainpad.dist.js',
], function (Util, SFCodeMirror, Messages, ChainPad) { '/common/inner/common-mediatag.js',
'/common/common-interface.js',
], function (Util, SFCodeMirror, Messages, ChainPad, MT, UI) {
var Markers = {}; var Markers = {};
/* TODO Known Issues /* TODO Known Issues
@ -38,7 +40,17 @@ define([
}); });
} }
uid = Number(uid); uid = Number(uid);
var name = Util.fixHTML(author.name || Messages.anonymous); var name = Util.fixHTML(UI.getDisplayName(author.name));
var animal;
if ((!name || name === Messages.anonymous) && typeof(author.uid) === 'string') {
animal = MT.getPseudorandomAnimal(author.uid);
if (animal) {
name = animal + ' ' + Messages.anonymous;
} else {
name = Messages.anonymous;
}
}
var col = Util.hexToRGB(author.color); var col = Util.hexToRGB(author.color);
var rgba = 'rgba('+col[0]+','+col[1]+','+col[2]+','+Env.opacity+');'; var rgba = 'rgba('+col[0]+','+col[1]+','+col[2]+','+Env.opacity+');';
return Env.editor.markText(from, to, { return Env.editor.markText(from, to, {
@ -520,7 +532,8 @@ define([
Env.authormarks.authors[Env.myAuthorId] = { Env.authormarks.authors[Env.myAuthorId] = {
name: userData.name, name: userData.name,
curvePublic: userData.curvePublic, curvePublic: userData.curvePublic,
color: userData.color color: userData.color,
uid: userData.uid,
}; };
if (!old || (old.name === userData.name && old.color === userData.color)) { return; } if (!old || (old.name === userData.name && old.color === userData.color)) { return; }
return true; return true;

@ -208,5 +208,7 @@ define(function() {
// the driveless mode by changing the following value to "false" // the driveless mode by changing the following value to "false"
AppConfig.allowDrivelessMode = true; AppConfig.allowDrivelessMode = true;
AppConfig.emojiAvatars = '🙈 🦀 🐞 🦋 🐬 🐋 🐢 🦉 🦆 🐧 🦡 🦘 🦨 🦦 🦥 🐼 🐻 🦝 🦓 🐄 💮️ 🐙️ 🌸️ 🌻️ 🐝️ 🐐 🦙 🦒 🐘 🦏 🐁 🐹 🐰 🦫 🦔 🐨 🐱 🐺 👺 👹 👽 👾 🤖'.split(/\s+/);
return AppConfig; return AppConfig;
}); });

@ -34,6 +34,7 @@ try {
define([ define([
'/common/requireconfig.js' '/common/requireconfig.js'
], function (RequireConfig) { ], function (RequireConfig) {
require.config(RequireConfig()); require.config(RequireConfig());
// most of CryptPad breaks if you don't support isArray // most of CryptPad breaks if you don't support isArray
@ -91,4 +92,10 @@ define([
} catch (e) { console.error(e); failStore(); } } catch (e) { console.error(e); failStore(); }
require([document.querySelector('script[data-bootload]').getAttribute('data-bootload')]); require([document.querySelector('script[data-bootload]').getAttribute('data-bootload')]);
if (typeof(Promise) !== 'function') {
setTimeout(function () {
var s = "Internet Explorer is not supported anymore, including by Microsoft.\n\nMost of CryptPad's collaborative functionality requires a modern browser to work.\n\nWe recommend Mozilla Firefox.";
window.alert(s);
});
}
}); });

@ -41,6 +41,10 @@ define([
return e; return e;
}; };
UI.getDisplayName = function (name) {
return (typeof(name) === 'string'? name: "").trim() || Messages.anonymous;
};
// FIXME almost everywhere this is used would also be // FIXME almost everywhere this is used would also be
// a good candidate for sframe-common's getMediatagFromHref // a good candidate for sframe-common's getMediatagFromHref
UI.mediaTag = function (src, key) { UI.mediaTag = function (src, key) {

@ -17,7 +17,8 @@ define([
edPublic: proxy.edPublic, edPublic: proxy.edPublic,
curvePublic: proxy.curvePublic, curvePublic: proxy.curvePublic,
notifications: Util.find(proxy, ['mailboxes', 'notifications', 'channel']), notifications: Util.find(proxy, ['mailboxes', 'notifications', 'channel']),
avatar: proxy.profile && proxy.profile.avatar avatar: proxy.profile && proxy.profile.avatar,
uid: proxy.uid,
}; };
if (hash === false) { delete data.channel; } if (hash === false) { delete data.channel; }
return data; return data;

@ -196,7 +196,7 @@ define([
reader.readAsText(blob); reader.readAsText(blob);
}; };
Thumb.fromBlob = function (blob, _cb) { Thumb.fromBlob = function (blob, _cb) {
var cb = Util.once(_cb); var cb = Util.once(Util.mkAsync(_cb));
// The blob is already in memory, it should be super-fast to make a thumbnail // The blob is already in memory, it should be super-fast to make a thumbnail
// ==> 1s timeout // ==> 1s timeout
setTimeout(function () { setTimeout(function () {

@ -156,9 +156,11 @@ define([
var icons = Object.keys(users).map(function (key, i) { var icons = Object.keys(users).map(function (key, i) {
var data = users[key]; var data = users[key];
var name = data.displayName || data.name || Messages.anonymous; var name = UI.getDisplayName(data.displayName || data.name);
var avatar = h('span.cp-usergrid-avatar.cp-avatar'); var avatar = h('span.cp-usergrid-avatar.cp-avatar', {
common.displayAvatar($(avatar), data.avatar, name); 'aria-hidden': true,
});
common.displayAvatar($(avatar), data.avatar, name, Util.noop, data.uid);
var removeBtn, el; var removeBtn, el;
if (config.remove) { if (config.remove) {
removeBtn = h('span.fa.fa-times'); removeBtn = h('span.fa.fa-times');
@ -649,7 +651,7 @@ define([
if (!AppConfig.enableTemplates) { return; } if (!AppConfig.enableTemplates) { return; }
if (!common.isLoggedIn()) { return; } if (!common.isLoggedIn()) { return; }
button = $('<button>', { button = $('<button>', {
'class': 'fa fa-bookmark cp-toolbar-icon-template', 'class': 'cptools cptools-new-template cp-toolbar-icon-template',
}).append($('<span>', {'class': 'cp-toolbar-drawer-element'}).text(Messages.saveTemplateButton)); }).append($('<span>', {'class': 'cp-toolbar-drawer-element'}).text(Messages.saveTemplateButton));
if (data.rt) { if (data.rt) {
button button
@ -753,7 +755,7 @@ define([
//title: Messages.previewButtonTitle, // TODO display if the label text is collapsed //title: Messages.previewButtonTitle, // TODO display if the label text is collapsed
}, [ }, [
h('i.fa.fa-eye'), h('i.fa.fa-eye'),
h('span.cp-toolbar-name', Messages.share_linkOpen) h('span.cp-toolbar-name', Messages.toolbar_preview)
])).click(common.prepareFeedback(type)); ])).click(common.prepareFeedback(type));
break; break;
case 'print': case 'print':
@ -1437,18 +1439,25 @@ define([
window.setTimeout(function () { $innerblock.hide(); }, 0); window.setTimeout(function () { $innerblock.hide(); }, 0);
}; };
config.options.forEach(function (o) { var setOptions = function (options) {
if (!isValidOption(o)) { return; } options.forEach(function (o) {
if (isElement(o)) { return $innerblock.append($(o)); } if (!isValidOption(o)) { return; }
var $el = $('<' + o.tag + '>', o.attributes || {}).html(o.content || ''); if (isElement(o)) { return $innerblock.append($(o)); }
$el.appendTo($innerblock); var $el = $('<' + o.tag + '>', o.attributes || {}).html(o.content || '');
if (typeof(o.action) === 'function') { $el.appendTo($innerblock);
$el.click(function (e) { if (typeof(o.action) === 'function') {
var close = o.action(e); $el.click(function (e) {
if (close) { hide(); } var close = o.action(e);
}); if (close) { hide(); }
} });
}); }
});
};
setOptions(config.options);
$container.setOptions = function (options) {
$innerblock.empty();
setOptions(options);
};
$container.append($button).append($innerblock); $container.append($button).append($innerblock);
@ -1579,16 +1588,20 @@ define([
}, 1000); }, 1000);
}); });
$container.setValue = function (val, name) { $container.setValue = function (val, name, sync) {
value = val; value = val;
var $val = $innerblock.find('[data-value="'+val+'"]'); var $val = $innerblock.find('[data-value="'+val+'"]');
var textValue = name || $val.html() || val; var textValue = name || $val.html() || val;
if (sync) {
$button.find('.cp-dropdown-button-title').html(textValue);
return;
}
setTimeout(function () { setTimeout(function () {
$button.find('.cp-dropdown-button-title').html(textValue); $button.find('.cp-dropdown-button-title').html(textValue);
}); });
}; };
$container.getValue = function () { $container.getValue = function () {
return value || ''; return typeof(value) === "undefined" ? '' : value;
}; };
} }
@ -1993,9 +2006,12 @@ define([
var loadingAvatar; var loadingAvatar;
var to; var to;
var oldUrl = ''; var oldUrl = '';
var oldUid;
var oldName;
var updateButton = function () { var updateButton = function () {
var myData = metadataMgr.getUserData(); var myData = metadataMgr.getUserData();
var privateData = metadataMgr.getPrivateData(); var privateData = metadataMgr.getPrivateData();
var uid = myData.uid;
if (!priv.plan && privateData.plan) { if (!priv.plan && privateData.plan) {
config.$initBlock.empty(); config.$initBlock.empty();
metadataMgr.off('change', updateButton); metadataMgr.off('change', updateButton);
@ -2010,18 +2026,19 @@ define([
return; return;
} }
loadingAvatar = true; loadingAvatar = true;
var newName = myData.name; var newName = UI.getDisplayName(myData.name);
var url = myData.avatar; var url = myData.avatar;
$displayName.text(newName || Messages.anonymous); $displayName.text(newName);
if (accountName && oldUrl !== url) { if ((accountName && oldUrl !== url) || !accountName && uid !== oldUid || oldName !== newName) {
$avatar.html(''); $avatar.html('');
Common.displayAvatar($avatar, url, Common.displayAvatar($avatar, url, newName, function ($img) {
newName || Messages.anonymous, function ($img) {
oldUrl = url; oldUrl = url;
oldUid = uid;
oldName = newName;
$userAdmin.find('> button').removeClass('cp-avatar'); $userAdmin.find('> button').removeClass('cp-avatar');
if ($img) { $userAdmin.find('> button').addClass('cp-avatar'); } if ($img) { $userAdmin.find('> button').addClass('cp-avatar'); }
loadingAvatar = false; loadingAvatar = false;
}); }, uid);
return; return;
} }
loadingAvatar = false; loadingAvatar = false;
@ -2303,6 +2320,7 @@ define([
var teams = Object.keys(privateData.teams).map(function (id) { var teams = Object.keys(privateData.teams).map(function (id) {
var data = privateData.teams[id]; var data = privateData.teams[id];
var avatar = h('span.cp-creation-team-avatar.cp-avatar'); var avatar = h('span.cp-creation-team-avatar.cp-avatar');
// We assume that teams always have a non-empty name, so we don't need a UID
common.displayAvatar($(avatar), data.avatar, data.name); common.displayAvatar($(avatar), data.avatar, data.name);
return h('div.cp-creation-team', { return h('div.cp-creation-team', {
'data-id': id, 'data-id': id,
@ -2431,14 +2449,14 @@ define([
} }
return b.used - a.used; return b.used - a.used;
}); });
if (!appCfg.noTemplates) { /*if (!appCfg.noTemplates) {
allData.unshift({ allData.unshift({
name: Messages.creation_newTemplate, name: Messages.creation_newTemplate,
id: -1, id: -1,
//icon: h('span.fa.fa-bookmark') //icon: h('span.fa.fa-bookmark')
icon: h('span.cptools.cptools-new-template') icon: h('span.cptools.cptools-new-template')
}); });
} }*/
if (!privateData.newTemplate) { if (!privateData.newTemplate) {
allData.unshift({ allData.unshift({
name: Messages.creation_noTemplate, name: Messages.creation_noTemplate,
@ -3036,22 +3054,10 @@ define([
var name = Util.fixHTML(data.title); var name = Util.fixHTML(data.title);
var url = data.href; var url = data.href;
var user = data.name; var user = data.name;
//Messages.link_open = "Open URL";
// openLinkInNewTab ("Open Link in New Tab")
// fc_open ("Open")
// share_linkOpen ("Preview")
// resources_openInNewTab ("Open it in a new tab")
Messages.link_open = Messages.fc_open; // XXX 4.11.0
//Messages.link_store = "Store link in drive";
// toolbar_storeInDrive ? ("Store in CryptDrive")
// autostore_store ? ("Store")
Messages.link_store = Messages.toolbar_storeInDrive; // XXX 4.11.0
var content = h('div', [ var content = h('div', [
UI.setHTML(h('p'), Messages._getKey('notification_openLink', [name, user])), UI.setHTML(h('p'), Messages._getKey('notification_openLink', [name, user])),
h('pre', url), h('pre.cp-link-preview', url),
UIElements.getVerifiedFriend(common, data.curve, user) UIElements.getVerifiedFriend(common, data.curve, user)
]); ]);
var clicked = false; var clicked = false;
@ -3066,7 +3072,7 @@ define([
keys: [27] keys: [27]
}, { }, {
className: 'primary', className: 'primary',
name: Messages.link_open, name: Messages.fc_open,
onClick: function () { onClick: function () {
if (clicked) { return true; } if (clicked) { return true; }
clicked = true; clicked = true;
@ -3076,7 +3082,7 @@ define([
keys: [13] keys: [13]
}, { }, {
className: 'primary', className: 'primary',
name: Messages.link_store, name: Messages.toolbar_storeInDrive,
onClick: function () { onClick: function () {
if (clicked) { return; } if (clicked) { return; }
clicked = true; clicked = true;
@ -3106,7 +3112,7 @@ define([
var sframeChan = common.getSframeChannel(); var sframeChan = common.getSframeChannel();
var msg = data.content.msg; var msg = data.content.msg;
var name = Util.fixHTML(msg.content.user.displayName) || Messages.anonymous; var name = Util.fixHTML(UI.getDisplayName(msg.content.user.displayName));
var title = Util.fixHTML(msg.content.title); var title = Util.fixHTML(msg.content.title);
var text = Messages._getKey('owner_add', [name, title]); var text = Messages._getKey('owner_add', [name, title]);
@ -3238,7 +3244,7 @@ define([
var sframeChan = common.getSframeChannel(); var sframeChan = common.getSframeChannel();
var msg = data.content.msg; var msg = data.content.msg;
var name = Util.fixHTML(msg.content.user.displayName) || Messages.anonymous; var name = Util.fixHTML(UI.getDisplayName(msg.content.user.displayName));
var title = Util.fixHTML(msg.content.title); var title = Util.fixHTML(msg.content.title);
var text = Messages._getKey('owner_team_add', [name, title]); var text = Messages._getKey('owner_team_add', [name, title]);
@ -3353,13 +3359,15 @@ define([
var verified = h('p'); var verified = h('p');
var $verified = $(verified); var $verified = $(verified);
name = UI.getDisplayName(name);
if (priv.friends && priv.friends[curve]) { if (priv.friends && priv.friends[curve]) {
$verified.addClass('cp-notifications-requestedit-verified'); $verified.addClass('cp-notifications-requestedit-verified');
var f = priv.friends[curve]; var f = priv.friends[curve];
$verified.append(h('span.fa.fa-certificate')); $verified.append(h('span.fa.fa-certificate'));
var $avatar = $(h('span.cp-avatar')).appendTo($verified); var $avatar = $(h('span.cp-avatar')).appendTo($verified);
$verified.append(h('p', Messages._getKey('isContact', [f.displayName]))); name = UI.getDisplayName(f.displayName);
common.displayAvatar($avatar, f.avatar, f.displayName); $verified.append(h('p', Messages._getKey('isContact', [name])));
common.displayAvatar($avatar, f.avatar, name, Util.noop, f.uid);
} else { } else {
$verified.append(Messages._getKey('isNotContact', [name])); $verified.append(Messages._getKey('isNotContact', [name]));
} }
@ -3369,7 +3377,7 @@ define([
UIElements.displayInviteTeamModal = function (common, data) { UIElements.displayInviteTeamModal = function (common, data) {
var msg = data.content.msg; var msg = data.content.msg;
var name = Util.fixHTML(msg.content.user.displayName) || Messages.anonymous; var name = Util.fixHTML(UI.getDisplayName(msg.content.user.displayName));
var teamName = Util.fixHTML(Util.find(msg, ['content', 'team', 'metadata', 'name']) || ''); var teamName = Util.fixHTML(Util.find(msg, ['content', 'team', 'metadata', 'name']) || '');
var verified = UIElements.getVerifiedFriend(common, msg.author, name); var verified = UIElements.getVerifiedFriend(common, msg.author, name);
@ -3453,7 +3461,8 @@ define([
name: f.displayName, name: f.displayName,
curvePublic: f.curvePublic, curvePublic: f.curvePublic,
profile: f.profile, profile: f.profile,
notifications: f.notifications notifications: f.notifications,
uid: f.uid,
}; };
}); });
}; };
@ -3552,7 +3561,7 @@ define([
}; };
// Set the value to receive from the autocomplete // Set the value to receive from the autocomplete
var toInsert = function (data, key) { var toInsert = function (data, key) {
var name = data.name.replace(/[^a-zA-Z0-9]+/g, "-"); var name = UI.getDisplayName(data.name.replace(/[^a-zA-Z0-9]+/g, "-"));
return "[@"+name+"|"+key+"]"; return "[@"+name+"|"+key+"]";
}; };
@ -3605,18 +3614,20 @@ define([
var avatar = h('span.cp-avatar', { var avatar = h('span.cp-avatar', {
contenteditable: false contenteditable: false
}); });
common.displayAvatar($(avatar), data.avatar, data.name);
var displayName = UI.getDisplayName(data.name);
common.displayAvatar($(avatar), data.avatar, displayName);
return h('span.cp-mentions', { return h('span.cp-mentions', {
'data-curve': data.curvePublic, 'data-curve': data.curvePublic,
'data-notifications': data.notifications, 'data-notifications': data.notifications,
'data-profile': data.profile, 'data-profile': data.profile,
'data-name': Util.fixHTML(data.name), 'data-name': Util.fixHTML(displayName),
'data-avatar': data.avatar || "", 'data-avatar': data.avatar || "",
}, [ }, [
avatar, avatar,
h('span.cp-mentions-name', { h('span.cp-mentions-name', {
contenteditable: false contenteditable: false
}, data.name) }, displayName)
]); ]);
}; };
} }
@ -3648,7 +3659,7 @@ define([
}).map(function (key) { }).map(function (key) {
var data = sources[key]; var data = sources[key];
return { return {
label: data.name, label: UI.getDisplayName(data.name),
value: key value: key
}; };
}); });
@ -3683,10 +3694,12 @@ define([
var obj = sources[key]; var obj = sources[key];
if (!obj) { return; } if (!obj) { return; }
var avatar = h('span.cp-avatar'); var avatar = h('span.cp-avatar');
common.displayAvatar($(avatar), obj.avatar, obj.name); var displayName = UI.getDisplayName(obj.name);
common.displayAvatar($(avatar), obj.avatar, displayName, Util.noop, obj.uid);
var li = h('li.cp-autocomplete-value', [ var li = h('li.cp-autocomplete-value', [
avatar, avatar,
h('span', obj.name) h('span', displayName),
]); ]);
return $(li).appendTo(ul); return $(li).appendTo(ul);
}; };

@ -75,7 +75,9 @@
handlers.push(cb); handlers.push(cb);
}, },
unreg: function (cb) { unreg: function (cb) {
if (handlers.indexOf(cb) === -1) { throw new Error("Not registered"); } if (handlers.indexOf(cb) === -1) {
return void console.error("event handler was already unregistered");
}
handlers.splice(handlers.indexOf(cb), 1); handlers.splice(handlers.indexOf(cb), 1);
}, },
fire: function () { fire: function () {
@ -437,7 +439,7 @@
var now = +new Date(); var now = +new Date();
if (last && now <= last + t) { return t - (now - last); } if (last && now <= last + t) { return t - (now - last); }
last = now; last = now;
f(); f.apply(null, Util.slice(arguments));
return null; return null;
}; };
}; };

@ -1,7 +1,7 @@
define([ define([
'/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad-crypto/crypto.js',
'/bower_components/chainpad-netflux/chainpad-netflux.js', 'chainpad-netflux',
'/bower_components/netflux-websocket/netflux-client.js', 'netflux-client',
'/common/common-util.js', '/common/common-util.js',
'/common/common-hash.js', '/common/common-hash.js',
'/common/common-realtime.js', '/common/common-realtime.js',

@ -161,7 +161,7 @@ define([
common.makeNetwork = function (cb) { common.makeNetwork = function (cb) {
require([ require([
'/bower_components/netflux-websocket/netflux-client.js', 'netflux-client',
'/common/outer/network-config.js' '/common/outer/network-config.js'
], function (Netflux, NetConfig) { ], function (Netflux, NetConfig) {
var wsUrl = NetConfig.getWebsocketURL(); var wsUrl = NetConfig.getWebsocketURL();

@ -2759,6 +2759,7 @@ define([
var $warning = $(warning).hide(); var $warning = $(warning).hide();
var $url = $(url).on('change keypress keyup keydown', function () { var $url = $(url).on('change keypress keyup keydown', function () {
var v = $url.val().trim(); var v = $url.val().trim();
$url.toggleClass('cp-input-invalid', !Util.isValidURL(v));
if (v.length > 200) { if (v.length > 200) {
$warning.show(); $warning.show();
return; return;
@ -2783,7 +2784,6 @@ define([
var u = $url.val().trim(); var u = $url.val().trim();
if (!n || !u) { return true; } if (!n || !u) { return true; }
if (!Util.isValidURL(u)) { if (!Util.isValidURL(u)) {
// XXX 4.11.0 add style for invalid input? input:invalid
UI.warn(Messages.fm_link_invalid); UI.warn(Messages.fm_link_invalid);
return true; return true;
} }

@ -171,7 +171,7 @@ define([
if (!Object.keys(_friends).length) { if (!Object.keys(_friends).length) {
var friendText; var friendText;
if (!friendKeys.length) { if (!friendKeys.length) {
console.error(UIElements.noContactsMessage(common)); //console.error(UIElements.noContactsMessage(common));
var findContacts = UIElements.noContactsMessage(common); var findContacts = UIElements.noContactsMessage(common);
friendText = h('span.cp-app-prop-content', friendText = h('span.cp-app-prop-content',
findContacts.content findContacts.content
@ -772,7 +772,8 @@ define([
if (friend.edPublic !== ed || c === 'me') { return; } if (friend.edPublic !== ed || c === 'me') { return; }
_owners[friend.edPublic] = { _owners[friend.edPublic] = {
name: friend.displayName, name: friend.displayName,
avatar: friend.avatar avatar: friend.avatar,
uid: friend.uid,
}; };
return true; return true;
})) { })) {
@ -782,6 +783,11 @@ define([
_owners[ed] = { _owners[ed] = {
avatar: '?', avatar: '?',
name: Messages.owner_unknownUser, name: Messages.owner_unknownUser,
// TODO a possible enhancement is to use data from the context
// ie. if you have opened the access modal from within the pad
// its owner might be present or they might have left some data
// in the pad itself (as is the case of the uid in rich text comments)
// TODO or just implement "Acquaintances"
}; };
strangers++; strangers++;
}); });

@ -6,12 +6,13 @@ define([
'/common/hyperscript.js', '/common/hyperscript.js',
'/common/media-tag.js', '/common/media-tag.js',
'/customize/messages.js', '/customize/messages.js',
'/customize/application_config.js',
'/bower_components/tweetnacl/nacl-fast.min.js', '/bower_components/tweetnacl/nacl-fast.min.js',
'/bower_components/croppie/croppie.min.js', '/bower_components/croppie/croppie.min.js',
'/bower_components/file-saver/FileSaver.min.js', '/bower_components/file-saver/FileSaver.min.js',
'css!/bower_components/croppie/croppie.css', 'css!/bower_components/croppie/croppie.css',
], function ($, Util, Hash, UI, h, MediaTag, Messages) { ], function ($, Util, Hash, UI, h, MediaTag, Messages, AppConfig) {
var MT = {}; var MT = {};
var Nacl = window.nacl; var Nacl = window.nacl;
@ -43,9 +44,16 @@ define([
}); });
}; };
var animal_avatars = {};
MT.getCursorAvatar = function (cursor) { MT.getCursorAvatar = function (cursor) {
var uid = cursor.uid;
// TODO it would be nice to have "{0} is editing" instead of just their name
var html = '<span class="cp-cursor-avatar">'; var html = '<span class="cp-cursor-avatar">';
html += (cursor.avatar && avatars[cursor.avatar]) || ''; if (cursor.avatar && avatars[cursor.avatar]) {
html += avatars[cursor.avatar];
} else if (animal_avatars[uid]) {
html += animal_avatars[uid] + ' ';
}
html += Util.fixHTML(cursor.name) + '</span>'; html += Util.fixHTML(cursor.name) + '</span>';
return html; return html;
}; };
@ -79,12 +87,63 @@ define([
}); });
}; };
MT.displayAvatar = function (common, $container, href, name, _cb) { // https://emojipedia.org/nature/
var ANIMALS = AppConfig.emojiAvatars || [];
var getPseudorandomAnimal = MT.getPseudorandomAnimal = function (seed) {
if (!ANIMALS.length) { return ''; }
if (typeof(seed) !== 'string') { return; }
seed = seed.replace(/\D/g, '').slice(0, 10); // TODO possible optimization for on-wire uid
seed = parseInt(seed);
if (!seed) { return; }
return ANIMALS[seed % ANIMALS.length] || '';
};
var getPrettyInitials = MT.getPrettyInitials = function (name) {
var parts = name.split(/\s+/);
var text;
if (parts.length > 1) {
text = parts.slice(0, 2).map(Util.getFirstCharacter).join('');
} else {
text = Util.getFirstCharacter(name);
var second = Util.getFirstCharacter(name.replace(text, ''));
if (second && second !== '?') {
text += second;
}
}
return text;
};
MT.displayAvatar = function (common, $container, href, name, _cb, uid) {
var cb = Util.once(Util.mkAsync(_cb || function () {})); var cb = Util.once(Util.mkAsync(_cb || function () {}));
var displayDefault = function () { var displayDefault = function () {
var text = Util.getFirstCharacter(name || Messages.anonymous); var animal_avatar;
var $avatar = $('<span>', {'class': 'cp-avatar-default'}).text(text); if (uid && animal_avatars[uid]) {
animal_avatar = animal_avatars[uid];
}
name = UI.getDisplayName(name);
var text;
if (ANIMALS.length && name === Messages.anonymous && uid) {
if (animal_avatar) {
text = animal_avatar;
} else {
text = animal_avatar = getPseudorandomAnimal(uid);
}
} else {
text = getPrettyInitials(name);
}
var $avatar = $('<span>', {
'class': 'cp-avatar-default' + (animal_avatar? ' animal': ''),
// this prevents screenreaders from trying to describe this
alt: '',
'aria-hidden': true,
}).text(text);
$container.append($avatar); $container.append($avatar);
if (uid && animal_avatar) {
animal_avatars[uid] = animal_avatar;
}
if (cb) { cb(); } if (cb) { cb(); }
}; };
if (!window.Symbol) { return void displayDefault(); } // IE doesn't have Symbol if (!window.Symbol) { return void displayDefault(); } // IE doesn't have Symbol
@ -97,6 +156,7 @@ define([
return void cb($el); return void cb($el);
} }
var centerImage = function ($img, $image) { var centerImage = function ($img, $image) {
var img = $image[0]; var img = $image[0];
var w = img.width; var w = img.width;

@ -76,6 +76,7 @@ define([
var shareButton = { var shareButton = {
className: 'primary cp-share-with-friends', className: 'primary cp-share-with-friends',
name: Messages.share_withFriends, name: Messages.share_withFriends,
iconClass: '.fa.fa-shhare-alt',
onClick: function () { onClick: function () {
var href; var href;
nThen(function (waitFor) { nThen(function (waitFor) {
@ -420,12 +421,12 @@ define([
embed: Util.isChecked($link.find('#cp-share-embed')) embed: Util.isChecked($link.find('#cp-share-embed'))
})); }));
}); });
var linkButtons = [ var linkButtons = [
makeCancelButton(), makeCancelButton(),
!opts.sharedFolder && { !opts.sharedFolder && {
className: 'secondary cp-nobar', className: 'secondary cp-nobar',
name: Messages.share_linkOpen, name: Messages.share_linkOpen,
iconClass: '.fa.fa-eye',
onClick: function () { onClick: function () {
opts.saveValue(); opts.saveValue();
var v = opts.getLinkValue({ var v = opts.getLinkValue({
@ -442,6 +443,7 @@ define([
}, { }, {
className: 'primary cp-nobar', className: 'primary cp-nobar',
name: Messages.share_linkCopy, name: Messages.share_linkCopy,
iconClass: '.fa.fa-link',
onClick: function () { onClick: function () {
opts.saveValue(); opts.saveValue();
var v = opts.getLinkValue({ var v = opts.getLinkValue({
@ -496,6 +498,7 @@ define([
{ {
className: 'primary', className: 'primary',
name: Messages.share_linkCopy, name: Messages.share_linkCopy,
iconClass: '.fa.fa-link',
onClick: function () { onClick: function () {
Feedback.send('SHARE_EMBED'); Feedback.send('SHARE_EMBED');
var v = opts.getEmbedValue(); var v = opts.getEmbedValue();
@ -870,6 +873,7 @@ define([
{ {
className: 'primary', className: 'primary',
name: Messages.share_linkCopy, name: Messages.share_linkCopy,
iconClass: '.fa.fa-link',
onClick: function () { onClick: function () {
var v = opts.getLinkValue(); var v = opts.getLinkValue();
var success = Clipboard.copy(v); var success = Clipboard.copy(v);
@ -915,6 +919,7 @@ define([
}, { }, {
className: 'primary', className: 'primary',
name: Messages.share_mediatagCopy, name: Messages.share_mediatagCopy,
iconClass: '.fa.fa-link',
onClick: function () { onClick: function () {
var v = common.getMediatagFromHref(opts.fileData); var v = common.getMediatagFromHref(opts.fileData);
var success = Clipboard.copy(v); var success = Clipboard.copy(v);

@ -87,6 +87,7 @@ var factory = function () {
image: function (metadata, url, content, cfg, cb) { image: function (metadata, url, content, cfg, cb) {
var img = document.createElement('img'); var img = document.createElement('img');
img.setAttribute('src', url); img.setAttribute('src', url);
img.setAttribute('alt', metadata.alt || "");
img.blob = content; img.blob = content;
cb(void 0, img); cb(void 0, img);
}, },
@ -94,12 +95,15 @@ var factory = function () {
var video = document.createElement('video'); var video = document.createElement('video');
video.setAttribute('src', url); video.setAttribute('src', url);
video.setAttribute('controls', true); video.setAttribute('controls', true);
// https://discuss.codecademy.com/t/can-we-use-an-alt-attribute-with-the-video-tag/300322/4
video.setAttribute('title', metadata.alt || "");
cb(void 0, video); cb(void 0, video);
}, },
audio: function (metadata, url, content, cfg, cb) { audio: function (metadata, url, content, cfg, cb) {
var audio = document.createElement('audio'); var audio = document.createElement('audio');
audio.setAttribute('src', url); audio.setAttribute('src', url);
audio.setAttribute('controls', true); audio.setAttribute('controls', true);
audio.setAttribute('alt', metadata.alt || "");
cb(void 0, audio); cb(void 0, audio);
}, },
pdf: function (metadata, url, content, cfg, cb) { pdf: function (metadata, url, content, cfg, cb) {
@ -115,6 +119,7 @@ var factory = function () {
download: function (metadata, url, content, cfg, cb) { download: function (metadata, url, content, cfg, cb) {
var btn = document.createElement('button'); var btn = document.createElement('button');
btn.setAttribute('class', 'btn btn-default'); btn.setAttribute('class', 'btn btn-default');
btn.setAttribute('alt', metadata.alt || "");
btn.innerHTML = '<i class="fa fa-save"></i>' + cfg.download.text + '<br>' + btn.innerHTML = '<i class="fa fa-save"></i>' + cfg.download.text + '<br>' +
(metadata.name ? '<b>' + fixHTML(metadata.name) + '</b>' : ''); (metadata.name ? '<b>' + fixHTML(metadata.name) + '</b>' : '');
btn.addEventListener('click', function () { btn.addEventListener('click', function () {
@ -542,7 +547,7 @@ var factory = function () {
// Process // Process
var process = function (mediaObject, decrypted, cfg, cb) { var process = function (mediaObject, decrypted, cfg, cb) {
var metadata = decrypted.metadata; var metadata = decrypted.metadata || {};
var blob = decrypted.content; var blob = decrypted.content;
var mediaType = getType(mediaObject, metadata, cfg); var mediaType = getType(mediaObject, metadata, cfg);
@ -596,6 +601,15 @@ var factory = function () {
}); });
}; };
var initHandlers = function () {
return {
'progress': [],
'complete': [],
'metadata': [],
'error': []
};
};
// Initialize a media-tag // Initialize a media-tag
var init = function (el, cfg) { var init = function (el, cfg) {
cfg = cfg || {}; cfg = cfg || {};
@ -613,13 +627,7 @@ var factory = function () {
}; };
} }
var handlers = cfg.handlers || { var handlers = cfg.handlers || initHandlers();
'progress': [],
'complete': [],
'metadata': [],
'error': []
};
var mediaObject = el._mediaObject = { var mediaObject = el._mediaObject = {
handlers: handlers, handlers: handlers,
tag: el tag: el
@ -762,15 +770,31 @@ var factory = function () {
init.fetchDecryptedMetadata = fetchDecryptedMetadata; init.fetchDecryptedMetadata = fetchDecryptedMetadata;
init.preview = function (content, metadata, cfg, cb) {
cfg = cfg || {};
addMissingConfig(cfg, config);
var handlers = cfg.handlers || initHandlers();
var el = document.createElement('media-tag');
var mediaObject = el._mediaObject = {
handlers: handlers,
tag: el,
};
process(mediaObject, {
metadata: metadata,
content: content
}, cfg, function (err) {
if (err) { return void cb(err); }
cb(void 0, el);
});
};
return init; return init;
}; };
if (typeof(module) !== 'undefined' && module.exports) { if (typeof(module) !== 'undefined' && module.exports) {
module.exports = factory(); module.exports = factory();
} else if ((typeof(define) !== 'undefined' && define !== null) && (define.amd !== null)) { } else if ((typeof(define) !== 'undefined' && define !== null) && (define.amd !== null)) {
define([ define([], function () {
'/bower_components/es6-promise/es6-promise.min.js'
], function () {
return factory(); return factory();
}); });
} else { } else {

@ -190,9 +190,11 @@ define([
markup.message = function (msg) { markup.message = function (msg) {
if (msg.type !== 'MSG') { return; } if (msg.type !== 'MSG') { return; }
var curvePublic = msg.author; var curvePublic = msg.author;
// FIXME this assignment looks like it has some holes in its logic
// but I'm scared to touch it because it looks like it was hacked to fix some bugs
var name = (typeof msg.name !== "undefined" || !contactsData[msg.author]) ? var name = (typeof msg.name !== "undefined" || !contactsData[msg.author]) ?
(msg.name || Messages.anonymous) : (msg.name || Messages.anonymous) :
contactsData[msg.author].displayName; contactsData[msg.author].displayName || Messages.anonymous;
var d = msg.time ? new Date(msg.time) : undefined; var d = msg.time ? new Date(msg.time) : undefined;
var day = d ? d.toLocaleDateString() : ''; var day = d ? d.toLocaleDateString() : '';
var hour = d ? d.toLocaleTimeString() : ''; var hour = d ? d.toLocaleTimeString() : '';
@ -239,7 +241,7 @@ define([
}); });
var chan = state.channels[id]; var chan = state.channels[id];
var displayName = chan.name; var displayName = UI.getDisplayName(chan.name || chan.displayName);
var fetching = false; var fetching = false;
var $moreHistory = $(moreHistory).click(function () { var $moreHistory = $(moreHistory).click(function () {
@ -364,7 +366,7 @@ define([
avatars[friend.avatar] = $img[0].outerHTML; avatars[friend.avatar] = $img[0].outerHTML;
} }
$(rightCol).insertAfter($avatar); $(rightCol).insertAfter($avatar);
}); }, friend.uid);
} }
var sending = false; var sending = false;
@ -544,7 +546,7 @@ define([
title: Messages.contacts_online title: Messages.contacts_online
}); });
var rightCol = h('span.cp-app-contacts-right-col', [ var rightCol = h('span.cp-app-contacts-right-col', [
h('span.cp-app-contacts-name', [room.name]), h('span.cp-app-contacts-name', [room.isFriendChat? UI.getDisplayName(room.name): room.name]),
h('span.cp-app-contacts-icons', [ h('span.cp-app-contacts-icons', [
room.isFriendChat ? mute : undefined, room.isFriendChat ? mute : undefined,
room.isFriendChat ? unmute : undefined, room.isFriendChat ? unmute : undefined,
@ -609,7 +611,7 @@ define([
avatars[friendData.avatar] = $img[0].outerHTML; avatars[friendData.avatar] = $img[0].outerHTML;
} }
$room.append(rightCol); $room.append(rightCol);
}); }, friendData.uid);
} }
$room.append(status); $room.append(status);
return $room; return $room;
@ -631,9 +633,9 @@ define([
var el_message = markup.message(message); var el_message = markup.message(message);
if (message.type === 'MSG') { if (message.type === 'MSG') {
var name = typeof message.name !== "undefined" ? var name = UI.getDisplayName(typeof message.name !== "undefined" ?
(message.name || Messages.anonymous) : message.name:
contactsData[message.author].displayName; contactsData[message.author].displayName);
common.notify({ common.notify({
title: name, title: name,
msg: message.text, msg: message.text,
@ -826,6 +828,11 @@ define([
} }
}; };
/* The following block is for a disabled feature which allows users to switch
between pad chat (when in the context of a pad) and direct chats with their
contacts.
*/
/*
common.getMetadataMgr().onTitleChange(function () { common.getMetadataMgr().onTitleChange(function () {
var padChat = common.getPadChat(); var padChat = common.getPadChat();
var md = common.getMetadataMgr().getMetadata(); var md = common.getMetadataMgr().getMetadata();
@ -839,11 +846,14 @@ define([
$lAvatar.find('.cp-avatar-default, media-tag').remove(); $lAvatar.find('.cp-avatar-default, media-tag').remove();
var $div = $('<div>'); var $div = $('<div>');
// There should always be a title here (defaultTitle if nothing else)
// so we don't ever need to supply a uid for an animal avatar
common.displayAvatar($div, null, name, function () { common.displayAvatar($div, null, name, function () {
$mAvatar.html($div.html()); $mAvatar.html($div.html());
$lAvatar.find('.cp-app-contacts-right-col').before($div.html()); $lAvatar.find('.cp-app-contacts-right-col').before($div.html());
}); });
}); });
*/
// TODO room // TODO room
// var onJoinRoom // var onJoinRoom
@ -878,7 +888,7 @@ define([
h('i.fa.fa-bell'), h('i.fa.fa-bell'),
Messages.contacts_unmute || 'unmute' Messages.contacts_unmute || 'unmute'
]); ]);
common.displayAvatar($(avatar), data.avatar, data.name); common.displayAvatar($(avatar), data.avatar, data.name, Util.noop, data.uid);
$(button).click(function () { $(button).click(function () {
unmuteUser(curve, button); unmuteUser(curve, button);
execCommand('UNMUTE_USER', curve, function (e, data) { execCommand('UNMUTE_USER', curve, function (e, data) {
@ -894,7 +904,7 @@ define([
}); });
return h('div.cp-contacts-muted-user', [ return h('div.cp-contacts-muted-user', [
h('span', avatar), h('span', avatar),
h('span', data.name), h('span', UI.getDisplayName(data.name)),
button button
]); ]);
}); });

@ -26,9 +26,9 @@ define([
'/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad-crypto/crypto.js',
'/bower_components/chainpad/chainpad.dist.js', '/bower_components/chainpad/chainpad.dist.js',
'/bower_components/chainpad-netflux/chainpad-netflux.js', 'chainpad-netflux',
'/bower_components/chainpad-listmap/chainpad-listmap.js', 'chainpad-listmap',
'/bower_components/netflux-websocket/netflux-client.js', 'netflux-client',
'/bower_components/nthen/index.js', '/bower_components/nthen/index.js',
'/bower_components/saferphore/index.js', '/bower_components/saferphore/index.js',
], function (ApiConfig, Sortify, UserObject, ProxyManager, Migrate, Hash, Util, Constants, Feedback, ], function (ApiConfig, Sortify, UserObject, ProxyManager, Migrate, Hash, Util, Constants, Feedback,

@ -97,7 +97,7 @@ define([
var checkCheckpoints = function (array) { var checkCheckpoints = function (array) {
if (!Array.isArray(array)) { return; } if (!Array.isArray(array)) { return; }
// Keep the last 100 messages // Keep the last 100 messages
if (array.length > 100) { // XXX 4.11.0 if (array.length > 100) { // FIXME this behaviour is only valid for chainpad-style documents
array.splice(0, array.length - 100); array.splice(0, array.length - 100);
} }
// Remove every message before the first checkpoint // Remove every message before the first checkpoint

@ -6,7 +6,7 @@ define([
'/common/outer/cache-store.js', '/common/outer/cache-store.js',
'/customize/messages.js', '/customize/messages.js',
'/bower_components/nthen/index.js', '/bower_components/nthen/index.js',
'/bower_components/chainpad-listmap/chainpad-listmap.js', 'chainpad-listmap',
'/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad-crypto/crypto.js',
'/bower_components/chainpad/chainpad.dist.js', '/bower_components/chainpad/chainpad.dist.js',
], function (Util, Hash, Constants, Realtime, Cache, Messages, nThen, Listmap, Crypto, ChainPad) { ], function (Util, Hash, Constants, Realtime, Cache, Messages, nThen, Listmap, Crypto, ChainPad) {

@ -187,6 +187,7 @@ define([
data.color = Util.find(proxy, ['settings', 'general', 'cursor', 'color']); data.color = Util.find(proxy, ['settings', 'general', 'cursor', 'color']);
data.name = proxy[Constants.displayNameKey] || ctx.store.noDriveName || Messages.anonymous; data.name = proxy[Constants.displayNameKey] || ctx.store.noDriveName || Messages.anonymous;
data.avatar = Util.find(proxy, ['profile', 'avatar']); data.avatar = Util.find(proxy, ['profile', 'avatar']);
data.uid = Util.find(proxy, ['uid']) || ctx.store.noDriveUid;
c.cursor = data; c.cursor = data;
sendMyCursor(ctx, client); sendMyCursor(ctx, client);
cb(); cb();

@ -7,7 +7,7 @@ define([
'/common/common-messaging.js', '/common/common-messaging.js',
'/common/notify.js', '/common/notify.js',
'/common/outer/mailbox-handlers.js', '/common/outer/mailbox-handlers.js',
'/bower_components/chainpad-netflux/chainpad-netflux.js', 'chainpad-netflux',
'/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad-crypto/crypto.js',
], function (Config, BCast, Util, Hash, Realtime, Messaging, Notify, Handlers, CpNetflux, Crypto) { ], function (Config, BCast, Util, Hash, Realtime, Messaging, Notify, Handlers, CpNetflux, Crypto) {
var Mailbox = {}; var Mailbox = {};

@ -3,7 +3,7 @@ define([
'/common/common-hash.js', '/common/common-hash.js',
'/common/common-constants.js', '/common/common-constants.js',
'/common/common-realtime.js', '/common/common-realtime.js',
'/bower_components/chainpad-listmap/chainpad-listmap.js', 'chainpad-listmap',
'/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad-crypto/crypto.js',
'/bower_components/chainpad/chainpad.dist.js', '/bower_components/chainpad/chainpad.dist.js',
], function (Util, Hash, Constants, Realtime, Listmap, Crypto, ChainPad) { ], function (Util, Hash, Constants, Realtime, Listmap, Crypto, ChainPad) {

@ -918,7 +918,7 @@ var factory = function (Util, Hash, CPNetflux, Sortify, nThen, Crypto, Feedback)
define([ define([
'/common/common-util.js', '/common/common-util.js',
'/common/common-hash.js', '/common/common-hash.js',
'/bower_components/chainpad-netflux/chainpad-netflux.js', 'chainpad-netflux',
'json.sortify', 'json.sortify',
'/bower_components/nthen/index.js', '/bower_components/nthen/index.js',
'/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad-crypto/crypto.js',

@ -6,7 +6,7 @@ define([
'/bower_components/nthen/index.js', '/bower_components/nthen/index.js',
'/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad-crypto/crypto.js',
'/bower_components/chainpad-listmap/chainpad-listmap.js', 'chainpad-listmap',
'/bower_components/chainpad/chainpad.dist.js', '/bower_components/chainpad/chainpad.dist.js',
], function (Hash, Util, UserObject, Cache, ], function (Hash, Util, UserObject, Cache,
nThen, Crypto, Listmap, ChainPad) { nThen, Crypto, Listmap, ChainPad) {

@ -14,9 +14,9 @@ define([
'/common/cryptget.js', '/common/cryptget.js',
'/common/outer/cache-store.js', '/common/outer/cache-store.js',
'/bower_components/chainpad-listmap/chainpad-listmap.js', 'chainpad-listmap',
'/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad-crypto/crypto.js',
'/bower_components/chainpad-netflux/chainpad-netflux.js', 'chainpad-netflux',
'/bower_components/chainpad/chainpad.dist.js', '/bower_components/chainpad/chainpad.dist.js',
'/bower_components/nthen/index.js', '/bower_components/nthen/index.js',
'/bower_components/saferphore/index.js', '/bower_components/saferphore/index.js',

@ -16,6 +16,9 @@ define([
cm: '/bower_components/codemirror', cm: '/bower_components/codemirror',
'tui-code-snippet': '/lib/calendar/tui-code-snippet.min', 'tui-code-snippet': '/lib/calendar/tui-code-snippet.min',
'tui-date-picker': '/lib/calendar/date-picker', 'tui-date-picker': '/lib/calendar/date-picker',
'netflux-client': '/bower_components/netflux-websocket/netflux-client',
'chainpad-netflux': '/bower_components/chainpad-netflux/chainpad-netflux',
'chainpad-listmap': '/bower_components/chainpad-listmap/chainpad-listmap',
}, },
map: { map: {
'*': { '*': {

@ -11,10 +11,12 @@ define([
'/common/hyperscript.js', '/common/hyperscript.js',
'/customize/messages.js', '/customize/messages.js',
'/customize/pages.js', '/customize/pages.js',
'/bower_components/nthen/index.js',
'/common/media-tag.js',
'/bower_components/file-saver/FileSaver.min.js', '/bower_components/file-saver/FileSaver.min.js',
'/bower_components/tweetnacl/nacl-fast.min.js', '/bower_components/tweetnacl/nacl-fast.min.js',
], function ($, ApiConfig, FileCrypto, MakeBackup, Thumb, UI, UIElements, Util, Hash, h, Messages, Pages) { ], function ($, ApiConfig, FileCrypto, MakeBackup, Thumb, UI, UIElements, Util, Hash, h, Messages, Pages, nThen, MT) {
var Nacl = window.nacl; var Nacl = window.nacl;
var module = {}; var module = {};
@ -312,7 +314,8 @@ define([
}); });
return manualStore; return manualStore;
}; };
var fileUploadModal = function (defaultFileName, cb) {
var fileUploadModal = function (defaultFileName, cb, preview) {
var parsedName = /^(\.?.+?)(\.[^.]+)?$/.exec(defaultFileName) || []; var parsedName = /^(\.?.+?)(\.[^.]+)?$/.exec(defaultFileName) || [];
var ext = parsedName[2] || ""; var ext = parsedName[2] || "";
@ -321,9 +324,14 @@ define([
// Ask for name, password and owner // Ask for name, password and owner
var content = h('div', [ var content = h('div', [
h('h4', Messages.upload_modal_title), h('h4', Messages.upload_modal_title),
(preview? h('div#cp-upload-preview-container', preview): undefined),
UIElements.setHTML(h('label', {for: 'cp-upload-name'}), UIElements.setHTML(h('label', {for: 'cp-upload-name'}),
Messages._getKey('upload_modal_filename', [ext])), Messages._getKey('upload_modal_filename', [ext])),
h('input#cp-upload-name', {type: 'text', placeholder: defaultFileName, value: defaultFileName}), h('input#cp-upload-name', {type: 'text', placeholder: defaultFileName, value: defaultFileName}),
h('label', {for: 'cp-upload-alt'}, Messages.upload_addOptionalAlt),
h('input#cp-upload-alt', {type: 'text', placeholder: Messages.upload_modal_alt}),
h('label', {for: 'cp-upload-password'}, Messages.addOptionalPassword), h('label', {for: 'cp-upload-password'}, Messages.addOptionalPassword),
UI.passwordInput({id: 'cp-upload-password'}), UI.passwordInput({id: 'cp-upload-password'}),
h('span', { h('span', {
@ -335,7 +343,8 @@ define([
manualStore manualStore
]); ]);
$(content).find('#cp-upload-owned').on('change', function () { var $content = $(content);
$content.find('#cp-upload-owned').on('change', function () {
var val = Util.isChecked($(content).find('#cp-upload-owned')); var val = Util.isChecked($(content).find('#cp-upload-owned'));
if (val) { if (val) {
$(content).find('#cp-upload-store').prop('checked', true).prop('disabled', true); $(content).find('#cp-upload-store').prop('checked', true).prop('disabled', true);
@ -348,8 +357,9 @@ define([
if (!yes) { return void cb(); } if (!yes) { return void cb(); }
// Get the values // Get the values
var newName = $(content).find('#cp-upload-name').val(); var newName = $content.find('#cp-upload-name').val();
var password = $(content).find('#cp-upload-password').val() || undefined; var password = $content.find('#cp-upload-password').val() || undefined;
var alt = $content.find('#cp-upload-alt').val() || undefined;
var owned = Util.isChecked($(content).find('#cp-upload-owned')); var owned = Util.isChecked($(content).find('#cp-upload-owned'));
var forceSave = owned || Util.isChecked($(content).find('#cp-upload-store')); var forceSave = owned || Util.isChecked($(content).find('#cp-upload-store'));
@ -366,7 +376,8 @@ define([
name: newName, name: newName,
password: password, password: password,
owned: owned, owned: owned,
forceSave: forceSave forceSave: forceSave,
alt: alt,
}); });
}); });
}; };
@ -437,6 +448,8 @@ define([
} }
var thumb; var thumb;
var preview;
var alt;
var file_arraybuffer; var file_arraybuffer;
var name = file.name; var name = file.name;
var password; var password;
@ -447,6 +460,7 @@ define([
var metadata = { var metadata = {
name: name, name: name,
type: type, type: type,
alt: alt,
}; };
if (thumb) { metadata.thumbnail = thumb; } if (thumb) { metadata.thumbnail = thumb; }
queue.push({ queue.push({
@ -486,8 +500,9 @@ define([
password = obj.password; password = obj.password;
owned = obj.owned; owned = obj.owned;
forceSave = obj.forceSave; forceSave = obj.forceSave;
alt = obj.alt;
finish(); finish();
}); }, preview);
} }
}; };
@ -495,11 +510,20 @@ define([
if (e) { console.error(e); } if (e) { console.error(e); }
file_arraybuffer = buffer; file_arraybuffer = buffer;
if (!Thumb.isSupportedType(file)) { return getName(); } if (!Thumb.isSupportedType(file)) { return getName(); }
// make a resized thumbnail from the image.. nThen(function (w) {
Thumb.fromBlob(file, function (e, thumb64) { // make a resized thumbnail from the image..
if (e) { console.error(e); } Thumb.fromBlob(file, w(function (e, thumb64) {
if (!thumb64) { return getName(); } if (e) { console.error(e); }
thumb = thumb64; if (!thumb64) { return; }
thumb = thumb64;
}));
MT.preview(buffer, {
type: file.type,
}, void 0, w(function (err, el) {
if (err) { return void console.error(err); }
preview = el;
}));
}).nThen(function () {
getName(); getName();
}); });
}); });

@ -618,6 +618,7 @@ define([
prefersDriveRedirect: Utils.LocalStore.getDriveRedirectPreference(), prefersDriveRedirect: Utils.LocalStore.getDriveRedirectPreference(),
isPresent: parsed.hashData && parsed.hashData.present, isPresent: parsed.hashData && parsed.hashData.present,
isEmbed: parsed.hashData && parsed.hashData.embed, isEmbed: parsed.hashData && parsed.hashData.embed,
canEdit: hashes && hashes.editHash,
oldVersionHash: parsed.hashData && parsed.hashData.version < 2, // password oldVersionHash: parsed.hashData && parsed.hashData.version < 2, // password
isHistoryVersion: parsed.hashData && parsed.hashData.versionHash, isHistoryVersion: parsed.hashData && parsed.hashData.versionHash,
notifications: notifs, notifications: notifs,
@ -1749,6 +1750,22 @@ define([
}); });
}); });
sframeChan.on('Q_COPY_VIEW_URL', function (data, cb) {
require(['/common/clipboard.js'], function (Clipboard) {
var url = window.location.origin +
Utils.Hash.hashToHref(hashes.viewHash, 'form');
var success = Clipboard.copy(url);
cb(success);
});
});
sframeChan.on('EV_OPEN_VIEW_URL', function () {
var url = Utils.Hash.hashToHref(hashes.viewHash, 'form');
var a = window.open(url);
if (!a) {
sframeChan.event('EV_POPUP_BLOCKED');
}
});
if (cfg.messaging) { if (cfg.messaging) {
sframeChan.on('Q_CHAT_OPENPADCHAT', function (data, cb) { sframeChan.on('Q_CHAT_OPENPADCHAT', function (data, cb) {
Cryptpad.universal.execCommand({ Cryptpad.universal.execCommand({

@ -235,9 +235,6 @@ define([
}; };
}; };
funcs.getAuthorId = function () {
};
var authorUid = function(existing) { var authorUid = function(existing) {
if (!Array.isArray(existing)) { existing = []; } if (!Array.isArray(existing)) { existing = []; }
var n; var n;
@ -249,11 +246,25 @@ define([
if (existing.indexOf(n) !== -1) { n = 0; } if (existing.indexOf(n) !== -1) { n = 0; }
return n; return n;
}; };
funcs.getAuthorId = function(authors, curve) { funcs.getAuthorId = function(authors, curve, tokenId) {
var existing = Object.keys(authors || {}).map(Number); var existing = Object.keys(authors || {}).map(Number);
if (!funcs.isLoggedIn()) { return authorUid(existing); }
var uid; var uid;
var loggedIn = funcs.isLoggedIn();
if (!loggedIn && !tokenId) { return authorUid(existing); }
if (!loggedIn) {
existing.some(function (id) {
var author = authors[id];
if (!author || author.uid !== tokenId) { return; }
uid = Number(id);
return true;
});
return uid || authorUid(existing);
}
// TODO this should check for a matching curvePublic / uid if:
// 1. you are logged in OR
// 2. you have a token
// so that users that register recognize comments from before
// they registered as their own (same uid)
existing.some(function(id) { existing.some(function(id) {
var author = authors[id] || {}; var author = authors[id] || {};
if (author.curvePublic !== curve) { return; } if (author.curvePublic !== curve) { return; }
@ -921,9 +932,10 @@ define([
}); });
ctx.sframeChan.on('EV_WORKER_TIMEOUT', function () { ctx.sframeChan.on('EV_WORKER_TIMEOUT', function () {
UI.errorLoadingScreen(Messages.timeoutError, false, function () { // XXX 4.11.0 mobile users can't necessarily hit 'ESC' as this message suggests. provice a click option var message = UI.setHTML(h('span'), Messages.timeoutError);
funcs.gotoURL(''); var cb = Util.once(function () { funcs.gotoURL(''); });
}); $(message).find('em').on('touchend', cb);
UI.errorLoadingScreen(message, false, cb);
}); });
ctx.sframeChan.on('EV_CHROME_68', function () { ctx.sframeChan.on('EV_CHROME_68', function () {

@ -65,7 +65,9 @@ MessengerUI, Messages, Pages) {
if (!config.$container) { return; } if (!config.$container) { return; }
var $container = config.$container; var $container = config.$container;
var isEmbed = Bar.isEmbed = config.metadataMgr.getPrivateData().isEmbed; var priv = config.metadataMgr.getPrivateData();
var isEmbed = Bar.isEmbed = priv.isEmbed ||
(priv.app === 'form' && priv.readOnly && !priv.form_auditorHash);
if (isEmbed) { if (isEmbed) {
$container.hide(); $container.hide();
} }
@ -249,6 +251,7 @@ MessengerUI, Messages, Pages) {
var friendRequests = Common.getFriendRequests(); // Friend requests received var friendRequests = Common.getFriendRequests(); // Friend requests received
editUsersNames.forEach(function (data) { editUsersNames.forEach(function (data) {
var name = data.name || Messages.anonymous; var name = data.name || Messages.anonymous;
var safeName = Util.fixHTML(name);
var $span = $('<span>', {'class': 'cp-avatar'}); var $span = $('<span>', {'class': 'cp-avatar'});
if (data.color && showColors) { if (data.color && showColors) {
$span.css('border-color', data.color); $span.css('border-color', data.color);
@ -323,7 +326,7 @@ MessengerUI, Messages, Pages) {
$('<button>', { $('<button>', {
'class': 'fa fa-bell cp-toolbar-userlist-button', 'class': 'fa fa-bell cp-toolbar-userlist-button',
'data-cptippy-html': true, 'data-cptippy-html': true,
'title': Messages._getKey('friendRequest_received', [Util.fixHTML(name)]), 'title': Messages._getKey('friendRequest_received', [safeName]),
}).appendTo($nameSpan).click(function (e) { }).appendTo($nameSpan).click(function (e) {
e.stopPropagation(); e.stopPropagation();
UIElements.displayFriendRequestModal(Common, friendRequests[data.curvePublic]); UIElements.displayFriendRequestModal(Common, friendRequests[data.curvePublic]);
@ -334,7 +337,7 @@ MessengerUI, Messages, Pages) {
'class': 'fa fa-user-plus cp-toolbar-userlist-button', 'class': 'fa fa-user-plus cp-toolbar-userlist-button',
'data-cptippy-html': true, 'data-cptippy-html': true,
'title': Messages._getKey('userlist_addAsFriendTitle', [ 'title': Messages._getKey('userlist_addAsFriendTitle', [
Util.fixHTML(name) safeName,
]) ])
}).appendTo($nameSpan).click(function (e) { }).appendTo($nameSpan).click(function (e) {
e.stopPropagation(); e.stopPropagation();
@ -356,14 +359,16 @@ MessengerUI, Messages, Pages) {
}); });
} }
if (data.profile) { if (data.profile) {
// Messages.contacts_info3 "Double-click their icon to view their profile",
$span.addClass('cp-userlist-clickable'); $span.addClass('cp-userlist-clickable');
$span.attr('title', Messages._getKey('userlist_visitProfile', [name]));
$span.click(function () { $span.click(function () {
Common.openURL(origin+'/profile/#' + data.profile); Common.openURL(origin+'/profile/#' + data.profile);
}); });
} }
Common.displayAvatar($span, data.avatar, name, function () { Common.displayAvatar($span, data.avatar, name, function () {
$span.append($rightCol); $span.append($rightCol);
}); }, data.uid);
$span.data('uid', data.uid); $span.data('uid', data.uid);
$editUsersList.append($span); $editUsersList.append($span);
}); });
@ -456,8 +461,8 @@ MessengerUI, Messages, Pages) {
}; };
createCollapse = function (toolbar) { createCollapse = function (toolbar) {
var up = h('i.fa.fa-chevron-up', {title: Messages.ui_collapse}); var up = h('i.fa.fa-chevron-up', {title: Messages.toolbar_collapse});
var down = h('i.fa.fa-chevron-down', {title: Messages.ui_expand}); var down = h('i.fa.fa-chevron-down', {title: Messages.toolbar_expand});
var $button = $(h('button.cp-toolbar-collapse',[ var $button = $(h('button.cp-toolbar-collapse',[
up, up,
@ -1039,24 +1044,10 @@ MessengerUI, Messages, Pages) {
userMenuCfg.displayName = 1; userMenuCfg.displayName = 1;
userMenuCfg.displayChangeName = 1; userMenuCfg.displayChangeName = 1;
} }
/*if (config.displayed.indexOf('userlist') !== -1) {
userMenuCfg.displayChangeName = 0;
}*/
Common.createUserAdminMenu(userMenuCfg); Common.createUserAdminMenu(userMenuCfg);
$userAdmin.find('> button').attr('title', Messages.userAccountButton); $userAdmin.find('> button').attr({
title: Messages.userAccountButton,
var $userButton = toolbar.$userNameButton = $userAdmin.find('a.' + USERBUTTON_CLS); alt: Messages.userAccountButton,
$userButton.click(function (e) {
e.preventDefault();
e.stopPropagation();
var myData = metadataMgr.getUserData();
var lastName = myData.name;
UI.prompt(Messages.changeNamePrompt, lastName || '', function (newName) {
if (newName === null && typeof(lastName) === "string") { return; }
if (newName === null) { newName = ''; }
else { Feedback.send('NAME_CHANGED'); }
setDisplayName(newName);
});
}); });
return $userAdmin; return $userAdmin;
@ -1232,18 +1223,31 @@ MessengerUI, Messages, Pages) {
} }
}; };
var getFancyGuestName = function (name, uid) {
name = UI.getDisplayName(name);
if (name === Messages.anonymous && uid) {
var animal = MT.getPseudorandomAnimal(uid);
if (animal) {
name = animal + ' ' + name;
}
}
return name;
};
// Notifications // Notifications
var initNotifications = function (toolbar, config) { var initNotifications = function (toolbar, config) {
// Display notifications when users are joining/leaving the session // Display notifications when users are joining/leaving the session
var oldUserData; var oldUserData;
if (!config.metadataMgr) { return; } if (!config.metadataMgr) { return; }
var metadataMgr = config.metadataMgr; var metadataMgr = config.metadataMgr;
var notify = function(type, name, oldname) { var notify = function(type, name, oldname, uid) {
if (toolbar.isAlone) { return; } if (toolbar.isAlone) { return; }
// type : 1 (+1 user), 0 (rename existing user), -1 (-1 user) // type : 1 (+1 user), 0 (rename existing user), -1 (-1 user)
if (typeof name === "undefined") { return; } if (typeof name === "undefined") { return; }
name = name || Messages.anonymous;
if (Config.disableUserlistNotifications) { return; } if (Config.disableUserlistNotifications) { return; }
name = getFancyGuestName(name, uid);
oldname = getFancyGuestName(oldname, uid);
switch(type) { switch(type) {
case 1: case 1:
UI.log(Messages._getKey("notifyJoined", [name])); UI.log(Messages._getKey("notifyJoined", [name]));
@ -1292,7 +1296,7 @@ MessengerUI, Messages, Pages) {
delete oldUserData[u]; delete oldUserData[u];
if (temp && newdata[userNetfluxId] && temp.uid === newdata[userNetfluxId].uid) { return; } if (temp && newdata[userNetfluxId] && temp.uid === newdata[userNetfluxId].uid) { return; }
if (userPresent(u, temp, newdata || oldUserData) < 1) { if (userPresent(u, temp, newdata || oldUserData) < 1) {
notify(-1, temp.name); notify(-1, temp.name, undefined, temp.uid);
} }
} }
} }
@ -1312,10 +1316,10 @@ MessengerUI, Messages, Pages) {
if (typeof oldUserData[k] === "undefined") { if (typeof oldUserData[k] === "undefined") {
// if the same uid is already present in the userdata, don't notify // if the same uid is already present in the userdata, don't notify
if (!userPresent(k, newdata[k], oldUserData)) { if (!userPresent(k, newdata[k], oldUserData)) {
notify(1, newdata[k].name); notify(1, newdata[k].name, undefined, newdata[k].uid);
} }
} else if (oldUserData[k].name !== newdata[k].name) { } else if (oldUserData[k].name !== newdata[k].name) {
notify(0, newdata[k].name, oldUserData[k].name); notify(0, newdata[k].name, oldUserData[k].name, newdata[k].uid);
} }
} }
} }

@ -62,7 +62,6 @@ define([
} }
var configTb = { var configTb = {
displayed: displayed, displayed: displayed,
//hideDisplayName: true,
$container: $bar, $container: $bar,
metadataMgr: metadataMgr, metadataMgr: metadataMgr,
sfCommon: common, sfCommon: common,

@ -10,12 +10,88 @@
@bg-color: @colortheme_apps[form] @bg-color: @colortheme_apps[form]
); );
@cp_form_bar_color: fade(@cryptpad_color_link, 75%); // Color for the response chart bars
display: flex; display: flex;
flex-flow: column; flex-flow: column;
font: @colortheme_app-font; font: @colortheme_app-font;
color: @cryptpad_text_col; color: @cryptpad_text_col;
background-color: @cp_app-bg; background-color: @cp_app-bg;
.alert {
font-size: 1rem;
&.alert-info {
color: @cryptpad_text_col !important;
}
}
@palette0: @cp_kanban-color0; // Default bg color for header
@form-colors: @cp_form-palette;
.form-colors(@form-colors; @index) when (@index > 0){
.form-colors(@form-colors; (@index - 1));
@color: extract(@form-colors, @index);
.cp-form-palette-color@{index}{
&.cp-form-palette {
background-color: @color !important;
}
}
&.cp-form-palette-color@{index}{
#cp-app-form-editor {
background-color: fade(@color, 50%);
}
}
}
.form-colors(@form-colors; length(@form-colors));
@form-colors2: @cp_form-palette2;
.checkmark-colors(@form-colors2; @index) when (@index > 0){
.checkmark-colors(@form-colors2; (@index - 1));
@color: extract(@form-colors2, @index);
&.cp-form-palette-color@{index}{
.cp-form-block {
.cp-radio input:checked ~ .cp-radio-mark, .cp-checkmark input:checked ~ .cp-checkmark-mark {
background-color: @color !important;
border-color: @color !important;
}
input, textarea {
border-color: @color !important;
}
}
.cp-form-block-question-text, .cp-form-block-question-number {
color: @color !important;
}
.cp-form-type-sort:hover {
color: @color !important;
.cp-form-sort-order {
border-color: @color !important;
}
}
.cp-form-input-block {
input { color: @color !important; }
border-bottom-color: @color !important;
}
}
}
.checkmark-colors(@form-colors2; length(@form-colors2));
.cp-form-palette {
&.cp-form-palette-nocolor {
background-color: @palette0 !important;
}
}
&.cp-form-palette-nocolor {
background-color: @cp_app-bg !important;
}
div.alert.cp-burn-after-reading {
margin: 10px !important;
}
& > .flatpickr-calendar {
animation: none !important;
-webkit-animation: none !important;
}
#cp-app-form-editor { #cp-app-form-editor {
flex: 1; flex: 1;
display: flex; display: flex;
@ -54,7 +130,7 @@
.cp-form-block { .cp-form-block {
cursor: default !important; cursor: default !important;
.cp-form-block-drag-handle { .cp-form-block-drag-handle {
display: none !important; visibility: hidden;
} }
} }
} }
@ -78,6 +154,28 @@
display: flex; display: flex;
} }
.cp-form-view-title {
margin-bottom: 20px;
}
div.cp-form-view-footer {
display: flex;
align-items: center;
justify-content: center;
padding: 20px 20px 150px 20px;
div.cp-form-view-logo {
padding: 10px;
font-size: 40px;
font-family: "IBM Plex Mono";
.tools_unselectable();
color: @cryptpad_color_grey_500;
cursor: pointer;
img {
max-height: 60px;
margin: 0px 20px;
}
}
}
div.cp-form-creator-container { div.cp-form-creator-container {
display: flex; display: flex;
flex: 1; flex: 1;
@ -93,20 +191,72 @@
width: 100% !important; width: 100% !important;
.cp-form-creator-settings { .cp-form-creator-settings {
display: flex; display: flex;
justify-content: space-evenly; justify-content: space-between;
flex-wrap: wrap; flex-wrap: wrap;
& > div {
flex-basis: 33.333333%;
padding-right: 20px;
}
}
}
}
@media screen and (max-width: 600px) and (min-width: 400px) {
.cp-form-creator-settings {
& > div {
flex-basis: 50% !important;
}
}
}
@media screen and (max-width: 400px) {
.cp-form-creator-settings {
& > div {
flex-basis: 100% !important;
} }
} }
} }
.cp-form-creator-settings { .cp-form-creator-settings {
padding: 30px;
.cp-form-actions { .cp-form-actions {
margin-top: 5px; margin-top: 5px;
} }
& > div:not(:last-child) { & > div:not(:last-child) {
margin-bottom: 20px; margin-bottom: 20px;
} }
.cp-forms-results-participant {
display: flex;
flex-flow: column;
button {
margin-bottom: 20px;
}
}
.cp-form-color-container {
& > div {
display: flex;
justify-content: space-between;
margin-top: 5px;
&:last-child {
justify-content: space-evenly;
}
.cp-form-palette {
display: inline-block;
border-radius: 50%;
height: 30px;
width: 30px;
text-align: center;
line-height: 30px;
color: @cp_kanban-fg;
border: 1px solid fade(@cp_kanban-fg, 40%);
cursor: pointer;
}
}
}
.cp-form-response-msg-container button {
white-space: initial;
line-height: 25px;
padding: 5.5px 6px;
}
} }
div.cp-form-filler-container { div.cp-form-filler-container {
width: 300px; width: 300px;
@ -115,6 +265,7 @@
} }
div.cp-form-creator-control { div.cp-form-creator-control {
padding: 10px; padding: 10px;
margin-top: 10px;
display: flex; display: flex;
flex-flow: column; flex-flow: column;
width: 300px; width: 300px;
@ -124,6 +275,74 @@
flex-flow: column; flex-flow: column;
} }
} }
div.cp-form-creator-content {
.cp-form-block-type {
margin-top: -35px;
&.editable {
cursor: pointer;
}
.fa-caret-down {
margin-left: 5px;
}
}
.cp-form-conditional {
.cp-form-conditional-hint {
margin-bottom: 10px;
}
.cp-form-condition {
display: flex;
align-items: center;
margin-bottom: 10px;
flex-wrap: wrap;
& > * {
margin-right: 10px;
}
.cp-dropdown-container button {
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.cp-form-condition-rule {
padding-bottom: 20px;
margin-bottom: 20px;
border-bottom: 1px solid @cryptpad_text_col;
}
}
div.cp-form-section-sortable {
min-height: 300px;
border: 2px dashed @cryptpad_text_col;
padding: 20px;
margin-top: 20px;
background: @cp_app-bg;
.cp-form-creator-add-inline {
button[data-type="section"] {
display: none;
}
}
}
}
div.cp-form-creator-results {
.cp-form-block {
.cp-form-block-content {
overflow-x: auto;
}
}
.cp-form-creator-results-timeline {
margin-bottom: 20px;
table.cp-charts.column {
overflow-x: initial;
td {
background-color: @cp_form_bar_color;
border-color: @cp_form_bar_color;
}
}
}
}
div.cp-form-creator-content, div.cp-form-creator-results { div.cp-form-creator-content, div.cp-form-creator-results {
max-width: 1000px; max-width: 1000px;
min-width: 300px; min-width: 300px;
@ -242,6 +461,7 @@
color: @cp_form-invalid; color: @cp_form-invalid;
ul { ul {
list-style-type: disclosure-closed; list-style-type: disclosure-closed;
margin-bottom: 5px;
} }
li { li {
text-align: left; text-align: left;
@ -249,6 +469,10 @@
color: @cryptpad_color_link; color: @cryptpad_color_link;
} }
} }
.alert-danger {
font-size: 1rem;
padding: 10px;
}
} }
.cp-form-anon-answer { .cp-form-anon-answer {
text-align: center; text-align: center;
@ -262,6 +486,10 @@
margin-left: 10px; margin-left: 10px;
} }
} }
.cp-form-anon-answer-registered {
font-style: italic;
margin-left: 10px;
}
} }
} }
@ -289,13 +517,27 @@
.cp-form-block { .cp-form-block {
background: @cp_form-bg1; background: @cp_form-bg1;
padding: 10px; padding: 10px;
box-shadow: 0px 0px 15px @cp_shadow-color;
&:not(:last-child) { &:not(:last-child) {
margin-bottom: 20px; margin-bottom: 20px;
} }
.cp-form-disabled {
.cp-form-poll-choice, .cp-form-type-sort {
cursor: not-allowed !important;
}
}
.cp-form-preview {
color: @cp_sidebar-hint;
margin-bottom: 10px;
padding: 0;
}
.cp-form-block-drag-handle { .cp-form-block-drag-handle {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
height: 25px;
align-items: center; align-items: center;
color: @cp_sidebar-hint; color: @cp_sidebar-hint;
i { i {
@ -318,18 +560,43 @@
.cp-form-block-question { .cp-form-block-question {
margin-bottom: 5px; margin-bottom: 5px;
display: flex;
.cp-form-block-question-number { .cp-form-block-question-number {
font-weight: bold; font-weight: bold;
margin-right: 10px; margin-right: 10px;
} }
.cp-form-block-question-text {
flex: 1;
}
.cp-form-required-tag {
background: fade(@cryptpad_text_col, 15%);
padding: 5px;
margin-top: -10px;
margin-right: -10px;
&.cp-is-empty {
padding: 3px;
border: 2px solid @cryptpad_color_red;
color: @cp_form-invalid;
}
}
} }
.cp-form-block-content { .cp-form-block-content {
overflow-x: auto;
p { p {
a { a {
color: @cryptpad_color_link; color: @cryptpad_color_link;
} }
} }
.cp-form-required-radio {
flex-direction: row;
display: flex;
margin-bottom: 20px;
span {
margin-right: 10px;
&.cp-radio-mark {
margin-right: 5px;
}
}
}
.cp-form-page-break-edit { .cp-form-page-break-edit {
font-size: 20px; font-size: 20px;
text-align: center; text-align: center;
@ -440,7 +707,12 @@
} }
} }
.cp-form-edit-block { .cp-form-edit-block {
&.cp-no-sortable {
.cp-form-handle {
visibility: hidden;
cursor: default;
}
}
button.btn-secondary { button.btn-secondary {
margin-left: 30px; margin-left: 30px;
margin-bottom: 5px; margin-bottom: 5px;
@ -475,6 +747,22 @@
} }
} }
} }
div.cp-form-creator-answered {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
flex-flow: column;
.cp-form-submit-actions {
button:not(:last-child) {
margin-right: 10px;
}
}
.cp-form-view-logo {
margin-top: 100px;
padding-bottom: 20px;
}
}
div.cp-form-creator-results { div.cp-form-creator-results {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
@ -487,11 +775,13 @@
p:last-child { p:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
* {
max-width: 100%;
}
} }
.cp-form-creator-results-controls { .cp-form-creator-results-controls {
margin-bottom: 20px; margin-bottom: 20px;
margin-top: 20px;
//background: @cp_form-bg1; //background: @cp_form-bg1;
//padding: 10px; //padding: 10px;
button { button {
@ -502,21 +792,13 @@
.cp-form-creator-results-content { .cp-form-creator-results-content {
padding-bottom: 100px; padding-bottom: 100px;
.cp-form-block { .cp-form-block {
background: @cp_form-bg1; background: @cp_form-bg1;
padding: 10px; padding: 10px;
} }
} }
.cp-form-block-question { .cp-form-block-question {
margin-bottom: 5px; margin-bottom: 5px;
} }
.cp-form-block-type {
float: right;
padding: 5px;
margin-top: -10px;
margin-right: -10px;
i { margin-right: 5px; }
background: fade(@cryptpad_text_col, 15%);
}
.cp-form-results-type-text { .cp-form-results-type-text {
max-height: 300px; max-height: 300px;
overflow: auto; overflow: auto;
@ -532,36 +814,52 @@
background: @cp_form-bg2; background: @cp_form-bg2;
&:not(:last-child) { margin-bottom: 1px; } &:not(:last-child) { margin-bottom: 1px; }
} }
.cp-form-results-type-radio {
display: table; .cp-form-results-cell() {
.cp-form-results-type-multiradio-data { border: 1px solid @cp_form-border;
display: flex; display: table-cell;
flex-flow: column; padding: 5px 10px;
background: @cp_form-bg2;
}
.cp-form-results-type-multiradio-data {
.cp-mr-q {
font-weight: bold;
padding: 5px 10px;
.cp-form-results-cell();
background: transparent;
} }
.cp-form-results-type-radio-data { &:not(:first-child) {
display: table-row; .cp-mr-q {
border: 1px solid @cp_form-border; margin-top: 15px;
& > span { }
border: 1px solid @cp_form-border; }
display: table-cell; }
padding: 5px 10px;
background: @cp_form-bg2; .cp-charts {
&.cp-value { .cp-charts-row {
min-width: 200px; .cp-grid-sub-question {
} background: transparent;
&.cp-bar-container { }
width: 99%; .cp-value {
padding: 0px; min-width: 200px;
position: relative; max-width: 200px;
.cp-bar { white-space: nowrap;
position: absolute; overflow: hidden;
background: @cryptpad_color_brand; text-overflow: ellipsis;
height: 100%; }
} .cp-bar-container {
.cp-bar {
background-color: @cp_form_bar_color;
} }
} }
} }
} }
.cp-form-results-contained {
max-height: 350px; // enough for 10 table entries
overflow: auto;
}
.cp-form-individual { .cp-form-individual {
background: @cp_form-bg1; background: @cp_form-bg1;
padding: 10px; padding: 10px;
@ -583,6 +881,14 @@
} }
} }
} }
.cp-form-block-type {
float: right;
padding: 5px;
margin-top: -10px;
margin-right: -10px;
i { margin-right: 5px; }
background: fade(@cryptpad_text_col, 10%);
}
} }
.cp-form-type-radio, .cp-form-type-checkbox { .cp-form-type-radio, .cp-form-type-checkbox {
@ -813,6 +1119,11 @@
color: @cp_form-poll-yes-color; color: @cp_form-poll-yes-color;
} }
} }
.cp-form-response-modal {
.CodeMirror {
border: 1px solid @cp_forms-border;
}
}
.charts_main(); .charts_main();
} }

File diff suppressed because it is too large Load Diff

@ -125,7 +125,7 @@ define([
var noDriveAnswered = false; var noDriveAnswered = false;
nThen(function (w) { nThen(function (w) {
require([ require([
'/bower_components/chainpad-netflux/chainpad-netflux.js', 'chainpad-netflux',
'/common/pinpad.js', '/common/pinpad.js',
], w(function (_CPNetflux, _Pinpad) { ], w(function (_CPNetflux, _Pinpad) {
CPNetflux = _CPNetflux; CPNetflux = _CPNetflux;
@ -176,7 +176,7 @@ define([
validateKey: keys.secondaryValidateKey, validateKey: keys.secondaryValidateKey,
owners: [myKeys.edPublic], owners: [myKeys.edPublic],
crypto: crypto, crypto: crypto,
//Cache: Utils.Cache // XXX 4.11.0 //Cache: Utils.Cache // TODO enable cache for form responses when the cache stops evicting old answers
}; };
var results = {}; var results = {};
config.onError = function (info) { config.onError = function (info) {
@ -221,6 +221,7 @@ define([
delete results[parsed._proof.key]; delete results[parsed._proof.key];
} }
} }
if (data.cantEdit && results[senderCurve]) { return; }
results[senderCurve] = { results[senderCurve] = {
msg: parsed, msg: parsed,
hash: hash, hash: hash,
@ -266,14 +267,21 @@ define([
if (obj && obj.error) { return void cb(obj); } if (obj && obj.error) { return void cb(obj); }
var messages = obj.messages; var messages = obj.messages;
if (!messages.length) { return void cb(); } if (!messages.length) { return void cb(); }
var res = Utils.Crypto.Mailbox.openOwnSecretLetter(messages[0].msg, { if (obj.lastKnownHash !== answer.hash) { return void cb(); }
validateKey: data.validateKey, try {
ephemeral_private: Nacl.util.decodeBase64(answer.curvePrivate), var res = Utils.Crypto.Mailbox.openOwnSecretLetter(messages[0].msg, {
my_private: Nacl.util.decodeBase64(myKeys.curvePrivate), validateKey: data.validateKey,
their_public: Nacl.util.decodeBase64(data.publicKey) ephemeral_private: Nacl.util.decodeBase64(answer.curvePrivate),
}); my_private: Nacl.util.decodeBase64(myKeys.curvePrivate),
res.content._isAnon = answer.anonymous; their_public: Nacl.util.decodeBase64(data.publicKey)
cb(JSON.parse(res.content)); });
var parsed = JSON.parse(res.content);
parsed._isAnon = answer.anonymous;
parsed._time = messages[0].time;
cb(parsed);
} catch (e) {
cb({error: e});
}
}); });
}); });

@ -1,17 +1,43 @@
define([ define([
'/customize/messages.js' '/customize/messages.js'
], function (Messages) { ], function (Messages) {
var pollValues = [];
var d8 = new Date();
d8.setDate(d8.getDate() - d8.getDay() + 7); // set sunday
d8.setHours(8);
d8.setMinutes(0);
d8.setSeconds(0);
d8.setMilliseconds(0);
var d14 = new Date(d8);
d14.setHours(14);
[0,1,2].forEach(function (el) {
d8.setDate(d8.getDate() + 1);
d14.setDate(d14.getDate() + 1);
if (el === 2) {
d8.setHours(10);
}
pollValues.push(+d8);
if (el === 2) { return; }
pollValues.push(+d14);
});
return [{ return [{
id: 'a', id: 'a',
used: 1, used: 1,
name: Messages.form_type_poll, name: Messages.form_template_poll,
content: { content: {
answers: {
anonymous: true,
},
form: { form: {
"1": { "1": {
type: 'md' type: 'md'
}, },
"2": { "2": {
type: 'poll' type: 'poll',
opts: {
type: 'time',
values: pollValues
}
} }
}, },
order: ["1", "2"] order: ["1", "2"]

@ -159,6 +159,14 @@
margin-right: 5px; margin-right: 5px;
.tools_unselectable(); .tools_unselectable();
cursor: default; cursor: default;
&.cp-cursor.cp-tippy-html {
.avatar_vars(20px);
background-color: var(--red);
font-size: @avatar-font-size;
&.animal {
font-size: @avatar-font-size-animal;
}
}
} }
} }
.kanban-item { .kanban-item {

@ -97,16 +97,28 @@ define([
// Tippy // Tippy
var html = MT.getCursorAvatar(cursor); var html = MT.getCursorAvatar(cursor);
var l = Util.getFirstCharacter(cursor.name || Messages.anonymous); var name = UI.getDisplayName(cursor.name);
var l; // label?
var animal = '';
if (cursor.name === Messages.anonymous && typeof(cursor.uid) === 'string') {
l = MT.getPseudorandomAnimal(cursor.uid);
if (l) {
animal = '.animal';
}
}
if (!l) {
l = MT.getPrettyInitials(name);
}
var text = ''; var text = '';
if (cursor.color) { if (cursor.color) {
text = 'color:'+getTextColor(cursor.color)+';'; text = 'background-color:' + cursor.color + '; color:'+getTextColor(cursor.color)+';';
} }
var avatar = h('span.cp-cursor.cp-tippy-html', { var avatar = h('span.cp-cursor.cp-tippy-html' + animal, {
style: "background-color: " + (cursor.color || 'red') + ";"+text, style: text,
'data-cptippy-html': true, 'data-cptippy-html': true,
title: html title: html,
}, l); }, l);
if (!noClear) { if (!noClear) {
cursor.clear = function () { cursor.clear = function () {
@ -563,12 +575,12 @@ define([
"12": { "12": {
"id": 12, "id": 12,
"title": Messages.kanban_working, "title": Messages.kanban_working,
"item": [3, 4] "item": [],
}, },
"13": { "13": {
"id": 13, "id": 13,
"title": Messages.kanban_done, "title": Messages.kanban_done,
"item": [5, 6] "item": [],
} }
}, },
items: items items: items
@ -1009,8 +1021,8 @@ define([
var common = framework._.sfCommon; var common = framework._.sfCommon;
var $button = common.createButton('toggle', true, { var $button = common.createButton('toggle', true, {
element: $(container), element: $(container),
//icon: 'fa-tags', // FIXME icon: 'fa-tags',
//text: Messages.fm_tagsName, // FIXME text: Messages.fm_tagsName,
}, function () { }, function () {
$button.toggleClass('cp-toolbar-button-active'); $button.toggleClass('cp-toolbar-button-active');
@ -1295,12 +1307,12 @@ define([
// Add new cursor // Add new cursor
var avatar = getAvatar(cursor); var avatar = getAvatar(cursor);
var $item = $('.kanban-item[data-eid="'+cursor.item+'"]'); var $item = $('.kanban-item[data-eid="'+cursor.item+'"]');
var $board = $('.kanban-board[data-id="'+cursor.board+'"]');
if ($item.length) { if ($item.length) {
remoteCursors[id] = cursor; remoteCursors[id] = cursor;
$item.find('.cp-kanban-cursors').append(avatar); $item.find('.cp-kanban-cursors').append(avatar);
return; return;
} }
var $board = $('.kanban-board[data-id="'+cursor.board+'"]');
if ($board.length) { if ($board.length) {
remoteCursors[id] = cursor; remoteCursors[id] = cursor;
$board.find('header .cp-kanban-cursors').append(avatar); $board.find('header .cp-kanban-cursors').append(avatar);

@ -43,18 +43,21 @@ define([
var canonicalize = function(t) { return t.replace(/\r\n/g, '\n'); }; var canonicalize = function(t) { return t.replace(/\r\n/g, '\n'); };
var getAuthorId = function(Env, curve) { var getAuthorId = function(Env, curve, uid) {
return Env.common.getAuthorId(Env.comments.authors, curve); return Env.common.getAuthorId(Env.comments.authors, curve, uid);
}; };
// Return the author ID and add/update the data for registered users // Return the author ID and add/update user data
// Return the username for unregistered users // associate data with a curvePublic for registered users and the uid otherwise
var updateAuthorData = function(Env, onChange) { var updateAuthorData = function(Env, onChange) {
var userData = Env.metadataMgr.getUserData(); var userData = Env.metadataMgr.getUserData();
var myAuthorId;
if (!Env.common.isLoggedIn()) { if (!Env.common.isLoggedIn()) {
return userData.name; myAuthorId = getAuthorId(Env, undefined, userData.uid);
} else {
myAuthorId = getAuthorId(Env, userData.curvePublic);
} }
var myAuthorId = getAuthorId(Env, userData.curvePublic);
var data = Env.comments.authors[myAuthorId] = Env.comments.authors[myAuthorId] || {}; var data = Env.comments.authors[myAuthorId] = Env.comments.authors[myAuthorId] || {};
var old = Sortify(data); var old = Sortify(data);
data.name = userData.name; data.name = userData.name;
@ -62,6 +65,8 @@ define([
data.profile = userData.profile; data.profile = userData.profile;
data.curvePublic = userData.curvePublic; data.curvePublic = userData.curvePublic;
data.notifications = userData.notifications; data.notifications = userData.notifications;
data.uid = userData.uid;
if (typeof(onChange) === "function" && Sortify(data) !== old) { if (typeof(onChange) === "function" && Sortify(data) !== old) {
onChange(); onChange();
} }
@ -82,6 +87,9 @@ define([
var userData = Env.metadataMgr.getUserData(); var userData = Env.metadataMgr.getUserData();
var privateData = Env.metadataMgr.getPrivateData(); var privateData = Env.metadataMgr.getPrivateData();
var others = {}; var others = {};
// XXX mentioned users should be excluded from the list of notified recipients to avoid notifying them twice
// Get all the other registered users with a mailbox // Get all the other registered users with a mailbox
thread.m.forEach(function(obj) { thread.m.forEach(function(obj) {
var u = obj.u; var u = obj.u;
@ -93,7 +101,8 @@ define([
curvePublic: author.curvePublic, curvePublic: author.curvePublic,
comment: obj.m, comment: obj.m,
content: obj.v, content: obj.v,
notifications: author.notifications notifications: author.notifications,
uid: author.uid,
}; };
}); });
// Send the notification // Send the notification
@ -146,7 +155,7 @@ define([
'aria-required': true, 'aria-required': true,
contenteditable: true, contenteditable: true,
}); });
Env.common.displayAvatar($(avatar), userData.avatar, name); Env.common.displayAvatar($(avatar), userData.avatar, name, Util.noop, userData.uid);
var cancel = h('button.btn.btn-cancel', { var cancel = h('button.btn.btn-cancel', {
tabindex: 1 tabindex: 1
@ -224,7 +233,9 @@ define([
if (Env.common.isLoggedIn()) { if (Env.common.isLoggedIn()) {
var authors = {}; var authors = {};
Object.keys((Env.comments && Env.comments.authors) ||  {}).forEach(function(id) { Object.keys((Env.comments && Env.comments.authors) ||  {})
.filter(function (id) { return Util.find(Env, ['commments', 'authors', id, 'curvePublic']); })
.forEach(function(id) {
var obj = Util.clone(Env.comments.authors[id]); var obj = Util.clone(Env.comments.authors[id]);
authors[obj.curvePublic] = obj; authors[obj.curvePublic] = obj;
}); });
@ -369,7 +380,7 @@ define([
var name = Util.fixHTML(author.name || Messages.anonymous); var name = Util.fixHTML(author.name || Messages.anonymous);
var date = new Date(msg.t); var date = new Date(msg.t);
var avatar = h('span.cp-avatar'); var avatar = h('span.cp-avatar');
Env.common.displayAvatar($(avatar), author.avatar, name); Env.common.displayAvatar($(avatar), author.avatar, name, Util.noop, author.uid);
if (author.profile) { if (author.profile) {
$(avatar).click(function(e) { $(avatar).click(function(e) {
Env.common.openURL(Hash.hashToHref(author.profile, 'profile')); Env.common.openURL(Hash.hashToHref(author.profile, 'profile'));
@ -393,7 +404,7 @@ define([
} }
cleanMentions($el); cleanMentions($el);
var avatar = h('span.cp-avatar'); var avatar = h('span.cp-avatar');
Env.common.displayAvatar($(avatar), avatarUrl, name); Env.common.displayAvatar($(avatar), avatarUrl, name, Util.noop, author.uid);
$el.append([ $el.append([
avatar, avatar,
h('span.cp-mentions-name', name) h('span.cp-mentions-name', name)

@ -3,7 +3,9 @@ define([
'/common/common-ui-elements.js', '/common/common-ui-elements.js',
'/common/common-interface.js', '/common/common-interface.js',
'/bower_components/chainpad/chainpad.dist.js', '/bower_components/chainpad/chainpad.dist.js',
], function ($, UIElements, UI, ChainPad) { '/customize/messages.js',
'/common/inner/common-mediatag.js',
], function ($, UIElements, UI, ChainPad, Messages, MT) {
var Cursor = {}; var Cursor = {};
Cursor.isCursor = function (el) { Cursor.isCursor = function (el) {
@ -40,8 +42,17 @@ define([
var cursors = {}; var cursors = {};
// FIXME despite the name of this function this doesn't actually render as a tippy tooltip
// that means that emojis will use the system font that shows up in native tooltips
// so this might be of limited value/aesthetic appeal compared to other apps' cursors
var makeTippy = function (cursor) { var makeTippy = function (cursor) {
return cursor.name; if (typeof(cursor.uid) === 'string' && (!cursor.name || cursor.name === Messages.anonymous)) {
var animal = MT.getPseudorandomAnimal(cursor.uid);
if (animal) {
return animal + ' ' + Messages.anonymous;
}
}
return cursor.name || Messages.anonymous;
}; };
var makeCursor = function (id, cursor) { var makeCursor = function (id, cursor) {

@ -7,7 +7,7 @@ define([
'/common/sframe-common.js', '/common/sframe-common.js',
'/common/common-realtime.js', '/common/common-realtime.js',
'/customize/application_config.js', '/customize/application_config.js',
'/bower_components/chainpad-listmap/chainpad-listmap.js', 'chainpad-listmap',
'/poll/render.js', '/poll/render.js',
'/poll/export.js', '/poll/export.js',
'/common/diffMarked.js', '/common/diffMarked.js',

@ -1,7 +1,7 @@
define([ define([
'jquery', 'jquery',
'/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad-crypto/crypto.js',
'/bower_components/chainpad-listmap/chainpad-listmap.js', 'chainpad-listmap',
'/common/toolbar.js', '/common/toolbar.js',
'/bower_components/nthen/index.js', '/bower_components/nthen/index.js',
'/common/sframe-common.js', '/common/sframe-common.js',
@ -348,8 +348,8 @@ define([
if (!val) { if (!val) {
$('<img>', { $('<img>', {
src: '/customize/images/avatar.png', src: '/customize/images/avatar.png',
title: Messages.profile_avatar, title: Messages.profile_defaultAlt,
alt: 'Avatar' alt: Messages.profile_defaultAlt,
}).appendTo($span); }).appendTo($span);
return; return;
} }

@ -10,7 +10,7 @@ define([
'/common/cryptpad-common.js', '/common/cryptpad-common.js',
'/common/outer/cache-store.js', '/common/outer/cache-store.js',
'/common/common-interface.js', '/common/common-interface.js',
'/bower_components/chainpad-netflux/chainpad-netflux.js', 'chainpad-netflux',
'/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad-crypto/crypto.js',
'/common/userObject.js', '/common/userObject.js',
'/common/clipboard.js', '/common/clipboard.js',

@ -22,6 +22,8 @@
.usergrid_main(); .usergrid_main();
.forms_main(); .forms_main();
.fa-shhare-alt:before { content: "\f1e0"; }
#cp-filepicker-dialog { #cp-filepicker-dialog {
display: none; display: none;
.cp-modal { .cp-modal {

@ -34,5 +34,14 @@
color: @cryptpad_color_link; color: @cryptpad_color_link;
text-decoration: underline; text-decoration: underline;
} }
.alert-info {
font-size: 16px;
margin-top: 15px;
margin-bottom: 15px;
}
// add some whitespace to improve readability a bit
br {
margin: 5px;
}
} }

@ -45,6 +45,7 @@ define([
'cp-support-list', 'cp-support-list',
], ],
'new': [ // Msg.support_cat_new 'new': [ // Msg.support_cat_new
'cp-support-subscribe',
'cp-support-language', 'cp-support-language',
'cp-support-form', 'cp-support-form',
], ],
@ -166,6 +167,26 @@ define([
return $div; return $div;
}; };
create['subscribe'] = function () {
if (!Pages.areSubscriptionsAllowed()) { return; }
var url = Pages.accounts.upgradeURL;
var accountsLink = h('a', {
href: url,
}, Messages.support_premiumLink);
$(accountsLink).click(function (ev) {
ev.preventDefault();
common.openURL(url);
});
return $(h('div.cp-support-subscribe.cp-sidebarlayout-element', [
h('div.alert.alert-info', [
Messages.support_premiumPriority,
' ',
accountsLink,
]),
]));
};
// Create a new tickets // Create a new tickets
create['form'] = function () { create['form'] = function () {
var key = 'form'; var key = 'form';

@ -693,6 +693,8 @@ define([
redrawRoster(common); redrawRoster(common);
}); });
}; };
var getDisplayName = UI.getDisplayName;
var makeMember = function (common, data, me, roster) { var makeMember = function (common, data, me, roster) {
if (!data.curvePublic) { return; } if (!data.curvePublic) { return; }
@ -701,11 +703,12 @@ define([
return user.role === "OWNER" && user.curvePublic !== me.curvePublic && !user.pendingOwner; return user.role === "OWNER" && user.curvePublic !== me.curvePublic && !user.pendingOwner;
}); });
var displayName = getDisplayName(data.displayName);
// Avatar // Avatar
var avatar = h('span.cp-avatar.cp-team-member-avatar'); var avatar = h('span.cp-avatar.cp-team-member-avatar');
common.displayAvatar($(avatar), data.avatar, data.displayName); common.displayAvatar($(avatar), data.avatar, displayName, Util.noop, data.uid);
// Name // Name
var name = h('span.cp-team-member-name', data.displayName); var name = h('span.cp-team-member-name', displayName);
if (data.pendingOwner) { if (data.pendingOwner) {
$(name).append(h('em', { $(name).append(h('em', {
title: Messages.team_pendingOwnerTitle title: Messages.team_pendingOwnerTitle
@ -789,7 +792,7 @@ define([
title: Messages.team_rosterKick title: Messages.team_rosterKick
}); });
$(remove).click(function () { $(remove).click(function () {
UI.confirm(Messages._getKey('team_kickConfirm', [Util.fixHTML(data.displayName)]), function (yes) { UI.confirm(Messages._getKey('team_kickConfirm', [Util.fixHTML(displayName)]), function (yes) {
if (!yes) { return; } if (!yes) { return; }
APP.module.execCommand('REMOVE_USER', { APP.module.execCommand('REMOVE_USER', {
pending: data.pending, pending: data.pending,
@ -1073,6 +1076,9 @@ define([
metadata: obj metadata: obj
}, function () { }, function () {
$avatar.empty(); $avatar.empty();
// the UI is not supposed to allow admins to remove team names
// so we expect that it will be there. Failing that the initials
// from the default name will be displayed
common.displayAvatar($avatar, data.url); common.displayAvatar($avatar, data.url);
}); });
}); });
@ -1093,8 +1099,8 @@ define([
if (!val) { if (!val) {
var $img = $('<img>', { var $img = $('<img>', {
src: '/customize/images/avatar.png', src: '/customize/images/avatar.png',
title: Messages.profile_avatar, title: Messages.profile_defaultAlt,
alt: 'Avatar' alt: Messages.profile_defaultAlt,
}); });
var mt = h('media-tag', $img[0]); var mt = h('media-tag', $img[0]);
$avatar.append(mt); $avatar.append(mt);
@ -1191,10 +1197,11 @@ define([
var displayUser = function (common, data) { var displayUser = function (common, data) {
var avatar = h('span.cp-teams-invite-from-avatar.cp-avatar'); var avatar = h('span.cp-teams-invite-from-avatar.cp-avatar');
common.displayAvatar($(avatar), data.avatar, data.displayName); var name = getDisplayName(data.displayName);
common.displayAvatar($(avatar), data.avatar, name);
return h('div.cp-teams-invite-from-author', [ return h('div.cp-teams-invite-from-author', [
avatar, avatar,
h('span.cp-teams-invite-from-name', data.displayName) h('span.cp-teams-invite-from-name', name)
]); ]);
}; };
@ -1316,23 +1323,31 @@ define([
}); });
}; };
var isValidInvitationLinkContent = function (json) {
if (!json) { return false; }
if (json.error || !Object.keys(json).length) { return false; }
if (!json.author) { return false; }
return true;
};
nThen(function (waitFor) { nThen(function (waitFor) {
// Get preview content. // Get preview content.
sframeChan.query('Q_ANON_GET_PREVIEW_CONTENT', { seeds: seeds }, waitFor(function (err, json) { sframeChan.query('Q_ANON_GET_PREVIEW_CONTENT', { seeds: seeds }, waitFor(function (err, json) {
if (json && (json.error || !Object.keys(json).length)) { if (!isValidInvitationLinkContent(json)) {
$(errorBlock).text(Messages.team_inviteInvalidLinkError).show(); $(errorBlock).text(Messages.team_inviteInvalidLinkError).show();
waitFor.abort(); waitFor.abort();
$div.empty(); $div.empty();
return; return;
} }
// FIXME nothing guarantees that teamName or author.displayName exist in json
$div.empty(); $div.empty();
$div.append(h('div.cp-teams-invite-from', [ $div.append(h('div.cp-teams-invite-from', [
Messages.team_inviteFrom || 'From:', Messages.team_inviteFrom,
displayUser(common, json.author) displayUser(common, json.author)
])); ]));
$div.append(UI.setHTML(h('p.cp-teams-invite-to'), $div.append(UI.setHTML(h('p.cp-teams-invite-to'),
Messages._getKey('team_inviteFromMsg', Messages._getKey('team_inviteFromMsg',
[Util.fixHTML(json.author.displayName), [Util.fixHTML(getDisplayName(json.author.displayName)),
Util.fixHTML(json.teamName)]))); Util.fixHTML(json.teamName)])));
if (json.message) { if (json.message) {
$div.append(h('div.cp-teams-invite-message', json.message)); $div.append(h('div.cp-teams-invite-message', json.message));
@ -1449,10 +1464,10 @@ define([
// Update the name in the user menu // Update the name in the user menu
var $displayName = $bar.find('.' + Toolbar.constants.username); var $displayName = $bar.find('.' + Toolbar.constants.username);
metadataMgr.onChange(function () { metadataMgr.onChange(function () {
var name = metadataMgr.getUserData().name || Messages.anonymous; var name = getDisplayName(metadataMgr.getUserData().name);
$displayName.text(name); $displayName.text(name);
}); });
$displayName.text(user.name || Messages.anonymous); $displayName.text(getDisplayName(user.name));
// Load the Team module // Load the Team module
var onEvent = function (obj) { var onEvent = function (obj) {

@ -1,7 +1,7 @@
define([ define([
'jquery', 'jquery',
'/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad-crypto/crypto.js',
'/bower_components/chainpad-listmap/chainpad-listmap.js', 'chainpad-listmap',
'/common/toolbar.js', '/common/toolbar.js',
'/bower_components/nthen/index.js', '/bower_components/nthen/index.js',
'/common/sframe-common.js', '/common/sframe-common.js',

Loading…
Cancel
Save